【问题标题】:Training loss stays constant while validation loss fluctuates heavily训练损失保持不变,而验证损失波动很大
【发布时间】:2021-02-08 00:16:29
【问题描述】:

在 VGG 上进行迁移学习时,数据量相当大,配置如下:

base_big_3 = tf.keras.applications.VGG19(include_top=False, weights='imagenet',input_shape=[IMG_SIZE,IMG_SIZE,3])

model_big_3 = tf.keras.Sequential()
model_big_3.add(base_big_3)
model_big_3.add(BatchNormalization(axis=-1))
model_big_3.add(GlobalAveragePooling2D())
model_big_3.add(Dense(5, activation='softmax'))

model_big_3.compile(loss=tf.keras.losses.CategoricalCrossentropy(), optimizer=tf.keras.optimizers.Adamax(learning_rate=0.01), metrics=['acc'])

history = model_big_3.fit(
      train_generator,
      steps_per_epoch=BATCH_SIZE,
      epochs=100,
      validation_data=valid_generator,
      batch_size=BATCH_SIZE
      )

训练损失和验证损失变化如下,其中训练损失自始至终是恒定的,验证损失最初会达到峰值,之后会变得恒定:

我尝试了什么

  1. 我一一尝试了here给出的解决方案,并将学习率从0.01降低到0.0001。现在,这次训练损失确实略有下降,但验证错误似乎仍然非常波动。训练损失和验证损失变化如下:

  1. 上面的解决方案链接也建议对输入进行归一化,但我认为图像不需要归一化,因为数据变化不大,而且 VGG 网络已经进行了批量归一化,如果我有,请纠正我错了。请指出导致这种行为的原因、配置中的哪些更改以及如何改进培训?

【问题讨论】:

  • 预计验证损失会随着火车损失波动更大,如第二个示例所示。您可以尝试使用诸如 dropout 之类的正则化来稳定验证损失。
  • 我们总是对输入数据进行归一化,批量归一化与此无关
  • 损失的波动性很大程度上取决于数据大小。我认为您的 validation_data 大小太小。通常我使用 5000 个样本

标签: python tensorflow machine-learning keras deep-learning


【解决方案1】:

我看到的一件事是您设置了steps_per_epoch = BATCH_SIZE。假设您有 3200 个训练样本并且 BATCH_SIZE=32。要遍历所有训练样本,您必须经过 3200/32=100 个批次。但是使用 steps_per_epoch=BATCH_SIZE=32 你在一个 epoch 中只经过 1024 个样本。将steps_per_epoch设置为

steps_per_epoch =number_of_train samples//BATCH_SIZE

其中 BATCH_SIZE 是您在生成器中指定的任何内容。或者,您可以将其保留为 None 并且 model.fit 将在内部确定正确的值。 如位于 here. 的 model.fit 文档中所述,

Do not specify the batch_size if your data is in the form of datasets,
generators, or keras.utils.Sequence instances (since they generate batches). 

因为在 model.fit 你使用 train_generator 我假设这是一个生成器。 VGG 模型在 imagenet 图像上进行训练,其中像素值在 -1 到 +1 的范围内重新缩放。因此,您应该在输入管道的某个地方重新缩放图像。例如 image=image/127.5-1 将完成这项工作。你用了什么 BATCH_SIZE?使其更大(在内存大小的限制内)可能有助于消除波动。 我还建议你使用两个 keras 回调,EarlyStopping 和 ReduceLROnPlateau。文档是 here. 设置它们以监控验证损失。我建议的代码如下所示

estop=tf.keras.callbacks.EarlyStopping(monitor="val_loss",patience=4,verbose=1,   
                                      restore_best_weights=True)
rlronp=tf.keras.callbacks.ReduceLROnPlateau( monitor="val_loss", factor=0.5,
                                       patience=2, verbose=1)
callbacks=[estop, rlronp]    
# in model.fit add callbacks=callbacks

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-02
    • 1970-01-01
    • 1970-01-01
    • 2019-11-29
    • 2019-01-12
    相关资源
    最近更新 更多