簡體   English   中英

Keras 模型在訓練時返回很高的驗證准確度,但在評估時准確度非常低

[英]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]]


到目前為止我已經嘗試過:

  1. 使用tf.keras.utils.image_dataset_from_directory()而不是ImageDataGenerator
  2. 修復了全局的 tensorflow 和 numpy 種子。
  3. 在另一篇SO 帖子中發現了類似的問題,並且將 MobileNet BatchNormalization 層的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM