【发布时间】: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 regularization、sparse regularization
标签: python tensorflow keras computer-vision