[英]Keras model returns high validation accuracy while training, but accuracy is very low while evaluating
我正在嘗試在MobileNetV3Small
下訓練一個簡單的keras.applications
,如下所示
base_model = keras.applications.MobileNetV3Small(
input_shape= INPUT_SHAPE,
alpha=.125,
include_top=False,
classes=1,
dropout_rate = 0.2,
weights=None)
x = keras.layers.Flatten()(base_model.output)
preds = keras.layers.Dense(1, activation="sigmoid")(x)
model = keras.Model(inputs=base_model.input, outputs=preds)
model.compile(loss="binary_crossentropy",
optimizer='RMSprop',
metrics=["binary_accuracy"])
train_datagen = ImageDataGenerator(
rescale=1.0 / 255,
rotation_range=40,
horizontal_flip=True,
vertical_flip=True,
)
train_generator = train_datagen.flow_from_directory(
os.path.join(DATA_ROOT, 'train'),
target_size=(56,56),
batch_size=128,
class_mode="binary",
)
validation_datagen = ImageDataGenerator(rescale=1.0 / 255)
validation_generator = validation_datagen.flow_from_directory(
os.path.join(DATA_ROOT, 'val'),
target_size=(56,56),
batch_size=128,
class_mode="binary",
)
model_checkpoint_callback = keras.callbacks.ModelCheckpoint(
filepath=SAVE_DIR,
save_weights_only=True,
monitor='val_binary_accuracy',
mode='max',
save_best_only=True)
es_callback = keras.callbacks.EarlyStopping(patience=10)
model.fit(train_generator,
epochs=100,
validation_data=validation_generator,
callbacks=[model_checkpoint_callback, es_callback],
shuffle=True)
當我訓練模型時,我得到了大約 0.94 的驗證准確度。 但是當我在完全相同的驗證數據上調用model.evaluate
時,准確度變為 0.48。 當我使用任何數據調用model.predict
時,它會輸出常數值 0.51...
學習率、優化器或指標沒有任何問題。 這里有什么問題?
編輯:
訓練后當我跑步
pred_results = model.evaluate(validation_generator)
print(pred_results)
它給了我 1 epoch 訓練網絡的輸出:
6/6 [===============================] - 1s 100ms/步 - 損失:0.6935 - binary_accuracy: 0.8461
但是,當我使用model.save()
或tf.keras.models.save_model()
保存和加載模型時。 輸出變成這樣:
6/6 [===============================] - 2s 100ms/step - 損失:0.6935 - binary_accuracy: 0.5028 [0.6935192346572876 , 0.5027709603309631]
model.predict(validation_generator)
的輸出是:
[[0.5080832] [0.5080832] [0.5080832] [0.5080832]。 . . [0.5080832] [0.5080832]]
到目前為止我已經嘗試過:
tf.keras.utils.image_dataset_from_directory()
而不是ImageDataGenerator
momentum
參數一一減少。for layer in model.layers[0].layers:
if type(layer) is tf.keras.layers.BatchNormalization:
layer.momentum = 0.9
前兩個動作沒有效果,在應用第三步之后,我對任何輸入都不再有相同的預測。 但是, evaluate()
和predict()
仍然具有不同的准確度值。
可能值得嘗試model.save_weights('directory')
,然后通過 model.load_weights('directory') 重建模型(我認為這里是重新運行base_model = ...
代碼model.load_weights('directory')
。 這就是我在自己的模型中所做的,然后當我這樣做時,准確性/損失在保存和加載之前和之后保持完全相同。
如果您在擬合模型后運行pred_results = model.evaluate(validation_generator)
,此時加載的權重是上次訓練時期更新的權重。 你必須做的是在model.fit
加載從model_checkpoint_callback
保存的權重之后
model = model.load_weights(SAVE_DIR)` # and then .evaluate
pred_results = model.evaluate(validation_generator)
print(pred_results)
您是否嘗試在validation_datagen.flow_from_directory()
中設置shuffle = False
? 這有點誤導,但默認情況下.flow_from_directory()
方法會隨機播放,這在生成驗證數據集時會出現問題。 當您嘗試調用.predict
時,這會改變您的驗證數據。 而在您的訓練循環中, .fit
方法隱式地不會打亂驗證集。
我認為這是問題的原因是因為您聲明在驗證集上調用.predict()
可以使您獲得 ~.5 的准確度,並且您還在運行二進制分類(具有二進制交叉熵損失的 sigmoid 輸出),其中如果您(錯誤地)改組您的驗證數據,則非常有意義。 平衡數據集上未經訓練的二元分類器通常會達到 50% 左右的准確率(0.5 表示 0,0.5 表示 1),因為它只是在那個時候進行猜測。
資料來源:我之前已經建立並訓練了很多圖像分類模型,這種情況經常發生在我身上。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.