踩坑:pytorch中eval模式下结果远差于train模式介绍


Posted in Python onJune 23, 2020

首先,eval模式和train模式得到不同的结果是正常的。我的模型中,eval模式和train模式不同之处在于Batch Normalization和Dropout。Dropout比较简单,在train时会丢弃一部分连接,在eval时则不会。Batch Normalization,在train时不仅使用了当前batch的均值和方差,也使用了历史batch统计上的均值和方差,并做一个加权平均(momentum参数)。在test时,由于此时batchsize不一定一致,因此不再使用当前batch的均值和方差,仅使用历史训练时的统计值。

我出bug的现象是,train模式下可以收敛,但一旦在测试中切换到了eval模式,结果就很差。如果在测试中仍沿用train模式,反而可以得到不错的结果。为了确保是程序bug而不是算法本身就不适合于预测,我在测试时再次使用了训练集,正常情况下此时应发生过拟合,正确率一定会很高,然而eval模式下正确率仍然很低。参照网上的一些说法(Performance highly degraded when eval() is activated in the test phase
),我调大了batchsize,降低了BN层的momentum,检查了是否存在不同层使用相同BN层的bug,均不见效。有一种方法说应在BN层设置track_running_stats为False,它虽然带来了好的效果,但实际上它只不过是不用eval模式,切回train模式罢了,所以也不对。

学习了在训练过程中,如何将BN层中统计的均值和方差输出。即在forward()中,

# bn是一个BN层,torch.nn.batch_normalization(...)
print(bn.running_mean)
print(bn.running_var)

同时学习了如何输出一个Tensor自身的均值和方差,即

# x是一个Tensor,dims是需要计算的维度
print(x.cpu().detach().numpy().mean(dims)
print(x.cpu().detach().numpy().var(dims)

观察每一层的输出结果,发现出现了很大的方差,才猛然意识到自己的输入数据没有做归一化(事后想想也确实如此,毕竟模型和训练方法都是github上参考别人的,出错概率很小;反而是自己写的DataSet部分,其实是最容易出错的)。给模型加上归一化后,eval和train的结果就没有问题了。

再次验证了我的观点:越是玄学的问题,越是傻逼的bug。

补充知识:Pytorch中的train和eval用法注意点

1.介绍

一般情况,model.train()是在训练的时候用到,model.eval()是在测试的时候用到

2.用法

如果模型中没有类似于BN这样的归一化或者Dropout,model.train()和model.eval()可以不要(建议写一下,比较安全),并且model.train()和model.eval()得到的效果是一样

如果模型中有类似于BN这样的归一化或者Dropout,并且程序需要边训练和边测试,最好就是用model.eval()测试完之后,后面补一个model.train()。

其中model.train()是保证BN用每一批数据的均值和方差,而model.eval()是保证BN用全部训练数据的均值和方差;而对于Dropout,model.train()是随机取一部分网络连接来训练更新参数,而model.eval()是利用到了所有网络连接(结果是取了平均)

以上这篇踩坑:pytorch中eval模式下结果远差于train模式介绍就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python通过定义一个类实例作为ftp回调方法
May 04 Python
Python用zip函数同时遍历多个迭代器示例详解
Nov 14 Python
浅谈Matplotlib简介和pyplot的简单使用——文本标注和箭头
Jan 09 Python
python简单商城购物车实例代码
Mar 15 Python
基于python OpenCV实现动态人脸检测
May 25 Python
python matlibplot绘制3D图形
Jul 02 Python
Python封装成可带参数的EXE安装包实例
Aug 24 Python
如何在mac环境中用python处理protobuf
Dec 25 Python
Python爬虫库requests获取响应内容、响应状态码、响应头
Jan 25 Python
浅谈Python协程
Jun 17 Python
python 如何快速复制序列
Sep 07 Python
python 通过 pybind11 使用Eigen加速代码的步骤
Dec 07 Python
pytorch掉坑记录:model.eval的作用说明
Jun 23 #Python
Python使用Selenium实现淘宝抢单的流程分析
Jun 23 #Python
python2和python3哪个使用率高
Jun 23 #Python
python使用QQ邮箱实现自动发送邮件
Jun 22 #Python
浅谈keras中loss与val_loss的关系
Jun 22 #Python
python实现简易版学生成绩管理系统
Jun 22 #Python
python能否java成为主流语言吗
Jun 22 #Python
You might like
第五节 克隆 [5]
2006/10/09 PHP
php set_time_limit(0) 设置程序执行时间的函数
2010/05/26 PHP
PHP数组无限分级数据的层级化处理代码
2012/12/29 PHP
单点登录 Ucenter示例分析
2013/10/29 PHP
ThinkPHP3.2.2的插件控制器功能简述
2014/07/09 PHP
php实现图片上传时添加文字和图片水印技巧
2020/04/18 PHP
Laravel 微信小程序后端搭建步骤详解
2019/11/26 PHP
php使用event扩展的io复用测试的示例
2020/10/20 PHP
jquery 学习笔记 传智博客佟老师附详细注释
2020/09/12 Javascript
Javascript图像处理—亮度对比度应用案例
2013/01/03 Javascript
js/html光标定位的实现代码
2013/09/23 Javascript
jQuery实现新闻播报滚动及淡入淡出效果示例
2018/03/23 jQuery
React Native开发封装Toast与加载Loading组件示例
2018/09/08 Javascript
ios设备中angularjs无法改变页面title的解决方法
2018/09/13 Javascript
Vue使用localStorage存储数据的方法
2019/05/27 Javascript
vue-cli4项目开启eslint保存时自动格式问题
2020/07/13 Javascript
[01:00:11]DOTA2-DPC中国联赛 正赛 CDEC vs DLG BO3 第一场 2月7日
2021/03/11 DOTA
Python实现登录人人网并抓取新鲜事的方法
2015/05/11 Python
python各种语言间时间的转化实现代码
2016/03/23 Python
python实现数据图表
2017/07/29 Python
Sanic框架基于类的视图用法示例
2018/07/18 Python
Python hashlib模块加密过程解析
2019/11/05 Python
Pytorch数据拼接与拆分操作实现图解
2020/04/30 Python
通过Python pyecharts输出保存图片代码实例
2020/11/25 Python
Python命令行参数argv和argparse该如何使用
2021/02/08 Python
详解CSS3中强大的filter(滤镜)属性
2017/06/29 HTML / CSS
韩国CJ食品专卖网:CJonmart
2016/09/11 全球购物
介绍一下Mysql的存储引擎
2015/02/12 面试题
三个Unix的命令面试题
2015/04/12 面试题
会计求职自荐信
2014/06/20 职场文书
小学生感恩父母演讲稿
2014/08/28 职场文书
2014企业年终工作总结
2014/12/23 职场文书
爱心助学感谢信
2015/01/21 职场文书
党员观看《筑梦中国》心得体会
2016/01/18 职场文书
MySQL GRANT用户授权的实现
2021/06/18 MySQL
详解Flutter和Dart取消Future的三种方法
2022/04/07 Java/Android