原文地址:
https://pytorch.org/tutorials/beginner/blitz/autograd_tutorial.html
Autograd: automatic differentiation 【Autograd:自动微分】
在PyTorch的所有神经网络的核心是autograd包。让我们首先简要地访问它,然后我们去训练我们地第一个神经网络。
autograd包未Tensor上地所有操作提供了自动微分。它是一个自由定义地框架,这意味着你的 BP算法是由你代码地运行方式定义地,并且每次迭代都是不同的。
让我们用更简单的术语来看看这些例子。
Tensor
torch.Tensor 是这个包的核心类。如果你设置它的属性 .requires_grad为True,则它会开始跟踪上面的所有操作。当你完成你的计算你可以调用 .backward()并且自动计算出所有梯度。tensor的梯度将会累积到 .grad属性中。
要停止tensor的跟踪历史,你可以调用 .detach()将其域计算历史记录分离,并且防止未来的计算被跟踪。
未来防止跟踪历史记录(和使用内存),你可以使用torch.no_grad():将代码块包装起来,在评估模型时这可能会非常有用,因为模型可能具有 reguires_grad=True的训练参数,但是我们不需要梯度。
还有一个类对于autograd实现非常重要- a Function.
Tensor和Function是互相连通的,并且构建了一个非循环图,它编码了一个完整的计算历史。每个tensor都有一个 .grad_fn属性,该属性引用function已创建的Tensor(除了用户所创建的Tensor-他们的grad_fn属性是None)。
如果你想计算导数,你可以在Tensor中调用 .backward()。如果Tensor是一个标量(也就是说它包含一个元素数据),则不需要指定任何参数 backward(),但是如果它有更多的元素,你需要指定一个和tensor匹配形状的梯度参数。
1 | import torch |
创建一个tensor并且设置requires_grad=true跟踪它的计算
1 | x = torch.ones(2, 2, requires_grad=True) |
输出1
2tensor([[1., 1.],
[1., 1.]], requires_grad=True)
做一个tensor操作:1
2y = x + 2
print(y)
输出1
2tensor([[3., 3.],
[3., 3.]], grad_fn=<AddBackward>)
y是作为一个操作的结果创建的,所以它有一个grad_fn。
1 | print(y.grad_fn) |
输出1
<AddBackward object at 0x00000251A7EC7F60>
在y上做更多的操作
1 | z = y * y * 3 |
输出1
2tensor([[27., 27.],
[27., 27.]], grad_fn=<MulBackward>) tensor(27., grad_fn=<MeanBackward1>)
.requires_grad_(…)
改变一个现有Tensor的requiresgrad标志。
如果没有给出输入标志,则默认为False。1
2
3
4
5
6
7a = torch.randn(2, 2)
a = ((a * 3) / (a - 1))
print(a.requires_grad)
a.requires_grad_(True)
print(a.requires_grad)
b = (a * a).sum()
print(b.grad_fn)
输出1
2
3False
True
<SumBackward0 object at 0x00000251A7ED09B0>
Gradients 【梯度】
现在让我们后退一步,因为out包含一个标量,out.backward()等价于out.backward(torch.tensor(1))。
1 | out.backward() |
输出梯度d(out)/ dx
1 | print(x.grad) |
输出1
2tensor([[4.5000, 4.5000],
[4.5000, 4.5000]])
你应该有一个矩阵4.5. 我们称 out
Tensor “o”.
我们有 $o = \frac{1}{4}\sum_i z_i$,
$z_i = 3(x_i+2)^2$ and $z_i\bigr\rvert_{x_i=1} = 27$.
因此,
$\frac{\partial o}{\partial x_i} = \frac{3}{2}(x_i+2)$, 因此
$\frac{\partial o}{\partial x_i}\bigr\rvert_{x_i=1} = \frac{9}{2} = 4.5$.
你可以用autograd做很多疯狂的事情!
1 | x = torch.randn(3, requires_grad=True) |
输出
1 | tensor([-816.7130, 1152.6641, 765.0383], grad_fn=<MulBackward>) |
1 | gradients = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float) |
输出
1 | tensor([ 102.4000, 1024.0000, 0.1024]) |
我们可以阻止autograd跟踪历史在Tensor上使用 .requires_grad=True 使用torch.no_grad()将代码块封装起来。
1 | print(x.requires_grad) |
输出1
2
3True
True
False
Read Later:
Documentation of autograd and Function is at http://pytorch.org/docs/autograd