提问者:小点点

图像分类。在初始培训期间,验证丢失被卡住(v1)


我已经建立了一个小的自定义图像分类训练/val数据集与4类。训练数据集有~110,000张图像。验证数据集约有6.000个图像。

我遇到的问题是,在培训过程中,培训准确度(以上次培训样本的平均准确度衡量)和培训损失都有所提高,而验证准确度和损失保持不变。

这仅在我使用inception和resnet模型时发生,如果我在相同的培训和验证数据上使用alexnet模型,验证损失和准确性会提高

在我的实验中,我从tensorflow导入了几种卷积结构。contrib。苗条的网

该守则的组织如下:

...

images, labels = preprocessing(..., train=True)
val_images, val_labels = preprocessing(..., train=False)

...

# AlexNet model
with slim.arg_scope(alexnet.alexnet_v2_arg_scope()):
    logits, _ = alexnet.alexnet_v2(images, ..., is_training=True)
    tf.get_variable_scope().reuse_variables()
    val_logits, _ = alexnet.alexnet_v2(val_images, ..., is_training=False)

# Inception v1 model
with slim.arg_scope(inception_v1_arg_scope()):
    logits, _ = inception_v1(images, ..., is_training=True)
    val_logits, _ = inception_v1(val_images, ..., is_training=False, reuse=True)

loss = my_stuff.loss(logits, labels)
val_loss = my_stuff.loss(val_logits, val_labels)

training_accuracy_op = tf.nn.in_top_k(logits, labels, 1)
top_1_op = tf.nn.in_top_k(val_logits, val_labels, 1)
train_op = ...

...

我没有使用单独的评估脚本,而是在每个纪元的末尾运行验证步骤,并且出于调试目的,我运行了一个早期的val步骤(训练前),并且通过对最后x个步骤的训练预测进行平均来检查训练的准确性。

当我使用Inception v1模型(注释掉alexnet模型)时,1个历元后的记录器输出如下:

early Validation Step
precision @ 1 = 0.2440 val loss = 1.39
Starting epoch 0
step 50, loss = 1.38, training_acc = 0.3250
...
step 1000, loss = 0.58, training_acc = 0.6725
...
step 3550, loss = 0.45, training_acc = 0.8063
Validation Step
precision @ 1 = 0.2473 val loss = 1.39

如图所示,经过一个历元后,训练精度和损失都有很大提高,但验证损失根本没有改变。这已经测试了至少10次,结果总是一样的。我可以理解,如果验证丢失由于过度拟合而变得更糟,但在这种情况下,它根本没有改变。

为了排除验证数据的任何问题,我还在使用超薄的AlexNet实现进行训练时展示了结果。使用alexnet模型进行培训会产生以下输出:

early Validation Step
precision @ 1 = 0.2448 val loss = 1.39
Starting epoch 0
step 50, loss = 1.39, training_acc = 0.2587
...
step 350, loss = 1.38, training_acc = 0.2919
...
step 850, loss = 1.28, training_acc = 0.3898
Validation Step
precision @ 1 = 0.4069 val loss = 1.25

在使用alexnet模型时,训练和测试数据中的准确性和验证损失都得到了正确的提高,并且在随后的几年中不断提高。

我不明白问题的原因是什么,以及为什么它在使用inception/resnet模型时会出现,而在使用alexnet进行培训时却不会出现。

有人有想法吗?


共2个答案

匿名用户

在搜索论坛、阅读各种帖子并进行实验后,我找到了问题的根源。

使用一个基本上从另一个例子中回收的train_op是个问题,它与alexnet模型配合得很好,但是在其他模型上不起作用,因为它缺乏批处理规范化更新。

要解决这个问题,我必须使用

optimizer = tf.train.GradientDescentOptimizer(0.005)
train_op = slim.learning.create_train_op(total_loss, optimizer)

train_op = tf.contrib.layers.optimize_loss(total_loss, global_step, .005, 'SGD')

这似乎解决了正在进行的batchnorm更新。

由于移动平均线更新缓慢,这个问题在短期训练中仍然存在。

默认的slim arg_范围将衰减设置为0.9997,这是稳定的,但显然需要许多步骤才能收敛。使用相同的arg_范围,但衰减设置为0.99或0.9,在这个简短的培训场景中确实有所帮助。

匿名用户

您似乎正在使用logits计算验证损失;使用预测,这可能会有所帮助。

val_logits, _ = inception_v1(val_images, ..., is_training=False, reuse=True)
val_logits = tf.nn.softmax(val_logits)