本文主要是介绍Pytorch学习笔记_2_Autograd自动求导机制,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Autograd 自动求导机制
PyTorch 中所有神经网络的核心是 autograd
包。
autograd
包为张量上的所有操作提供了自动求导。它是一个在运行时定义的框架,可以通过代码的运行来决定反向传播的过程,并且每次迭代可以是不同的。
通过一些示例来了解
Tensor 张量
torch.tensor
是这个包的核心类。
- 设置
.requires_grad
为True
,会追踪所有对于该张量的操作。计算完成后调用.backward()
,可以自动计算所有的梯度,并自动累计到.grad
属性中
事实上即使
.requires_grad
为True
并不意味着.grad
一定不为None
-
可以调用
.detach()
将该张量与计算历史记录分离,并禁止跟踪它将来的计算记录 -
为防止跟踪历史记录(和使用内存),可以将代码块包装在
with torch.no_grad():
中。这在评估模型时特别有用,因为模型可能具有requires_grad = True
的可训练参数,但是我们不需要梯度计算。
Function类
Tensor
和 Function
互相连接并生成一个非循环图,它表示和存储了完整的计算历史。
每个张量都有一个.grad_fn
属性,这个属性引用了一个创建了Tensor
的Function
(除非这个张量是用户手动创建的,即,这个张量的 grad_fn
是 None
)
leaf Tensors 叶张量
Tensor
中有一属性is_leaf
,当它为True
有两种情况:
- 按照惯例,
requires_grad = False
的 Tensorrequires_grad = True
且由用户创建的 Tensor。这意味着它们不是操作的结果且grad_fn = None
只有leaf Tensors叶张量在反向传播时才会将本身的grad
传入backward()
的运算中。要想得到non-leaf Tensors非叶张量在反向传播时的grad
,可以使用retain_grad()
如果需要计算导数,可以在Tensor
上调用.backward()
:若Tensor
是一个标量(即包含一个元素数据)则不需要为backward()
指定任何参数, 但是如果它有更多的元素,需要指定一个gradient
参数来匹配张量的形状。
x = torch.ones(2, 2, requires_grad=True)
print(x)
# Output:
# tensor([[1., 1.],
# [1., 1.]], requires_grad=True)
y = x + 2
print(y)
# Output:
# tensor([[3., 3.],
# [3., 3.]], grad_fn=<AddBackward0>)
此时,y
已经被计算出来,grad_fn
已经自动生成了
>>> print(y.grad_fn)
<AddBackward0 object at 0x0000013D6C2AB848>
对y进行操作
z = y * y * 3
out = z.mean()
print(z, out)
# Output:
# tensor([[27., 27.],
# [27., 27.]], grad_fn=<MulBackward0>) # tensor(27., grad_fn=<MeanBackward0>)
.requires_grad_( ... )
可以改变现有张量的 requires_grad
属性。 如果没有指定的话,默认输入的flag是 False
Gradients 梯度
现在开始反向传播
因为out
是一个标量,因此不需要为backward()
指定任何参数:
out.backward()
print(x.grad)
# Output:
# tensor([[4.5000, 4.5000],
# [4.5000, 4.5000]])
现在让我们来看一个vector-Jacobian product的例子
x = torch.randn(3, requires_grad=True)
y = x * 2
while y.data.norm() < 1000:y = y * 2
print(y)
# Output:
# tensor([ 293.4463, 50.6356, 1031.2501], grad_fn=<MulBackward0>)
此处
y.data.norm()
指y的范数,即(y_1^2 + … + y_n2)(1/2)
在这个情形中,y不再是个标量。torch.autograd
无法直接计算出完整的雅可比行列,但是如果我们只想要vector-Jacobian product,只需将向量作为参数传入backward
:
v = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float)
y.backward(v)
print(x.grad)
# Output:
# tensor([5.1200e+01, 5.1200e+02, 5.1200e-02])
如果.requires_grad=True
但是你又不希望进行autograd的计算, 那么可以将变量包裹在 with torch.no_grad()
中:
print(x.requires_grad) # True
print((x ** 2).requires_grad) # Truewith torch.no_grad():print((x ** 2).requires_grad) # False
这篇关于Pytorch学习笔记_2_Autograd自动求导机制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!