PyTorch 0.4.0 迁移指南

PyTorch入门实战教程

PyTorch 0.4.0 的发布给我们带来了很多新的特性。但与此同时,很多重要的语法和格式都发生了变化。这篇文章带给大家怎行从旧的代码迁移到 PyTorch 0.4.0 的一些具体方法。主要集中在以下方面:

  • Tensor 和 Variable 合并了
  • Tensor 支持 0 维度(即标量)
  • 放弃使用 volatile
  • dtypesdevices 和 Numpy-style 的 Tensor 初始函数
  • 设备无关性
  • 一些新的参数命名规则

Tensor 和 Variable 合并了

torch.Tensor and torch.autograd.Variable 现在是一样的了。torch.Tensor 可以像以前的 Variable 一样记录历史数据,Variable 还可以继续使用,但会返回一个 torch.Tensor 类型的变量。这意味着,我们再也不需要在代码里到处用 Variable 了。

Tensor 类型查看

type() 方法不会再返回 Tensor 的数据类型了。需要使用 isinstance() or x.type()

关于 Tensor 的 requires_grad

requires_grad  现在是 Tensor 的一个属性,用法和以前 Variable 一样。

除了直接给定 requires_grad,还可以原地设定:my_tensor.requires_grad_()

关于 .data

.data是从Variable中获取Tensor 的主要方法。合并后,调用y = x.data 后 y 和 x 共享相同的数据,但 y 与 x 的计算历史无关,而且 requires_grad=False

但是,.data在某些情况下不安全。x.data 上的任何变化都不被 autograd 跟踪,并且在向后传播的过程中 x 的值将出现差错。一种更安全的替代方法是使用 x.detach(),它也返回一个 requires_grad=False 的 Tensor,但它会有梯度变化的信息。

下面是一个.datax.detach()(以及为什么我们建议使用 detach)区别的例子。

如果你使用 Tensor.detach(),梯度计算一定是正确的。

但是用 Tensor.data 是不安全的,当引用的 tensor 被修改后,原 tensor 也会被修改,会导致梯度计算出错:

Tensor 支持 0 维度(即 标量)

之前版本中,一维 Tensor 的索引会返回一个数值,一维 Variable 会返回(1,)。类似的情况出现在求和函数中,例如 tensor.sum() 返回一个数值,然而 Variable.sum() 返回的是(1,)

此版本在PyTorch中引入了适当的标量(0维张量)支持,不像原来单个数据还给搞出个一维数组!可以使用新torch.tensor函数来创建标量。

关于 Loss 的累加

之前都使用 total_loss += loss.data[0] 累积损失率。在0.4版本中有0维的标量,直接用loss.item()得到其 loss 的数值就可以了。

请注意,如果您在累加损失时未将其转换为 Python 数字,则可能出现程序内存使用量增加的情况。这是因为上面表达式的右侧原本是一个Python浮点数,而它现在是一个零维张量。因此,总损失累加了张量和它们的梯度历史,这可能会使大的autograd 图保存比我们所需要长的时间。

放弃使用 volatile

volatile 标志现在已被弃用。之前,autograd 不会跟踪任何涉及 Variable(volatile=True)的计算。它已经被换成了一套更加灵活的上下文管理器,如:torch.no_grad()torch.set_grad_enabled(grad_mode)等等。

dtypesdevices 和 Numpy-style 的 Tensor 初始函数

在以前的 PyTorch 版本中,我们用数据类型(例如float vs double),设备类型(cpu vs cuda)和 layout(dense vs sparse)共同作为”张量类型”。例如,torch.cuda.sparse.DoubleTensorTensordouble数据类型,支持CUDA,以及支持 COO Sparse Tensor Layout。

在此版本中,我们引入torch.dtypetorch.device以及torch.layout类,通过NumPy的风格更好的管理这些类型。

torch.dtype

下图是 dtype 的完整列表以及对应的 tensor 类型:

一个 tensor 的 dtype 可以同过 tensor.dtype 获得。

torch.device

torch.device 包含设备类型(cpucuda)和可选设备序号(id)。它可以用torch.device('{device_type}')torch.device('{device_type}:{device_ordinal}')初始化。

如果没有设备序号,则表示设备为当前设备; 例如,torch.device('cuda')等同于torch.device('cuda:X'),这里的Xtorch.cuda.current_device()

张量设备可以通过tensor.device 获得。

torch.layout

torch.layout 代表一个 Tensor 的数据布局。

张量的布局可以通过tensor.layout 获得。

创建Tensor

现在创建Tensor的方法还包括dtype,device,layout和requires_grad选项来指定返回Tensor所需的属性。例如:

torch.tensor 是新增张量创建方法之一。torch.tensor()就像numpy.array()构造器,可以将数组类数据直接转换为Tensor,本版本中这个函数也可以构造标量。如果初始化没有指定dtype数据类型,PyTorch 将自动分配合适类型,我们极力推荐使用这种方法将已有的数据类(例如list)转化为Tensor。

下面介绍其他创建Tensor的方法:

  • torch.*_like接受Tensor数据(注意不是数据的尺寸),如果不设置相关参数,它默认返回一个具有相同属性的Tensor
  • tensor.new_*使用尺寸作为参数创建具有相同属性的Tensor
如果需要创建指定尺寸的Tensor,可以直接用元组指定尺寸作为参数,例如torch.zeros((2,3))torch.zeros(2,3),这样就能创建尺寸为 2×3,元素为 0 的Tensor。

设备无关性

在之前的版本中,当不确定计算设备 (CPU 或 GPU) 的情况时不太好写代码。 0.4版本做出了如下更新

  • 使用to方法可以轻松转换训练的网络(module)和数据到不同计算设备运行
  • device属性用来指定使用的计算设备,之前要用cpu(),cuda()转换模型或数据

一些新的参数命名规则

name 如果是一个空字符串或包含”.”,将不再可以作为 module.add_module(name, value)module.add_parameter(name, value)或者module.add_buffer(name, value)的参数。因为这样可能会在state_dict中导致数据丢失。

PyTorch 0.3.1 和 0.4.0 代码对比实例

0.3.1

0.4.0

文章来源:PyTorchTutorial.com PyTorch 中文网 翻译。

PyTorch入门实战教程
除特别注明外,本站所有文章均为 PyTorch 中文网原创,转载请注明出处:https://www.pytorchtutorial.com/pytorch-0-4-0-migration-guide/

Leave a Reply

Your email address will not be published. Required fields are marked *

1条评论

  1. 对于atuograd那里有一点疑问,如果想要计算梯度,需要把tensor的requires_grad设为True,否则,.backward()是会报错的,可是在实际案例时,比如神经网络里,我看并没有对输入参数对这个属性进行设置,可是在迭代时,照样可以反向传播,这是为什么?

返回顶部