我不得不说这可能是我遇到过的最奇怪的问题之一。
我正在实现ResNet以使用tensorflow在cifr-10上执行10分类。在训练阶段一切似乎都很好-损失稳步下降,并且训练集的准确性一直提高到90%以上,但是在推理过程中结果完全不正常。
我已经非常仔细地分析了我的代码,并排除了在馈入数据或保存/加载模型时出错的可能性。因此,训练阶段和测试阶段之间的唯一区别在于批处理规范化层。
对于BN层,我直接使用tf.layers.batch_normalization
,并且我认为使用tf.layers.batch_normalization
时要注意所有陷阱。
具体来说,我已经包括了train_op
的依赖项,
update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
with tf.control_dependencies(update_ops):
self.train_op = optimizer.minimize(self.losses)
此外,为了保存和加载模型,我将var_list
指定为tf.global_variables()
。此外,我使用training=True
进行训练,并使用training=False
进行测试。
尽管如此,即使将其应用于训练所用的相同数据,推理过程中的准确性也仅为10%左右。当我输出网络的最后一层(即,输入到softmax的10维向量)时,我发现训练过程中10维向量中每个项的大小始终为1e0或1e-1,而用于推理,可能是1e4甚至1e5。 最奇怪的是,我发现推理过程中10维向量的大小与训练中使用的批量大小有关,即,批量大小越大,大小越小。
此外,我还发现BN层的moving_mean
和moving_variance
的大小也与批次大小相关,但是为什么这可能呢?我以为moving_mean
是整个培训人口的均值,moving_variance
也是。那么,为什么与批量大小有什么关系呢?
我认为对于使用带有Tensorflow的BN一定有一些我不知道的地方。这个问题真的会让我发疯!考虑到将BN与PyTorch一起使用有多方便,我从没想过要在Tensorflow中处理这样的问题!
答案 0 :(得分:0)
问题已解决!
我阅读了tensorflow的源代码。根据我的理解,momentum
中tf.layers.batch_normalization
的值应为1-1 / num_of_batches。默认值为0.99,这意味着当训练数据中有100批次时,默认值最合适。
我没有发现任何提及此的文件。希望这对那些在张量流中与BN有相同问题的人有所帮助!