model.train()和model.eval()的用法及model.eval()可能导致测试准确率的下降

问题导入:

一般我们在训练模型时会在前面加上:model.train()
在测试模型时会在前面使用:model.eval()
但是在某次使用网络测试模型时,训练准确率很高,但测试准确率很低,排查了各种问题,绝不是过拟合问题,因为都使用了训练集来测试模型,准确率还是不行,最终发现把model.eval()去掉后,准确率就上来了,百思不得其解。

为何使用model.train()和model.eval()?

model.train()和model.eval()主要是针对网络中存在BN层(Batch Normalization)和Dropout,在训练模型前添加model.train(),在测试模型前添加model.eval()。

针对BN层:
model.train():是保证BN层用每一批数据的均值和方差,即针对每个mini-batch的 ;
model.eval():是保证BN用全部训练数据的均值和方差,即针对单张图片的;
针对Dropout层:
model.train():随机取一部分网络连接来训练更新参数;
model.eval():利用到了所有网络连接;

为什么有时测试时使用model.eval()会使得准确率降低?

主要是由于batch size设置较小,如1,2,训练时针对BN层计算的均值和方差只使用很小的mini batch数据,而测试中因为加入model.eval()使用的是单张图片的均值和方差,训练时的BN层学习的参数经过eval()的固定,对测试时的单张图片的均值和方差适应性较差,就会导致准确率下降。
为什么参数可能不适应,这里就需要知道BN层的原理,如下:
参考文章:BN(Batch Normalization)层原理与作用model.train()和model.eval()的用法及model.eval()可能导致测试准确率的下降_第1张图片
根据BN层的原理可以知道,当batch size设置比较大时,BN层中可学习的参数每次所使用的均值和方差更接近全局的数据,因此其参数对测试时的单张图像也是普遍适用的;但是当batch size很小时,BN层中可学习的参数每次所使用的均值和方差很少,其参数也因此对测试的单张图像的均值和方差不适应。

问题解决:如何解决model.eval()可能导致的准确率下降问题?

1.尽量将batch size设置大一些(2的整数次幂),32,64,128,256,能多大就多大,但是一般不要超过512.
2.如果设备受限,导致batch size只能设置很小(1,2),那测试时可以把eval()去掉,前提是网络结构中并没有dropout层。

你可能感兴趣的:(深度学习,深度学习,pytorch)