更多干货内容请关注微信公众号“AI 前线”,(ID:ai-front)
作为 Facebook 人工智能团队(FAIR)提供支持的深度学习框架,PyTorch 自 2017 年 1 月推出以来立即成为了一种流行开发工具。其在调试、编译等方面的优势使其受到了学界研究者们的普遍欢迎。这个月月初,Caffe2 代码并入 PyTorch 的消息也在业界引起热烈的讨论。
今天,PyTorch 官方在 GitHub 上重磅发布了 0.4.0 版本,这一次更新从 0.3.1 到 0.4.0 有非常多的改进,最重要的就是, PyTorch 现在正式支持 Windows! 在没有官方支持前,广大炼丹师们在 Windows 上安装 PyTorch 需要借助其它开发者发布的第三方 Conda 包,现在官方为 Python 3.5 和 3.6 提供预编译的 Conda 二进制文件和 pip wheels。不过 Windows 上的 PyTorch 不支持分布式训练,可能比 Linux/OSX 慢一点,因为 Visual Studio 支持较早版本的 OpenMP。
与往常一样,你可以使用 http://pytorch.org 上的命令在 Windows 上安装 PyTorch。
这里有一个常见问题解答,可以解答你在 Windows 上可能遇到的大多数问题:
http://pytorch.org/docs/stable/notes/windows.html
除了 Windows 支持外,0.4.0 版的 PyTorch 还重点权衡了计算中的内存、支持多种概率分布、优化数据类型和修正张量等。
以下为本次版本更新目录:
-
Tensor/Variable 合并
-
零维张量
-
数据类型
-
迁移指南
-
Tensors:
-
全面支持高级索引
-
快速傅立叶变换
-
神经网络:
-
计算时的存储权衡
-
bottleneck,识别代码中热点(hotspots)的工具
-
torch.distributions
-
24 个基础的概率分布
-
增加 cdf、方差、信息熵、困惑度等
-
分布式训练
-
易于使用的 Launcher utility
-
NCCL2 后端
-
C++ 拓展
-
Windows 支持
-
ONNX 改进
-
RNN 支持
为了帮助老版本用户更轻松地将代码转换为新的 API 和 Style,也为了吸引更多的新用户,PyTorch 团队还编写了一份迁移指南。AI 前线对该迁移指南完整编译如下,如果你想要快速升级以前版本的 PyTorch 代码,请接着往下看!
PyTorch 0.4.0 带来了很多令人兴奋的新特性和一些重要的 Bug 修复,旨在为用户提供更好、更干净的接口。在这篇升级指南中,我们将介绍在从旧版本 PyTorch 升级到最新版本时需要做出哪些重要的改动:
-
Tensor 和 Variable 已合并
-
支持零维度(标量)Tensor
-
弃用 volatile 标志
-
dtype、device 和 Numpy 风格的 Tensor 创建函数
-
编写具有设备无关性的代码
torch.Tensor 和 torch.autograd.Variable 现在合并到同一个类中。更确切地说,torch.Tensor 可用于跟踪历史,并具有与旧 Variable 一样的行为。Variable 基本不变,只是返回类型变成了 torch.Tensor。这意味着我们不再需要在代码中使用 Variable 包装器。
需要注意的是,Tensor 的 type() 无法反映出数据类型,可使用 isinstance() 或 x.type() 代替:
requires_grad 是 autograd 的主要标志,现在变成 Tensor 的一个属性。之前用于 Variables 的规则同样适用于 Tensor。只要某个操作的输入 Tensor 包含了 require_grad=True 时,autograd 就会开始跟踪历史记录。例如:
除了可以直接设置这个属性之外,还可以通过 my_tensor.requires_grad_() 来就地更改这个标志,或者如上例所示,在创建 Tensor 时将它作为参数传递进去(默认为 False),例如:
.data 是从 Variable 中获取底层 Tensor 的主要方式。在合并后,仍然可以继续使用 y=x.data 这种方式,它的语义保持不变。所以,y 是一个与 x 共享相同数据的 Tensor,与 x 的计算历史无关,并且它的 requires_grad 值为 False。
但是,在某些情况下,.data 可能不安全。对 x.data 的任何更改都不会被 autograd 跟踪到,如果在逆推中需要用到 x,那么计算出的梯度可能不正确。更安全的方法是使用 x.detach(),它会返回一个共享数据的 Tensor(requires_grad=False),但如果在逆推中需要用到 x,autograd 将会跟踪到它的变化。
之前,索引一个 Tensor 向量(1 维 Tensor)会得到一个 Python 数字,而索引一个 Variable 向量会得到(有时候也不一定)一个大小为(1,)的向量!reduction 函数也存在类似的情况,例如 tensor.sum() 将返回一个 Python 数字,但是 variable.sum() 会返回一个大小为(1,)的向量。
幸运的是,新版本适当引入了对标量(0 维 Tensor)的支持!可以使用新的 torch.tensor 函数来创建标量(这将在后面更详细地解释)。现在我们可以做这样的事情:
以广泛使用的模式 total_loss+=loss.data [0] 为例,在 0.4.0 之前,损失是一个 Variable,包装了大小为(1,)的 Tensor,而在 0.4.0 中,损失是一个零维度的标量。索引标量是没有意义的(现在会给出一个警告,但在 0.5.0 中将变成一个错误)。我们可以使用 loss.item() 从标量中获取 Python 数字。
请注意,如果在累积损失时未将其转换为 Python 数字,可能会消耗大量内存。这是因为上面表达式的右侧之前是一个 Python 浮点数,而现在变成了一个零维度的 Tensor。因此,总损失是 Tensor 和它们的梯度历史累积起来的,这可能会使 autograd 图保留更长的时间。
volatile 标志现在已经被弃用。之前,autograd 不会跟踪任何包含 volatile=True 的 Variable 计算。现在可以通过一组更灵活的上下文管理器来实现相同的功能,包括 torch.no_grad()、torch.set_grad_enabled(grad_mode)等。
在以前的版本中,我们需要指定数据类型(float 还是 double?)、设备类型(cpu 还是 cuda?)和布局(dense 还是 sparse?)作为“Tensor 类型”。例如,torch.cuda.sparse.DoubleTensor 表示驻存在 CUDA 设备上具有 COO sparse 布局的 double 数据类型。
在新版本中,我们引入了 torch.dtype、torch.device 和 torch.layout 类,可通过 NumPy 风格的创建函数更好地管理这些属性。
torch.dtype
以下是可用的 torch.dtype(数据类型)及其相应 Tensor 类型的完整列表。
现在可以通过访问 Tensor 的 dtype 属性获取到它的 dtype 数据类型。
torch.device
torch.device 包含设备类型(cpu 或 cuda)和可选的设备序号(id)。它可以通过 torch.device('{device_type}')或 torch.device('{device_type}:{device_ordinal}')进行初始化。