pytorch学习笔记——requires_grad、detach、torch.no_grad

requires_grad()

requires_grad表示这个tensor是否要求计算梯度,自己新建的tensor(即叶子节点)默认为False,不用计算梯度。如果创建一个张量x,并设置其 requires_grad参数为True,程序将会追踪所有对于该张量的操作,当完成计算后通过调用 .backward(),自动计算所有的梯度, 这个张量的所有梯度将会自动积累到 .grad 属性。(即如果某个输入需要计算梯度,则其输出也默认需要计算梯度,就算想把这个输出强行改为False也不行会提示错误),依赖于requires_grad为True的tensor默认其值为True,pytorch自定义的卷积层,全连接层的参数也默认requires_grad为True.
在这里插入图片描述

detach()

返回一个tensor,与原tensor共享值,但没有grad_fn和requires_grad改为False。

torch.no_grad()

是一个上下文管理器,被该语句 wrap 起来的部分将不会track 梯度。
with torch.no_grad()或者@torch.no_grad()中的数据不需要计算梯度,也不会进行反向传播。这种情况是允许输入要求梯度,改变输出的requires_grad。

import torch
x = torch.randn(2, 3, requires_grad = True)
y = torch.randn(2, 3, requires_grad = False)
z = torch.randn(2, 3, requires_grad = False)
m=x+y+z
with torch.no_grad():
    w = x + y + z
print(w)
print(m)
print(w.requires_grad)
print(w.grad_fn)
print(m.requires_grad)
tensor([[-1.4483, -0.1749,  1.7052],
        [-0.4888, -0.1138, -3.6700]])
tensor([[-1.4483, -0.1749,  1.7052],
        [-0.4888, -0.1138, -3.6700]], grad_fn=<AddBackward0>)
False
None
True

model.eval()与with torch.no_grad()

共同点:
在PyTorch中进行validation时,使用这两者均可切换到测试模式。
如用于通知dropout层和batchnorm层在train和val模式间切换。
在train模式下,dropout网络层会按照设定的参数p设置保留激活单元的概率(保留概率=p); batchnorm层会继续计算数据的mean和var等参数并更新。
在val模式下,dropout层会让所有的激活单元都通过,而batchnorm层会停止计算和更新mean和var,直接使用在训练阶段已经学出的mean和var值。

不同点:
model.eval()会影响各层的gradient计算行为,即gradient计算和存储与training模式一样,只是不进行反传。

with torch.zero_grad()则停止autograd模块的工作,也就是停止gradient计算,以起到加速和节省显存的作用,从而节省了GPU算力和显存,但是并不会影响dropout和batchnorm层的行为。

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

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