首页 文章

图像分类 . 在启动培训期间验证损失(v1)

提问于
浏览
2

我已经构建了一个包含4个类的小型自定义图像分类训练/ val数据集 . 训练数据集具有~110,000个图像 . 验证数据集具有~6000个图像 .

我遇到的问题是,在训练期间,训练准确性(以最后训练样本的平均准确度衡量)和训练损失都得到改善,而验证准确性和损失保持不变 .

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

在我的实验中,我通过从tensorflow.contrib.slim.nets导入它们来使用几个卷积架构

代码组织如下:

...

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 = ...

...

我没有使用单独的eval脚本,而是在每个时代结束时运行验证步骤,并且出于调试目的,我正在运行早期的val步骤(在训练之前),我正在通过平均检查训练精度训练最后x步的预测 .

当我使用Inception v1模型(注释掉alexnet)时, Logger 输出在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模型时,训练和测试数据中的准确性和验证损失都得到了正确的改善,并且在随后的时期中不断改进 .

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

有人有想法吗?

2 回答

  • 0

    您似乎使用logits来计算验证损失;使用预测,它可能会有所帮助 .

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

    通过论坛搜索,阅读各种线程并进行实验后,我找到了问题的根源 .

    使用一个基本上从另一个例子中回收的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_scope将衰减设置为0.9997,这是稳定的,但显然需要很多步骤才能收敛 . 使用相同的arg_scope但衰减设置为0.99或0.9确实有助于这个简短的训练场景 .

相关问题