梯度
反向传播 因为 out是一个纯量(scalar),out.backward() 等于out.backward(torch.tensor(1))。
In [8]:
out.backward()print gradients d(out)/dx
In [9]:
print(x.grad)tensor([[4.5000, 4.5000], [4.5000, 4.5000]])
得到矩阵 4.5.将 out叫做 Tensor “o”
得到O=1/4 ∑_iz_i , z_i=3(x_i+2)² 和
.因此,
, 则
.
在数学上,如果我们有向量值函数 y ⃗=f(x ⃗) ,且 y ⃗ 关于 x ⃗ 的梯度是一个雅可比矩阵(Jacobian matrix):
一般来说,torch.autograd就是用来计算vector-Jacobian product的工具。也就是说,给定任一向量
,计算 v^T∙J ,如果 v 恰好是标量函数 l=g(y ⃗)) 的梯度,也就是说
,那么根据链式法则,vector-Jacobian product 是 x ⃗ 对 l 的梯度:
(注意,v^T∙J 给出了一个行向量,可以通过 J^T∙v 将其视为列向量)
vector-Jacobian product 这种特性使得将外部梯度返回到具有非标量输出的模型变得非常方便。
现在让我们来看一个vector-Jacobian product的例子
In [10]:
x = torch.randn(3, requires_grad=True)
y = x * 2
while y.data.norm() < 1000:
y = y * 2
print(y)tensor([ 293.4463, 50.6356, 1031.2501], grad_fn=<MulBackward0>)
在这个情形中,y不再是个标量。torch.autograd无法直接计算出完整的雅可比行列,但是如果我们只想要vector-Jacobian product,只需将向量作为参数传入backward:
In [11]:
gradients = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float)
y.backward(gradients)
print(x.grad)tensor([5.1200e+01, 5.1200e+02, 5.1200e-02])
如果.requires_grad=True但是你又不希望进行autograd的计算, 那么可以将变量包裹在 with torch.no_grad()中:
In [12]:
print(x.requires_grad)
print((x ** 2).requires_grad)
with torch.no_grad():
print((x ** 2).requires_grad)True True False
稍后阅读:
autograd 和 Function 的官方文档 https://pytorch.org/docs/autograd
学员评价