PyTorch 1.0 基础教程(2):autograd: 自动微分器

PyTorch 1.0 基础教程(2):autograd: 自动微分器

所有在PyTorch神经网络的核心是autograd包. 让我们来简要地观察一下这个,我们将先去训练我们的神经网络.

autograd包为所有在张量上的操作提供自动微分.auto是一个通过运行来定义(define-by-run)的框架,意味着你的反向传播有你运行的代码定义,同时,每个迭代都可以不一样.
接下来我们通过一些例子来看看它时怎么做的吧.

张量

torch.Tensorautograd包的核心类. 如果我们设置.requires_gradTrueautograd将跟踪发生在这个张量的所有操作.当完成我们需要的计算后,调用.backwoad(),它将为我们自动计算好所有的梯度. 这些张量的梯度值将被保存到该张量的.grad属性中.
如果该张量接下来的操作中,我们不再需要跟踪张量的历史,可以调用.detach()将其从计算历史中分离开来,这样以后该张量的计算就不会被跟踪了.
为了防止跟踪张量的历史以及占用内存空间,可以用with torch.no_grad():包裹代码块. 在评估模型时,这样做特别有帮助,因为模型可能具有带requires_grad=True的可训练参数,但是在评估过程,我们并不需要计算梯度.
还有一个类对autograd的实现是非常重要的–函数.
TensorsFunction是相互关联的,他们构建了一个无环图,编织成一个完整的计算历史. 每个张量有一个属性.grad_fn,其引用一个已经创建了TensorsFunction(除了被用户创建的Tensors–他们的grad_fnNone).
如果要进行计算过程的推导,需要调用一个Tensor.backward(). 如果Tensor是一个标量(例如:它包含一个元素数据),就不需要特别指定任何backward()的命令参数,然而如果它有多个元素,则需要指定一个拥有对应匹配张量形状的gradient命令参数.

import torch

创建一个张量并且设置requires_grad=True以跟踪它的计算过程.

x = torch.ones(2, 2, requires_grad=True)
print(x)

Out:

tensor([[1., 1.],
        [1., 1.]], requires_grad=True)

执行一个操作:

y = x + 2
print(y)

Out:

tensor([[3., 3.],
        [3., 3.]], grad_fn=<AddBackward0>)

y是一个操作的执行结果,所以它有一个grad_fn.

print(y.grad_fn)

Out:

<AddBackward0 object at 0x7f1b248453c8>

y上继续执行更多的操作

z = y * y * 3
out = z.mean()

print(z, out)

Out:

tensor([[27., 27.],
        [27., 27.]], grad_fn=<MulBackward0>) tensor(27., grad_fn=<MeanBackward0>)

.requires_grad_(...)可以用in-place方式改变一个存在的张量的requires_grad标志. 这个输入标志默认为False.

a = 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)

Out:

False
True
<SumBackward0 object at 0x7f1b24845f98>

梯度

现在可以开始反向传播了,因为out包含仅一个标量,out.backward()等价于out.backward(torch.tensor(1.)).

out.backward()

输出梯度d(out)/dx

print(x.grad)

Out:

tensor([[4.5000, 4.5000],
        [4.5000, 4.5000]])

上面的结果究竟时怎样得出的呢,接下来让我们手工推导一下公式.
因为
在这里插入图片描述
所以
在这里插入图片描述
所以
在这里插入图片描述

在这里插入图片描述
在数学上来看,设
在这里插入图片描述
那么,y⃗x⃗的所有梯度可以表示为一个雅可比矩阵(Jacobian matrix):
在这里插入图片描述
通常,torch.autograd是一个计算雅可比向量乘积的引擎. 即给定向量
在这里插入图片描述
计算J⋅v如果v恰好是标量函数l=g(y⃗ )的梯度,即
在这里插入图片描述
那么根据链式法则,雅可比向量乘积就是lx⃗的梯度:
在这里插入图片描述
雅可比向量积的这一特性使得将外部梯度输入到具有非标量输出的模型中变得非常方便.
现在,我们看看雅可比向量积的一个示例:

x = torch.randn(3, requires_grad=True)

y = x * 2
while y.data.norm() < 1000:
    y = y * 2

print(y)

Out:

tensor([-278.6740,  935.4016,  439.6572], grad_fn=<MulBackward0>)

在这个例子中,y不再是一个标量. torch.autograd不能直接计算全部雅可比,但我们只想要雅可比向量积,仅需要简单的将向量传到backward中作为命令参数:

v = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float)
y.backward(v)

print(x.grad)

Out:

tensor([4.0960e+02, 4.0960e+03, 4.0960e-01])

当然,我们也可以可以用with torch.no_grad():包裹代码块,停止张量上不断跟踪的历史,停止自动求微分.

print(x.requires_grad)
print((x ** 2).requires_grad)

with torch.no_grad():
    print((x ** 2).requires_grad)

Out:

True
True
False

更多

autogradFunction的更多文档在这里.

参考

pytorch官方网站

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值