[英]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 ,这使事情变得更容易。
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:
由于我的文件夹具有以下结构:
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 损失函数以及如何解决它。
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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.