4

我正在使用 MobileNet 和 TensorFlow 2 来区分 4 个非常相似的玩具。每个玩具我正好有 750 张图片,一个标签包含 750 张“负面”图片,没有任何玩具。

我之前使用过 MobileNet 并取得了相当大的成功,但是关于这种情况的某些事情导致了很多过度拟合(训练/验证准确度之间存在约 30-40% 的差异)。该模型在 3 个 epoch 内很快训练到大约 99.8% 的训练准确度,但验证准确度停留在 75% 左右。验证数据集是 20% 的输入图像的随机集。在查看模型的准确性时,人们对其中一个玩具有很大的偏见,而许多其他玩具被错误地识别为该玩具。

我已经尝试了几乎所有的方法来解决这个问题:

我在添加到 MobileNet 顶部的 Conv2D 层之后添加了 Dropout,并尝试了 0.2 到 0.9 之间的各种丢弃率。

model = tf.keras.Sequential([
  base_model,
  tf.keras.layers.Conv2D(32, 3, activation='relu'),
  tf.keras.layers.Dropout(0.5),
  tf.keras.layers.GlobalAveragePooling2D(),
  tf.keras.layers.Dense(label_count, activation='softmax')
])

我在 Conv2D 层之前添加了一个额外的 Dropout 层,这似乎稍微改善了一些事情:

model = tf.keras.Sequential([
  base_model,
  tf.keras.layers.Dropout(0.5),
  tf.keras.layers.Conv2D(32, 3, activation='relu'),
  tf.keras.layers.Dropout(0.5),
  tf.keras.layers.GlobalAveragePooling2D(),
  tf.keras.layers.Dense(label_count, activation='softmax')
])

我还添加了更多测试数据,尝试在各种照明条件和背景下混合玩具照片,并生成叠加在随机背景上的玩具图像。这些都没有显着影响。

我应该将 dropout 添加到 MobileNet 模型中,而不仅仅是添加到我在它之后添加的层吗?我在 github 上遇到了这样的代码,但我不知道这是否真的是一个好主意 - 或者不知道如何使用 TensorFlow 2 来实现这一点。

这是明智的,还是可行的?

或者,我能想到的唯一其他想法是:

  • 捕获更多图像,以使训练更加困难 - 但我认为每个项目 750 应该足以做得很好。
  • 不要使用 MobileNet,从头开始创建神经网络或使用另一个预先存在的网络。
4

1 回答 1

4

由于模型过度拟合,您可以

  1. Shuffle数据,通过使用shuffle=Truein cnn_model.fit。代码如下所示:

    history = cnn_model.fit(x = X_train_reshaped, y = y_train, batch_size = 512, epochs = epochs, callbacks=[callback], verbose = 1, validation_data = (X_test_reshaped, y_test), validation_steps = 10, steps_per_epoch=steps_per_epoch, shuffle = True)

  2. 使用Early Stopping. 代码如下所示

callback = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=15)

  1. 使用Regularization. 正则化代码如下所示(您可以尝试l1 Regularizationl1_l2 Regularization也可以):

    from tensorflow.keras.regularizers import l2

    Regularizer = l2(0.001)

    cnn_model.add(Conv2D(64,3, 3, input_shape = (28,28,1), activation='relu', data_format='channels_last', activity_regularizer=Regularizer, kernel_regularizer=Regularizer))

    cnn_model.add(Dense(units = 10, activation = 'sigmoid', activity_regularizer=Regularizer, kernel_regularizer=Regularizer))

  2. 尝试替换GlobalAveragePooling2DMaxPool2D

  3. 您可以尝试使用BatchNormalization.

  4. 使用 执行图像数据增强ImageDataGenerator。有关更多信息,请参阅此链接。

  5. 如果Pixels不是Normalized,将像素值除以255也有帮助。

  6. 最后,如果仍然没有变化,您可以尝试其他Pre-Trained Models类似ResNet, Vgg Net, DenseNet(正如 Mohsin 在评论中提到的)

于 2019-12-04T08:14:56.147 回答