我在实验使用tensorflow实现图片分类,试图训练一个VGG19模型。
vgg = tf.keras.applications.VGG19(weights='imagenet', include_top=False, pooling='max')
vgg.trainable = False
tf_vgg_model = tf.keras.Sequential([
vgg,
tf.keras.layers.Dense(6)
])
tf_vgg_model.build(input_shape=(None, IMG_HEIGHT, IMG_WIDTH, 3))
tf_vgg_model.summary()
early_stopping = tf.keras.callbacks.EarlyStopping(
monitor='val_loss',
patience=3,
min_delta=0.001
)
tf_vgg_model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001),
loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
# 训练模型
history = tf_vgg_model.fit(data_train, validation_data=data_val,
batch_size=BATCH_SIZE, validation_freq=1,
epochs=EPOCHS, callbacks=[early_stopping])
但训练模型的过程中,遇到了一个错误:
ValueError: Shapes (None, 1) and (None, 50) are incompatible
开始我以为是数据某个地方设置错了,导致形状不兼容。但是反复查看了数据处理的代码,并没有发现存在问题。最后发现实际上是因为compile中的loss参数设置错误。
tf_vgg_model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001),
loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
由于我的label目标是数字编码,因此只需将tf.keras.losses.CategoricalCrossentropy更改为tf.keras.losses.SparseCategoricalCrossentropy:
tf_vgg_model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001),
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
此错误的原因是CategoricalCrossentropy是适用于目标是 one-hot 编码,而SparseCategoricalCrossentropy才是适用于数字编码目标。