探究pytorch model.eval()测试效果远差于model.train()

2022-10-17 10:18:23

前言:
第一篇博客,记录下自己的学习心得。如有谬误,欢迎指正。

为什么用model.eval()

当网络中存在BN层或者Dropout,在测试的时候需要固定住固定BN层和dropout层。关于BN层的详细介绍可以参考这篇博文:Pytorch的BatchNorm层使用中容易出现的问题

训练数据的时候acc可以达到99%,但是测试时acc只有33%,显然这是不行的。查询了一些资料给出的解决方案如下:、

  1. 删去相同的BN层
    其实我没太理解这个,怎么才算相同的BN层

  2. track_running_stats设为False
    含义为测试时用当前batch的方差和均值(为True则使用训练时得到的方差和均值)。我在这样设定后,测试效果确实变好了,但是之前训练得到方差和均值就没啥意义了。

  3. 数据进行归一化
    有的人可能是没有进行数据归一化从而导致测试效果较差。我的训练集归一化什么的肯定是没问题的,将训练集作为测试集,原则上应该拟合的很好,但在加model.eval()后,效果依然不好,显然不是归一化的问题了。

  4. 增大训练样本batch_size
    没想到会是这方面原因,因为我以前觉得加不加大batch_size,最后得到的方差和均值都一样,有点搞笑。
    网络中加入了BN层,训练时BN层中的方差和均值是根据每个batch的样本进行更新的,测试的时候这俩个参数是固定的。
    我把训练的batch_size设为了1,那么训练完成后获得的方差和均值是接近于最后一个样本的方差和均值的。加了model.eval(),在测试的时候相当于是用这最后一个样本的方差和均值来获得测试集的输出,显然这个方差和均值是不具备全局性的,结果肯定是不好的。在增大batch_size后,获得的方差和均值是更接近于全局特性的,所以当我将batch_size设为64后,测试集的acc提到了85%,尽管不是很高,但也足以证明增大batch_size是十分有效的。

  • 作者:Coding-Prince
  • 原文链接:https://blog.csdn.net/qq_42362891/article/details/108119556
    更新时间:2022-10-17 10:18:23