PyTorch 中所有神经网络的核心是autograd
包.我们首先简单介绍一下这个包,然后训练我们的第一个神经网络.
autograd包为张量上的所有操作提供了自动求导.它是一种在运行时才被定义的,意味着反向传播只有再代码运行的时候才会计算,每次循环的时候都可以不同,就是说可以有不同的计算图。
接下来我们用一些简单的示例来看这个包
torch.Tensor
是torch库的核心类。如果你设置它的属性.requires_grad
为True
,它就会计算其上的梯度。当你结束了你的前向计算,你可以调用.backward()
,让它开始自动梯度运算。张量的梯度将会被累积到它的.grad
属性中去。
为了让张量从它的运行过程中停止,你可以调用.detach
来让它从它的计算过程中分离出来,并且阻止它进行继续运算。
为了阻止运算过程(或者使用内存),你可以将代码块放置在 with torch.no_grad():
中。这个操作在评估一个模型的时候特别有帮助,因为,你已经拥有了训练过的属性requires_grad
为True
的参数,但是,我们不再需要他的梯度值。
有另一个对自动求导实现非常关键的类:Function
。
Tensor
和Function
互相连接起来,构建了一个无环图,对所有的运算过程进行了编码。每个张量都有一个叫 .grad_fn
的属性,它指向创建该变量的一个Function
(用户自己创建的张量除外,它的grad_fn属性为None.)。
如果你想计算导数,那么你就可以对一个Tensor
调用它的.backward()
方法。如果Tensor是一个标量(只有一个元素的数据),你不需要指明backward()
的任何参数,如果它有多个元素的话,就需要指定一个gradient
的参数,该参数与调用该Tensor
的形状相同。
import torch
创建一个tensor并且设置 requires_grad=True 来跟踪计算。
x = torch.Tensor(2,2,requires_grad = True)
print(x)
输出
tensor([[1., 1.],
[1., 1.]], requires_grad=True)
给他来个运算
y = x + 2
print(y)
y 是有运算产生的张量,所以它有grad_fn
print(y.grad_fn)
输出
给 y再来一些运算:
z = y * y * 3
out = z.mean()
print(z, out)
输出
tensor([[27., 27.],
[27., 27.]], grad_fn=) tensor(27., grad_fn=)
.requires_grad_( ... )
改变现有张量的 requires_grad 标志。如果没有提供.requires_grad参数的话,输入的标志默认是False。
这在fine tune神经网络时候很有用,特别是迁移的时候
参看例子:
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)
输出
False
True
<SumBackward0 object at 0x7f833e0d9940>
现在我们来执行反向传播,out.backward()
相当于执行out.backward(torch.Tensor([1.0]))
out.backward()
输出out对x的梯度d(out)/dx:
print(x.grad)
输出
tensor([[4.5000, 4.5000],
[4.5000, 4.5000]])
你应该得到一个值全为4.5的矩阵,我们把变量out
称为o
,则
因此,
我们还可以用自动求导做更多有趣的事!
x = torch.randn(3, requires_grad=True)
y = x * 2
while y.data.norm() < 1000:
y = y * 2
print(y)
输出
tensor([-1178.9551, 1202.9015, 293.6342], grad_fn=)
gradients = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float)
y.backward(gradients)
print(x.grad)
输出
tensor([1.0240e+02, 1.0240e+03, 1.0240e-01])
你可以使用with torch.no_grad()
停止自动的梯度计算,即使tensor的属性.requires_grad=True
print(x.requires_grad)
print((x ** 2).requires_grad)
with torch.no_grad():
print((x ** 2).requires_grad)
输出
True
True
False
稍后阅读
autograd
和 Function
的文档在: http://pytorch.org/docs/autograd