以前使用Caffe的时候没注意这个,现在使用预训练模型来动手做时遇到了。在slim中的自带模型中inception, resnet, mobilenet等都自带BN层,这个坑在《实战Google深度学习框架》第二版这本书P166里只是提了一句,没有做出解答。

  书中说训练时和测试时使用的参数is_training都为True,然后给出了一个链接供参考。本人刚开始使用时也是按照书中的做法没有改动,后来从保存后的checkpoint中加载模型做预测时出了问题:当改变需要预测数据的batchsize时预测的label也跟着变,这意味着checkpoint里面没有保存训练中BN层的参数,使用的BN层参数还是从需要预测的数据中计算而来的。这显然会出问题,当预测的batchsize越大,假如你的预测数据集和训练数据集的分布一致,结果就越接近于训练结果,但如果batchsize=1,那BN层就发挥不了作用,结果很难看。

  那如果在预测时is_traning=false呢,但BN层的参数没有从训练中保存,那使用的就是随机初始化的参数,结果不堪想象。

  所以需要在训练时把BN层的参数保存下来,然后在预测时加载,参考几位大佬的博客,有了以下训练时添加的代码:

 update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
with tf.control_dependencies(update_ops):
train_step = tf.train.AdamOptimizer(learning_rate=0.0001).minimize(loss) # 设置保存模型
var_list = tf.trainable_variables()
g_list = tf.global_variables()
bn_moving_vars = [g for g in g_list if 'moving_mean' in g.name]
bn_moving_vars += [g for g in g_list if 'moving_variance' in g.name]
var_list += bn_moving_vars
saver = tf.train.Saver(var_list=var_list, max_to_keep=5)

这样就可以在预测时从checkpoint文件加载BN层的参数并设置is_training=False。

最后要说的是,虽然这么做可以解决这个问题,但也可以利用预测数据来计算BN层的参数,不是说一定要保存训练时的参数,两种方案可以作为超参数来调节使用,看哪种方法的结果更好。

感谢几位大佬的博客解惑:

  https://blog.csdn.net/dongjbstrong/article/details/80447110?utm_source=blogxgwz0

  http://www.cnblogs.com/hrlnw/p/7227447.html

Tensorflow训练和预测中的BN层的坑的更多相关文章

  1. tensorflow CNN 卷积神经网络中的卷积层和池化层的代码和效果图

    tensorflow CNN 卷积神经网络中的卷积层和池化层的代码和效果图 因为很多 demo 都比较复杂,专门抽出这两个函数,写的 demo. 更多教程:http://www.tensorflown ...

  2. TensorFlow使用记录 (七): BN 层及 Dropout 层的使用

    参考:tensorflow中的batch_norm以及tf.control_dependencies和tf.GraphKeys.UPDATE_OPS的探究 1. Batch Normalization ...

  3. 【转载】 Pytorch(1) pytorch中的BN层的注意事项

    原文地址: https://blog.csdn.net/weixin_40100431/article/details/84349470 ------------------------------- ...

  4. 吴裕雄 python 神经网络——TensorFlow训练神经网络:不使用隐藏层

    import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data INPUT_NODE = 784 ...

  5. tensorflow 训练最后预测结果为一个定值,可能的原因

    训练一个分类网络,没想到预测结果为一个定值. 找了很久发现,是因为tensor的维度的原因.  注意:我说的是我的label数据的维度. 我的输入是: y_= tf.placeholder(tf.in ...

  6. 【转载】 【caffe转向pytorch】caffe的BN层+scale层=pytorch的BN层

    原文地址: https://blog.csdn.net/u011668104/article/details/81532592 ------------------------------------ ...

  7. tensorflow在文本处理中的使用——Word2Vec预测

    代码来源于:tensorflow机器学习实战指南(曾益强 译,2017年9月)——第七章:自然语言处理 代码地址:https://github.com/nfmcclure/tensorflow-coo ...

  8. BN层

    论文名字:Batch Normalization: Accelerating Deep Network Training by  Reducing Internal Covariate Shift 论 ...

  9. 【卷积神经网络】对BN层的解释

    前言 Batch Normalization是由google提出的一种训练优化方法.参考论文:Batch Normalization Accelerating Deep Network Trainin ...

随机推荐

  1. 617A

    #include <stdio.h> int main() { int moves[5]={1,2,3,4,5}; int x; scanf("%d", &x) ...

  2. new Date() 日期格式处理

    var myDate = new Date(); myDate.getYear(); //获取当前年份(2位) myDate.getFullYear(); //获取完整的年份(4位,1970-???? ...

  3. IP代理网址

    http://www.kuaidaili.com/free/ http://www.66ip.cn/ http://www.xicidaili.com/nn/ http://www.ip3366.ne ...

  4. 3.1.3 Spring之AOP

    三.Spring之AOP 1. 代理模式 (1) 什么是代理模式? 代理模式是面向对象编程的23种基础设计模式之一.为其他对象(代理对象)提供一种代理以控制对这个对象(源对象)的访问. 就是说,声明一 ...

  5. face++静态库转为动态库之二

    上一篇的时候,已经介绍了如何将carthage转为动态库.这一篇,我们是单纯的建一个动态库.还是以face++为例 查看上一篇: face++静态库转为动态库 制作动态库 1.创建一个工程MGLive ...

  6. hibernate框架的简单入门

    1.什么是框架 框架是一个半成品,框架帮我们实现了一部分的功能. 2.使用框架的最大好处 使用框架的最大好处就是,少写一部分代码但仍能实现我们所需要实现的功能. 3.什么是hiberbnate框架 ( ...

  7. Ubuntu MariaDB PhpMyAdmin

    root@www:~# apt-get -y install phpmyadmin php-mbstring php-gettext # select which one you using (thi ...

  8. C#中的as关键字

    你能进到这篇文章…… 首先你可能明白类似于 double num=0;int m=(int) num; 或者你明白 int m=209;String str=m.toString();或者说你甚至见过 ...

  9. 使用gulp构建一个项目

    gulp是前端开发过程中自动构建项目的工具,相同作用的还有grunt.构建工具依靠插件能够自动监测文件变化以及完成js/sass/less/html/image/css/coffee等文件的语法检查. ...

  10. linux系统安装MongoDB

    1.在官网https://www.mongodb.org/dl/linux/x86_64下载对应的安装压缩包,我用的是3.2.5,建议使用此版本,版本越高,可能会出现其它未知问题,比如需要glibc高 ...