简体   繁体   English

Keras 的稀疏分类交叉熵形状问题

[英]Sparse Categorical CrossEntropy shape problem with Keras

I have a multiclass problem where an image can be one of three classes (Masked, UnMasked, Hybrid).我有一个多类问题,其中图像可以是三个类之一(Masked、UnMasked、Hybrid)。

I am using image_dataset_from_directory from keras preprocessing module which makes things easier.我正在使用来自 keras 预处理模块的image_dataset_from_directory ,这使事情变得更容易。

Load dataset加载数据集

def load_from_directory(shuffle=False):
  train_ds = tfk.preprocessing.image_dataset_from_directory(
    directory=TRAINING_PATH,
    image_size=IMAGE_SIZE,
    validation_split=VALIDATION_SPLIT,
    batch_size=BATCH_SIZE,
    seed=SEED,
    subset='training',
    label_mode='int',
    shuffle=shuffle
  )

  val_ds = tfk.preprocessing.image_dataset_from_directory(
    directory=TRAINING_PATH,
    image_size=IMAGE_SIZE,
    validation_split=VALIDATION_SPLIT,
    batch_size=BATCH_SIZE,
    seed=SEED,
    subset='validation',
    label_mode='int',
    shuffle=False
  )

  test_ds = tfk.preprocessing.image_dataset_from_directory(
    directory=TESTING_PATH,
    labels=None,
    image_size=IMAGE_SIZE,
    batch_size=BATCH_SIZE,
    seed=SEED,
    label_mode='int',
    shuffle=False
  )

  return train_ds, val_ds, test_ds

On the keras documentation it states for the label_model the following: 'int': means that the labels are encoded as integers (eg for sparse_categorical_crossentropy loss) ... ( here is the link).在 keras 文档中,它为 label_model 声明了以下内容: 'int':表示标签被编码为整数(例如,对于 sparse_categorical_crossentropy 损失)......这里是链接)。 Since my folder has the following structure:由于我的文件夹具有以下结构:

  • MaskDataset掩码数据集
    • training训练
      • 0/ 0/
        • img1, img2, …, imgN img1, img2, ..., imgN
      • 1/ 1/
        • img1, img2, …, imgN img1, img2, ..., imgN
      • 2/ 2/
        • img1, img2, …, imgN img1, img2, ..., imgN
    • testing测试
      • img1, img2, …, imgN img1, img2, ..., imgN

And for the model by final layers are the following:对于最终层的模型如下:

  x = tfkl.SeparableConv2D(1024, 3, padding='same')(x)
  x = tfkl.BatchNormalization()(x)
  x = tfkl.Activation('relu')(x)  

  # GlobalAveragePooling + Dropout
  x = tfkl.GlobalAveragePooling2D()(x)
  x = tfkl.Dropout(0.5)(x) 
  
  # Softmax
  outputs = tfkl.Dense(units=len(CLASS_NAMES), activation='softmax')(x)

  model = tfk.Model(inputs, outputs)

which I get the following complain: "ValueError: Shapes (None, 3) and (None, 1) are incompatible"我得到以下抱怨:“ValueError:形状(None,3)和(None,1)不兼容”

If I change the label_mode to 'categorical', when loading the dataset and change the loss function from SparseCategoricalCrossEntropy to CategoricalCrossEntropy and the accuracy from SparseCategoricalAccuracy to CategoricalAccuracy it works, but I really wanted to understand why I am not able to use the SparseCrossEntropy loss function and how to fix it.如果我将 label_mode 更改为“categorical”,在加载数据集并将损失函数从 SparseCategoricalCrossEntropy 更改为 CategoricalCrossEntropy 并将准确度从 SparseCategoricalAccuracy 更改为 CategoricalAccuracy 它有效,但我真的很想了解为什么我无法使用 SparseCrossEntropy 损失函数以及如何解决它。

Edit: Add model compile and fit编辑:添加模型编译和拟合

