了解 Variable
之前,就要分版本来讲解,一个是 0.4
之前,一个是 0.4
之后。
参考资料
在这里不谈论 0.4
之前的版本了,太老了。
0.4 之后
Facebook
推出了 PyTorch 0.4.0
版本,该版本有诸多更新和改变,比如支持 Windows
,Variable
和 Tensor
合并等等。
torch.Tensor
和 torch.autograd.Variable
现在是同一个类。torch.Tensor
能够像之前的Variable
一样追踪历史和反向传播。Variable
仍能够正常工作,但是返回的是Tensor
。所以在0.4
的代码中,不需要使用Variable
了。
Tensor 中 type () 的变化
这里需要注意到张量的 type()
不再反映数据类型,而是改用 isinstance()
或 x.type()
来表示数据类型,代码如下:
1 | 1, 1, 1]) x = torch.DoubleTensor([ |
autograd 用于跟踪历史记录
作为 autograd
方法的核心标志,requires_grad
现在是 Tensors
类的一个属性。让我们看看这个变化是如何体现在代码中的。autograd
使用先前用于 Variable
的相同规则。当操作中任意输入 Tensor
的 require_grad = True
时,它开始跟踪历史记录。代码如下所示:
1 | 1) # create a tensor with requires_grad=False (default) x = torch.ones( |
requires_grad 操作
除了直接设置属性之外,你还可以使用 my_tensor.requires_grad_(requires_grad = True)
在原地更改此标志,或者如上例所示,在创建时将其作为参数传递(默认为False
)来实现,代码如下:
1 | existing_tensor.requires_grad_() |
关于 .data
.data
是从 Variable
中获取底层 Tensor
的主要方式。 合并后,调用 y = x.data
仍然具有相似的语义。因此 y
将是一个与 x
共享相同数据的 Tensor
,并且 requires_grad = False
,它与 x
的计算历史无关。
然而,在某些情况下 .data
可能不安全。 对 x.data
的任何更改都不会被 autograd
跟踪,如果在反向过程中需要 x
,那么计算出的梯度将不正确。另一种更安全的方法是使用 x.detach()
,它将返回一个与 requires_grad = False
时共享数据的 Tensor
,但如果在反向过程中需要 x
,那么 autograd
将会就地更改它。
标量
0.4
之后的PyTorch
中引入了适当的标量(0维张量)支持! 可以使用新版本中的 torch.tensor
函数来创建标量(这将在后面更详细地解释,现在只需将它认为是PyTorch
中 numpy.array
的等效项),代码如下:
1 | 3.1416) # create a scalar directly torch.tensor( |
累计损失函数
考虑在 PyTorch0.4.0
版本之前广泛使用的 total_loss + = loss.data [0]
模式。Loss
是一个包含张量(1,)
的 Variable
,但是在新发布的 0.4.0
版本中,loss
是一个 0
维标量。 对于标量的索引是没有意义的(目前的版本会给出一个警告,但在0.5.0
中将会报错一个硬错误):使用 loss.item()
从标量中获取 Python
数字。
值得注意得是,如果你在累积损失时未能将其转换为 Python 数字,那么程序中的内存使用量可能会增加。这是因为上面表达式的右侧,在先前版本中是一个 Python 浮点型数字,而现在它是一个零维的张量。因此,总损失将会张量及其历史梯度的累加,这可能会需要更多的时间来自动求解梯度值。