python - Keras 模型在训练时返回较高的验证准确率,但在评估时准确率非常低

标签 python tensorflow keras mobilenet

我正在尝试训练一个简单的 MobileNetV3Smallkeras.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/step - loss: 0.6935 - binary_accuracy: 0.8461

但是,当我使用 model.save() 保存并加载模型时或tf.keras.models.save_model() 。输出变成这样:

6/6 [==============================] - 2s 100ms/step - loss: 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 post ,并减少momentum MobileNet BatchNormalization 层的参数一一对应。
for layer in model.layers[0].layers:
    if type(layer) is tf.keras.layers.BatchNormalization:
        layer.momentum = 0.9

前两个 Action 没有效果,在应用第三步之后,我对任何输入都不再得到相同的预测。然而,evaluate()predict()仍然有不同的精度值。

最佳答案

您是否尝试过在 validation_datagen.flow_from_directory() 中设置 shuffle = False?这有点误导,但 .flow_from_directory() 方法默认情况下会进行洗牌,这在生成验证数据集时会出现问题。当您尝试调用 .predict 时,这会打乱您的验证数据。而在训练循环中,.fit 方法隐式地不会对验证集进行洗牌。

我认为这是问题所在的原因是因为您声明在验证集上调用 .predict() 可以获得约 .5 的准确率,并且您还运行了二进制分类(带有二进制交叉熵损失的 sigmoid 输出),如果您(错误地)打乱了验证数据,那么这是非常有意义的。平衡数据集上未经训练的二元分类器通常会达到 50% 左右的准确率(0 为 0.5,1 为 0.5),因为它只是猜测这一点。

来源:我之前构建并训练了很多图像分类模型,这种情况在我身上发生过很多次。

关于python - Keras 模型在训练时返回较高的验证准确率,但在评估时准确率非常低,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72774644/

相关文章:

python - 关于 model.load 的 Tflearn 问题

TensorFlow:FIFOQueue 的 DequeueMany 和 DequeueUpTo 要求组件具有指定的形状

python - 我想用keras为深度学习添加一对一层

python - 如何将 Tensorflow 的结果记录到 CSV 文件

tensorflow - 如何以示例格式序列化数据以进行 tensorflow 排名?

python - 根据另一个嵌套列表对嵌套列表进行排序

python - 缩短一个语句被反转的 if 语句

python : UDP Socket How to Waiting Client Side Reply Bytes String

python - 时尚 MNIST 代码将 bag 作为每个真实世界图像的输出

python - 如何在Python中区分大小写的同时测试两个字符串是否是字谜?