model.train() 与model.eval() 的区别

1. 背景说明

        参考: pytorch中model.eval的作用

        如果模型中有BN层(Batch Normalization)和Dropout,需要在训练时添加model.train(),在测试时添加model.eval()。

BN层:

        其作用对网络中间的每层进行归一化处理,并且使用变换重构保证每层提取的特征分布不会被破坏。训练时是针对每个mini-batch的,但是测试是针对单张图片的,即不存在batch的概念。由于网络训练完成后参数是固定的,每个batch的均值和方差是不变的,因此直接结算所有batch的均值和方差。所有Batch Normalization的训练和测试时的操作不同。

 model.train():  保证BN层用每一批数据的均值和方差;

 model.eval():  保证BN用全部训练数据的均值和方差。

Dropout层:

        其作用克服Overfitting,在每个训练批次中,通过忽略一半的特征检测器,可以明显的减少过拟合现象。

  model.train():  随机取一部分网络连接来训练更新参数;

  model.eval():  利用到了所有网络连接。

2. model.train()

        train模式下,dropout层会按照设定的参数p设置保留激活单元的概率; BN层会继续计算数据的mean和var等参数并更新。

3. model.eval()

        在validation时,会使用model.eval()切换到测试模式,用于通知dropout层和BN层在train和val模式间切换。不启用BN层和Dropout,保证BN和dropout不发生变化,pytorch框架会自动把BN和Dropout固定住,不会取平均,而是用训练好的值,不然的话,一旦test的batch_size过小,很容易就会被BN层影响结果。     

       dropout层会让所有的激活单元都通过,而BN层会停止计算和更新mean和var,直接使用在训练阶段学到的mean和var值。该模式不会影响各层的gradient计算行为,即gradient计算和存储与training模式一样,只是不进行反传(backprobagation)

       此时,可使用with torch.no_grad()停止autograd模块的工作,以起到加速和节省显存的作用,具体行为就是停止gradient计算,从而节省了GPU算力和显存,但no_grad()本身并不会影响dropout和BN层的行为。

所以二者一般配合使用。即:

        如果不在意显存大小和计算时间的话,仅仅使用model.eval()已足够得到正确的validation的结果;而with torch.zero_grad()则是更进一步加速和节省gpu空间(因为不用计算和存储gradient),从而可以更快计算,也可以跑更大的batch来测试。

4. 梯度是否更新

1. requires_grad

        requires_grad是Variable变量中的一个属性,requires_grad的属性默认为False(即不需要计算梯度),若一个节点requires_grad被设置为True,那么所有依赖它的节点的requires_grad都为True,此时要求计算tensor的梯度。

2. model.eval()                 

        数据不会进行反向传播,但仍然需要计算梯度;
3. with torch.no_grad()  

        torch.no_grad() 是一个上下文管理器,被该语句内部的语句将不会计算梯度,也不会进行反向传播。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值