pytorch02
pytorch的变量
同样感谢xmfbit,讲的很清楚搬过来。
说完了数据类型Tensor,下一步便是如何实现一个神经网络。首先,对自动求导做一说明。
我们需要关注的是autograd.Variable。这个东西包装了Tensor。一旦你完成了计算,就可以使用.backward()方法自动得到(以该Variable为叶子节点的那个)网络中参数的梯度。Variable有一个名叫data的字段,可以通过它获得被包装起来的那个原始的Tensor数据。同时,使用grad字段,可以获取梯度(也是一个Variable)。
Variable是计算图的节点,同时Function实现了变量之间的变换。它们互相联系,构成了用于计算的无环图。每个Variable有一个creator的字段,表明了它是由哪个Function创建的(除了用户自己显式创建的那些,这时候creator是None)。
当进行反向传播计算梯度时,如果Variable是标量(比如最终的loss是欧氏距离或者交叉熵),那么backward()函数不需要参数。然而如果Variable有不止一个元素的时候,需要为其中的每个元素指明其(由上层传导来的)梯度(也就是一个和Variableshape匹配的Tensor)。看下面的说明代码。
from torch.autograd import Variable
x = Variable(torch.ones(2, 2), requires_grad = True)
x # x 包装了一个2x2的Tensor
"""
Variable containing:
1 1
1 1
[torch.FloatTensor of size 2x2]
"""
# Variable进行计算
# y was created as a result of an operation,
# so it has a creator
y = x + 2
y.creator # out: <torch.autograd._functions.basic_ops.AddConstant at 0x7fa1cc158c08>
z = y * y * 3
out = z.mean() # out: Variable containing: 27 [torch.FloatTensor of size 1]
# let's backprop now
out.backward() # 其实相当于 out.backward(torch.Tensor([1.0]))
# print gradients d(out)/dx
x.grad
"""
Variable containing:
4.5000 4.5000
4.5000 4.5000
[torch.FloatTensor of size 2x2]
"""
下面的代码就是结果不是标量,而是普通的Tensor的例子。
# 也可以通过Tensor显式地创建Variable
x = torch.randn(3)
x = Variable(x, requires_grad = True)
# 一个更复杂的 op例子
y = x * 2
while y.data.norm() < 1000:
y = y * 2
# 计算 dy/dx
gradients = torch.FloatTensor([0.1, 1.0, 0.0001])
y.backward(gradients)
x.grad
"""
Variable containing:
204.8000
2048.0000
0.2048
[torch.FloatTensor of size 3]
"""
获取Variable 里面的数据:
上面已经说过,Variable包装了data的字段,
print(variable.data)# 获取包装的数据信息。