def compile_model(model, plot=False):
  model.compile(
    optimizer=tf.optimizers.Adam(1e-3),
    loss=tf.losses.SparseCategoricalCrossentropy(name='loss'),
    metrics=[
      tfk.metrics.SparseCategoricalAccuracy(name='accuracy'), 
      tfk.metrics.Precision(name='precision'), 
      tfk.metrics.Recall(name='recall'), 
    ]
  )

  model.summary()
  if plot: tfk.utils.plot_model(model, show_shapes=True)

def train_model(model, debug_mode=False):
  callbacks = [tfk.callbacks.EarlyStopping(patience=5, monitor='val_loss', restore_best_weights=True)]
  if debug_mode:
    callbacks.append(tfk.callbacks.ModelCheckpoint(filepath='model.{epoch:02d}-{val_loss:.2f}.h5', save_best_only=True, monitor='val_loss'))
    callbacks.append(tfk.callbacks.TensorBoard(log_dir='./tensorboard'))

  history = model.fit(
    x=train_ds, 
    validation_data=val_ds,
    epochs=100, 
    callbacks=callbacks,
    # steps_per_epoch=len(train_ds),
    # validation_steps=len(val_ds),
  )

  return history

tf.keras.metrics.SparseCategoricalAccuracy() --> is for SparseCategorical (int) class. tf.keras.metrics.SparseCategoricalAccuracy() --> 用于 SparseCategorical (int) 类。 tf.keras.metrics.Recall() --> is for categorical (one-hot) class. tf.keras.metrics.Recall() --> 用于分类(one-hot)类。

You have to use a one-hot class if you want to use any metric naming without the 'Sparse'.如果要使用没有“稀疏”的任何度量命名,则必须使用 one-hot 类。

update:更新:

num_class=4
def get_img_and_onehot_class(img_path, class):
    img = tf.io.read_file(img_path)
    img = tf.io.decode_jpeg(img, channels=3)
    """ Other preprocessing of image."""
    return img, tf.one_hot(class, num_class)

when you got the one-hot class:当你上了一堂热课时:

loss=tf.losses.CategoricalCrossentropy
METRICS=[tf.keras.metrics.CategoricalAccuracy(name='accuracy'),
            tf.keras.metrics.Precision(name='precision'),
            tf.keras.metrics.Recall(name='recall'),]

model.compile(
        optimizer = tf.keras.optimizers.Adam(learning_rate=0.0001),
        loss=loss,
        metrics= METRICS)

Ref: #72217176编号: #72217176

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Tensorflow 和 Keras:sparse_categorical_crossentropy - Tensorflow with Keras: sparse_categorical_crossentropy keras sparse_categorical_crossentropy损失函数输出形状不匹配 - keras sparse_categorical_crossentropy loss function output shape didn't match Keras logits 和 label 必须具有相同的第一维,得到 logits 形状 [10240,151] 和标签形状 [1],sparse_categorical_crossentropy - Keras logits and labels must have the same first dimension, got logits shape [10240,151] and labels shape [1], sparse_categorical_crossentropy keras, sparse_categorical_crossentropy label Y维度和取值范围 - keras, sparse_categorical_crossentropy label Y dimension and value range keras sparse_categorical_crossentropy 损失 function 中的错误 - Error in keras sparse_categorical_crossentropy loss function Tensoflow Keras - 具有稀疏类别交叉熵的 Nan 损失 - Tensoflow Keras - Nan loss with sparse_categorical_crossentropy keras自定义生成器categorical_crossentropy修复输出形状问题 - keras custom generator categorical_crossentropy fix output shape issue keras 分类和二元交叉熵 - keras categorical and binary crossentropy sparse_categorical_crossentropy 和 categorical_crossentropy 有什么区别? - What is the difference between sparse_categorical_crossentropy and categorical_crossentropy? Keras 自定义损失 function - 尽管返回与分类交叉熵相同的形状,但形状不匹配 - Keras custom loss function - shape mismatch despite returning same shape as categorical crossentropy
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM