使用autograd来自动求导
在机器学习中,我们通常使用梯度下降来更新模型参数从而求解。损失函数关于模型参数的梯度指向一个可以降低损失函数值的方向,我们不断地沿着梯度的方向更新模型从而最小化损失函数。虽然梯度计算比较直观,但对于复杂的模型,例如多达数十层的神经网络,手动计算梯度非常困难。
PyTorch使用autograd
程序包提供自动求导。
Variable
autograd.Variable()
是这个程序包的核心类。封装了一个Tensor和它上的所有运算。一旦完成计算可以调用.backward()
自动计算所有梯度。
属性.data
访问tensor
属性.grad
变量的梯度
我们先导入
autograd
。
import torch
form torch.autograd import Variable
创建一个变量:
x = Variable(torch.arange(1, 5).resize_(2, 2), requires_grad=True)
print(x)
Variable containing:
1 2
3 4
[torch.FloatTensor of size 2x2]
变量上运算:
y = x * 2
z = y * x
print(z)
Variable containing:
2 8
18 32
[torch.FloatTensor of size 2x2]
接下来我们可以通过z.backward()
来进行求导,这里z不是一个标量,所以使用torch.sum(z).backward()
torch.sum(z).backward()
print(x.grad)
Variable containing:
4 8
12 16
[torch.FloatTensor of size 2x2]
对控制流求导
命令式的编程的一个便利之处是几乎可以对任意的可导程序进行求导,即使里面包含了Python的控制流。考虑下面程序,里面包含控制流for和if,但循环迭代的次数和判断语句的执行都是取决于输入的值。不同的输入会导致这个程序的执行不一样。(对于计算图框架来说,这个对应于动态图,就是图的结构会根据输入数据不同而改变)。
def f(a):
b = a * 2
while torch.norm(b.data) < 1000:
b = b * 2
if torch.sum(b.data) > 0:
c = b
else:
c = 100 * b
return c
x = Variable(torch.randn(3), requires_grad=True)
c = f(x)
torch.sum(c).backward()
print(x.grad == c/x)
Variable containing:
1
1
1
[torch.ByteTensor of size 3]