【问题标题】:Validation metrics stagnate while training keeps improving验证指标停滞不前,而培训不断改进
【发布时间】:2020-02-28 15:09:19
【问题描述】:

这是我一直在使用的模型。它采用预训练的 InceptionV3 模型并在其上添加一些全连接层。整个事情都是可训练的(包括预训练的 InceptionV3 层)。

with tf.device('/cpu:0'):
    pretrained_model = InceptionV3(weights='imagenet', include_top=False)

    x = pretrained_model.output
    x = GlobalAveragePooling2D(name='gap_final')(x)
    x = Dense(512, activation='relu', kernel_regularizer=regularizers.l2(0.01))(x)
    x = Dropout(0.2)(x)
    x = Dense(512, activation='relu', kernel_regularizer=regularizers.l2(0.01))(x)
    x = Dropout(0.2)(x)
    x = Dense(512, activation='relu', kernel_regularizer=regularizers.l2(0.01))(x)
    x = Dropout(0.2)(x)

    preds = Dense(len(config.classes),activation='softmax')(x)
    model = Model(inputs=pretrained_model.input, outputs=preds)

parallel_model = multi_gpu_model(model, gpus=16)
parallel_model.compile(optimizer=Adam(lr=0.0005), loss='categorical_crossentropy', metrics=['accuracy'])

我尝试使用不同的图像增强配置对其进行训练,无论我做什么,结果总是类似于以下:

Epoch 1/20
181/181 [====] - 1372s 8s/step - loss: 19.2332 - acc: 0.3330 - val_loss: 8.7765 - val_acc: 0.4747
Epoch 2/20
181/181 [====] - 1379s 8s/step - loss: 4.9885 - acc: 0.5474 - val_loss: 3.5256 - val_acc: 0.4084
Epoch 3/20
181/181 [====] - 1354s 7s/step - loss: 2.0334 - acc: 0.6469 - val_loss: 2.5382 - val_acc: 0.4275
Epoch 4/20
181/181 [====] - 1361s 8s/step - loss: 1.3522 - acc: 0.7117 - val_loss: 2.2028 - val_acc: 0.4741
Epoch 5/20
181/181 [====] - 1356s 7s/step - loss: 1.0838 - acc: 0.7599 - val_loss: 2.3402 - val_acc: 0.4738

从现在开始(5/20 纪元),如果我让模型永远训练,那么训练损失/acc 将不断提高,而验证损失/acc 将一直停滞在这些值上。

这是一个包含 28 个不同类别的分类问题,因此 0.47 的验证准确度并不是那么糟糕,因为随机性会给出 0.035 的准确度,但我不明白训练集如何非常适合,而验证集还有很多不足之处。

整个数据集由 32,000 张标记良好的图像组成,所有图像都采用相同的配置(想想面部分类问题)。训练大约需要 27,000 张,并通过水平翻转和灰度缩放(总共 93,000 张训练图像)来增强它们,而验证图像没有被增强。从视觉角度来看,训练和验证图像看起来非常相似,我注意到这两组之间没有显着差异(显然是在增强训练集之前)。

类略有不平衡,但不是那么多:最大的类有 2,600 张图像,最小的有 610 张(类大小分布在这两个极端之间呈线性)。

注意一些我已经尝试过但不会改变结果的事情:

  • 辍学:如果我玩弄辍学率,影响不大
  • 正则化:使用具有不同值的 L1 或 L2 不会对结果产生太大影响
  • 批量标准化:有或没有,同样的事情
  • 全连接层数:一层、两层甚至三层(如上),差别不大
  • 预训练网络类型:我尝试使用 VGG16 得到类似结果

无论我做什么,训练指标总是显着提高,而验证却停滞不前。

这仅仅是“获取更多数据”的问题,32,000 张图片对于 28 个班级来说“不够”,尤其是对于目前较小的班级(例如,目前有 610 张图片的班级)还是我做错了什么?我是否应该使用较小的学习率,尽管目前使用的学习率已经相当小了?

从训练集中而不是从验证集中增强图像是错误的吗?我读过这是标准做法,而且这样做似乎也很有意义......

最后,我应该限制可训练的层吗?例如。我应该只训练最后 10 层或 20 层而不是完整的 InceptionV3 网络吗?虽然在使用 VGGxx 模型(纯顺序)时选择可训练层很简单,但对于 Inception 来说似乎有点棘手。欢迎任何有关这方面的建议。

【问题讨论】:

  • 我建议尝试与 L2 不同的正则化函数,或者可能尝试使用 adam 优化器。并且从训练集中扩充数据是正确的,您应该避免从验证集中扩充数据,因为这被认为是一种作弊。我建议的另一件事是尝试检查验证集的混淆矩阵,以了解究竟会发生什么。
  • 感谢@AnuragReddy。正如您在模型配置中看到的那样,我已经在使用 Adam 优化器。你会推荐什么样的正则化器而不是 L2?另外,感谢您确认只增加训练数据是正确的做法。
  • 很抱歉要求添加 adam 优化器,因此在正则化方面,一种配置通常是将正则化器速率设置为非常低的值,例如 (0.0005),因为很少有论文报告该值具有良好的准确度.但我推荐的主要是研究一些技术,如deep implicit regularizationsparse regularization

标签: python tensorflow keras computer-vision


【解决方案1】:

尝试了几个模型,更彻底地查看数据后,似乎标签并没有我想象的那么清晰,不同的28个类别之间存在很多孔隙。

每当模型对测试数据做出“错误”的预测时,仔细检查图片就会发现模型“在某种程度上是正确的”并且标签存在问题。例如。想到一张同时微笑和皱眉的脸。模型可以以同等的合法性说“快乐”或“不快乐”,而“基本事实”的标签将是相当随意的。

因此,验证集上 45% 的准确率似乎是任何模型(或任何人)在考虑这些多孔类时所能达到的最高水平。

InspectionV3 能够在包含数万张图像的训练集上达到 85% 的准确率(一个时期之后),这说明了它能够找到人类无法找到的特定模式的能力不。正如这个例子所表明的,这种能力必须与同样定性的正则化相平衡。

这也意味着给定一个高质量的数据集,标签之间的孔隙率很小,InceptionV3 应该能够很快给出好的结果,例如与 VGG16 相比。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-10
    • 2012-06-15
    • 1970-01-01
    • 1970-01-01
    • 2019-06-16
    • 2015-11-05
    相关资源
    最近更新 更多