踩坑: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将图片转换成excel文档格式
Dec 30 Python
Python实现JSON反序列化类对象的示例
Jan 31 Python
对Python 两大环境管理神器 pyenv 和 virtualenv详解
Dec 31 Python
python实现简单图书管理系统
Nov 22 Python
使用 Python 清理收藏夹里已失效的网站
Dec 03 Python
Python实现i人事自动打卡的示例代码
Jan 09 Python
python判断两个序列的成员是否一样的实例代码
Mar 01 Python
VS2019+python3.7+opencv4.1+tensorflow1.13配置详解
Apr 16 Python
浅谈Python中文件夹和python package包的区别
Jun 01 Python
基于python SMTP实现自动发送邮件教程解析
Jun 02 Python
浅谈TensorFlow中读取图像数据的三种方式
Jun 30 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
一些关于PHP的知识
2006/11/17 PHP
PHP5新特性: 更加面向对象化的PHP
2006/11/18 PHP
php中实现记住密码自动登录的代码
2011/03/02 PHP
PHP多线程批量采集下载美女图片的实现代码(续)
2013/06/03 PHP
一个PHP的远程图片抓取函数分享
2013/09/25 PHP
TP3.2批量上传文件或图片 同名冲突问题的解决方法
2017/08/01 PHP
PHP中number_format()函数的用法讲解
2019/04/08 PHP
PHP回调函数简单用法示例
2019/05/08 PHP
PHP大文件分割分片上传实现代码
2020/12/09 PHP
JavaScript中使用正则匹配多条,且获取每条中的分组数据
2010/11/30 Javascript
javascript实现可改变滚动方向的无缝滚动实例
2013/06/17 Javascript
Jquery操作js数组及对象示例代码
2014/05/11 Javascript
原生js和jQuery随意改变div属性style的名称和值
2014/10/22 Javascript
高效利用Angular中内置服务$http、$location等
2016/03/22 Javascript
javascript表单处理具体实现代码(表单、链接、按钮)
2016/05/07 Javascript
javascript中Date对象的使用总结
2016/11/21 Javascript
Vue.js:使用Vue-Router 2实现路由功能介绍
2017/02/22 Javascript
微信小程序使用Socket的实例
2017/09/19 Javascript
jquery实现Ajax请求的几种常见方式总结
2019/05/28 jQuery
Vue的生命周期操作示例
2019/09/17 Javascript
[41:37]DOTA2北京网鱼队选拔赛——冲击职业之路
2015/04/13 DOTA
[00:32]2018DOTA2亚洲邀请赛Newbee出场
2018/04/03 DOTA
python中sleep函数用法实例分析
2015/04/29 Python
numpy添加新的维度:newaxis的方法
2018/08/02 Python
python将字典列表导出为Excel文件的方法
2019/09/02 Python
Python实现Word表格转成Excel表格的示例代码
2020/04/16 Python
用python 绘制茎叶图和复合饼图
2021/02/26 Python
林清轩官方网站:山茶花润肤油开创者
2016/10/26 全球购物
为什么会有内存对齐
2016/10/10 面试题
linux系统都有哪些运行级别
2016/03/26 面试题
歌唱比赛获奖感言
2014/01/21 职场文书
2015年城管个人工作总结范文
2015/04/20 职场文书
单身证明格式样本
2015/06/15 职场文书
2015年教导处教学工作总结
2015/07/22 职场文书
python如何在word中存储本地图片
2021/04/07 Python
java高级用法JNA强大的Memory和Pointer
2022/04/19 Java/Android