zoukankan      html  css  js  c++  java
  • Tensorflow训练和预测中的BN层的坑

      以前使用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层的参数保存下来,然后在预测时加载,参考几位大佬的博客,有了以下训练时添加的代码:

     1 update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
     2 with tf.control_dependencies(update_ops):
     3         train_step = tf.train.AdamOptimizer(learning_rate=0.0001).minimize(loss)
     4 
     5 # 设置保存模型
     6 var_list = tf.trainable_variables()
     7 g_list = tf.global_variables()
     8 bn_moving_vars = [g for g in g_list if 'moving_mean' in g.name]
     9 bn_moving_vars += [g for g in g_list if 'moving_variance' in g.name]
    10 var_list += bn_moving_vars
    11 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

  • 相关阅读:
    docker下用keepalived+Haproxy实现高可用负载均衡集群
    Centos 7 搭建蓝鲸V4.1.16社区版
    IDEA中Thrift插件配置
    idea打包java可执行jar包
    CentOS7 docker.repo 用阿里云Docker Yum源
    linux 配置maven环境变量
    Linux中修改docker镜像源及安装docker
    Spring-boot和Spring-Cloud遇到的问题
    IntelliJ Idea 常用快捷键列表
    Invocation of destroy method failed on bean with name ‘XXXX’
  • 原文地址:https://www.cnblogs.com/baijing1/p/9842321.html
Copyright © 2011-2022 走看看