2017-08-04 106 views
2

我已经建立了一个包含4个类的小型自定义图像分类训练/ val数据集。 训练数据集有〜110.000个图像。 验证数据集具有〜6.000图像。图像分类。 (v1)

我遇到的问题是,在训练中,无论是训练精度(如在最后的训练样本的平均测量精度)和培训损耗而提高,同时验证准确性和损失保持不变。

这只有当我使用以来和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脚本,我跑在每个时期和ALS结束的验证步骤o,为了调试目的,我正在运行一个早期的val步骤(在训练之前),并且通过对最后x个步骤的训练预测进行平均来检查训练的准确性。

当我使用盗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模型时正确地改进,他们保持在随后的时期提高。

我不明白是什么可能是问题的原因,以及为什么它使用开始/ RESNET模型时,但alexnet训练的时候不提出了自己。

有没有人有想法?

回答

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更新的护理正在做。

由于缓慢移动的平均值更新,短期训练运行仍然存在问题。

默认苗条arg_scope的衰减设置为0.9997,这是稳定的,但显然需要很多步骤来收敛。使用相同的arg_scope,但将衰减设置为0.99或0.9,在此短期培训场景中确实有所帮助。

0

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

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

使用tf.nn.sparse_softmax_cross_entropy_with_logits计算损失,该值使用未缩放的logits并在内部执行softmax。 – user3897060