引 言 在项目代码中,model.train()、model.eval()和torch.no_grad()频繁出现,有时候并不能够分清楚model.eval()和torch.no_grad()有何区别,尤其对于初次接触深度学习框架的菜鸟。针对此情况,查阅一些资料后将它们之间的不同进行总结,可以迅速地掌握它们的使用技巧。
目录
一、model.train()、model.eval()区别
一、model.train()、model.eval()区别
model.train()和model.eval()函数主要用于将模型中的training属性设置为True或False两种状态,training属性开启或关闭会直接影响BatchNorm层(链接)和Dropout层的运行机理。
- BN层主要是对特征数据进行归一化操作。在训练阶段,BN层采用的是当前批次数据计算所得均值和方差用于对数据进行归一化。在评估阶段,BN层采用的是训练阶段整个数据集的全局统计均值和方差用于数据归一化操作。
- Dropout层在训练阶段作为一个正则化项丢弃一部分神经元放置模型过拟合,在模型评估模式下,Dropout层失效不会丢弃任何神经元。
1.1、model.train()函数
调用model.train()函数将model.training属性变成True状态,BN层对数据进行标准化处理时,使用的均值和方差来自前批次数据,运用移动平均(moving average)策略更新running_mean和running_var。Dropout层会按照一定比例失活一部分神经元。
1.2、model.eval()函数
调用model.eval()函数将model.training属性变成False状态,BN层对样本数据标准化使用训练集的全局统计数据running_mean和running_var。BN层不进行反向传播和梯度更新,running_mean和running_var保持不变。Dropout层使用所有神经元不会选择性丢弃神经元。
二、torch.no_grad()、以及detach()
2.1、detach函数
detach函数从计算图中分离张量,生成与原始张量共享数据的新张量,新张量的requires_grad属性设置成False。新张量不参与计算图的梯度计算。而原始张量的requires_grad保持不变。
a = torch.tensor([1.1],requires_grad=True)
b = a.detach()
print(a.requires_grad) #True
print(b.requires_grad) #False
2.2、torch.no_grad函数
torch.no_grad函数与detach函数使用效果一样,放入上下文管理器中的操作不构建计算图,节省内存和显存消耗。torch.no_grad函数等价于@torch.no_grad()
x = torch.randn(3,2,requires_grad=True)
w = torch.tensor([1.1,2.2])
b = torch.ones(3)
z = torch.matmul(x, w)+b
print(z.requires_grad)
with torch.no_grad():
z = torch.matmul(x, w)+b
print(z.requires_grad)
@torch.no_grad()
def fun(x,w,b):
return torch.matmul(x, w)+b
z = fun(x,w,b)
print(z.requires_grad)
##############
True
False
False
参考博文:
pytorch中model.train()和model.eval()的区别_想念@思恋的博客-CSDN博客
pytroch:model.train()、model.eval()的使用_model.train和model.eval_像风一样自由的小周的博客-CSDN博客