踩坑: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提取内容关键词的方法
Mar 16 Python
Python操作MySQL模拟银行转账
Mar 12 Python
浅谈dataframe中更改列属性的方法
Jul 10 Python
使用Selenium破解新浪微博的四宫格验证码
Oct 19 Python
基于python实现名片管理系统
Nov 30 Python
Python PIL图片添加字体的例子
Aug 22 Python
python 多进程队列数据处理详解
Dec 23 Python
Pytorch.nn.conv2d 过程验证方式(单,多通道卷积过程)
Jan 03 Python
python使用Thread的setDaemon启动后台线程教程
Apr 25 Python
详解python中groupby函数通俗易懂
May 14 Python
使用python-cv2实现Harr+Adaboost人脸识别的示例
Oct 27 Python
用Python实现Newton插值法
Apr 17 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
备份mysql数据库的php代码(一个表一个文件)
2010/05/28 PHP
Smarty的配置与高级缓存技术分享
2012/06/05 PHP
Linux平台PHP5.4设置FPM线程数量的方法
2016/11/09 PHP
JScript分割字符串示例代码
2013/09/04 Javascript
javascript中字符串的定义示例代码
2013/12/19 Javascript
jquery easyui combox一些实用的小方法
2013/12/25 Javascript
WebView启动支付宝客户端支付失败的问题小结
2017/01/11 Javascript
AngularJS 文件上传控件 ng-file-upload详解
2017/01/13 Javascript
Scala解析Json字符串的实例详解
2017/10/11 Javascript
vuejs实现标签选项卡动态更改css样式的方法
2018/05/31 Javascript
Vue-cli3项目配置Vue.config.js实战记录
2018/07/29 Javascript
Vue 与 Vuex 的第一次接触遇到的坑
2018/08/16 Javascript
vue3.0 CLI - 2.2 - 组件 home.vue 的初步改造
2018/09/14 Javascript
使用vue-cli webpack 快速搭建项目的代码
2018/11/21 Javascript
javascript实现fetch请求返回的统一拦截
2019/12/22 Javascript
vue 导航菜单刷新状态不消失,显示对应的路由界面操作
2020/08/06 Javascript
Zabbix实现微信报警功能
2016/10/09 Python
利用 Monkey 命令操作屏幕快速滑动
2016/12/07 Python
Python实现删除文件中含“指定内容”的行示例
2017/06/09 Python
python itchat实现调用微信接口的第三方模块方法
2019/06/11 Python
pip 安装库比较慢的解决方法(国内镜像)
2019/10/06 Python
Python timer定时器两种常用方法解析
2020/01/20 Python
纯css3实现的动画按钮的实例教程
2014/11/17 HTML / CSS
世界上最大的在线旅行社新加坡网站:Expedia新加坡
2016/08/25 全球购物
英国广泛的照明产品网站:Lights4living
2018/01/28 全球购物
求职信内容考虑哪几点
2013/10/05 职场文书
xxx同志考察材料
2014/02/07 职场文书
大学生党员自我评价范文
2014/04/09 职场文书
离婚协议书怎么写2014
2014/09/30 职场文书
2014年安全工作总结范文
2014/11/13 职场文书
2014年人事专员工作总结
2014/11/19 职场文书
新生儿未入户证明
2015/06/23 职场文书
使用Vue3+Vant组件实现App搜索历史记录功能(示例代码)
2021/06/09 Vue.js
Python面向对象编程之类的概念
2021/11/01 Python
nginx设置资源请求目录的方式详解
2022/05/30 Servers
Windows Server 修改远程桌面端口的实现
2022/06/25 Servers