十分钟从 PyTorch 转 MXNet

2018 年 4 月 3 日 ApacheMXNet

PyTorch 是一个纯命令式的深度学习框架。它因为提供简单易懂的编程接口而广受欢迎,而且正在快速的流行开来。例如 Caffe2 最近就并入了 PyTorch。

可能大家不是特别知道的是,MXNet 通过 ndarray 和 gluon 模块提供了非常类似 PyTorch 的编程接口。本文将简单对比如何用这两个框架来实现同样的算法。

安装

PyTorch 默认使用 conda 来进行安装,例如

conda install pytorch-cpu -c pytorch

而 MXNet 更常用的是使用 pip。我们这里使用了 --pre 来安装 nightly 版本

pip install --pre mxnet

多维矩阵

对于多维矩阵,PyTorch 沿用了 Torch 的风格称之为 tensor,MXNet 则追随了 NumPy 的称呼 ndarray。下面我们创建一个两维矩阵,其中每个元素初始化成 1。然后每个元素加 1 后打印。

PyTorch:

import torch
x = torch.ones(5,3)
y = x + 1
print(y)
 2  2  2
 2  2  2
 2  2  2
 2  2  2
 2  2  2
[torch.FloatTensor of size 5x3]

MXNet:

from mxnet import nd
x = nd.ones((5,3))
y = x + 1
print(y)
[[2. 2. 2.]
 [2. 2. 2.]
 [2. 2. 2.]
 [2. 2. 2.]
 [2. 2. 2.]]
<NDArray 5x3 @cpu(0)>

忽略包名的不一样的话,这里主要的区别是 MXNet 的形状传入参数跟 NumPy 一样需要用括号括起来。

模型训练

下面我们看一个稍微复杂点的例子。这里我们使用一个多层感知机(MLP)来在 MINST 这个数据集上训练一个模型。我们将其分成 4 小块来方便对比。

读取数据

这里我们下载 MNIST 数据集并载入到内存,这样我们之后可以一个一个读取批量。

PyTorch:

import torch
from torchvision import datasets, transforms

train_data
= torch.utils.data.DataLoader(    datasets.MNIST(train=True, transform=transforms.Compose([         transforms.ToTensor(),         transforms.Normalize((0.13,), (0.31,))])),    batch_size=128, shuffle=True, num_workers=4)

MXNet:

from mxnet import gluon
from mxnet.gluon.data.vision import datasetes, transforms

train_data = gluon.data.DataLoader(    datasets.MNIST(train=True).transform_first(transforms.Compose([        transforms.ToTensor(),        transforms.Normalize(0.13, 0.31)])), batch_size=128, shuffle=True, num_workers=4)

这里的主要区别是 MXNet 使用 transform_first 来表明数据变化是作用在读到的批量的第一个元素,既 MNIST 图片,而不是第二个标号元素。

定义模型

下面我们定义一个只有一个单隐层的 MLP 。

PyTorch:

from torch import nn

net = nn.Sequential(    nn.Linear(28*28, 256),    nn.ReLU(),    nn.Linear(256, 10))

MXNet:

from mxnet.gluon import nn

net = nn.Sequential()
with net.name_scope():    net.add(        nn.Dense(256, activation='relu'),        nn.Dense(10)    )
net.initialize()

我们使用了 Sequential 容器来把层串起来构造神经网络。这里MXNet跟PyTorch的主要区别是:

  • 不需要指定输入大小,这个系统会在后面自动推理得到

  • 全连接和卷积层可以指定激活函数

  • 需要创建一个  name_scope 的域来给每一层附上一个独一无二的名字,这个在之后读写模型时需要

  • 我们需要显示调用模型初始化函数。

大家知道 Sequential 下只能神经网络只能逐一执行每个层。PyTorch可以继承 nn.Module 来自定义 forward 如何执行。同样,MXNet 可以继承 nn.Block 来达到类似的效果。

损失函数和优化算法

PyTorch:

loss_fn = nn.CrossEntropyLoss()
trainer = torch.optim.SGD(net.parameters(), lr=0.1)

MXNet:

loss_fn = gluon.loss.SoftmaxCrossEntropyLoss()
trainer = gluon.Trainer(net.collect_params(),                        'sgd', {'learning_rate': 0.1})

这里我们使用交叉熵函数和最简单随机梯度下降并使用固定学习率 0.1

训练

最后我们实现训练算法,并附上了输出结果。注意到每次我们会使用不同的权重和数据读取顺序,所以每次结果可能不一样。

PyTorch

from time import time

for epoch in range(5):    total_loss = .0    tic = time()    for X, y in train_data:        X, y = torch.autograd.Variable(X), torch.autograd.Variable(y)        trainer.zero_grad()        loss = loss_fn(net(X.view(-1, 28*28)), y)        loss.backward()        trainer.step()        total_loss += loss.mean()    print('epoch %d, avg loss %.4f, time %.2f' % (        epoch, total_loss/len(train_data), time()-tic))
epoch 0, avg loss 0.3251, time 3.71
epoch 1, avg loss 0.1509, time 4.05
epoch 2, avg loss 0.1057, time 4.07
epoch 3, avg loss 0.0820, time 3.70
epoch 4, avg loss 0.0666, time 3.63

MXNet

from time import time

for epoch in range(5):    total_loss = .0    tic = time()    for X, y in train_data:        with mx.autograd.record():        loss = loss_fn(net(X.flatten()), y)        loss.backward()        trainer.step(batch_size=128)        total_loss += loss.mean().asscalar()    print('epoch %d, avg loss %.4f, time %.2f' % (        epoch, total_loss/len(train_data), time()-tic))
epoch 0, avg loss 0.3162, time 1.59
epoch 1, avg loss 0.1503, time 1.49
epoch 2, avg loss 0.1073, time 1.46
epoch 3, avg loss 0.0830, time 1.48
epoch 4, avg loss 0.0674, time 1.75

MXNet 跟 PyTorch 的不同主要在下面这几点:

  • 不需要将输入放进 Variable, 但需要将计算放在 mx.autograd.record() 里使得后面可以对其求导

  • 不需要每次梯度清 0,因为新梯度是写进去,而不是累加

  • step 的时候 MXNet 需要给定批量大小

  • 需要调用 asscalar() 来将多维数组变成标量。

  • 这个样例里 MXNet 比 PyTorch 快两倍。当然大家对待这样的比较要谨慎


下一步

扫描或者长按下面QR码来关注我们:

请点击下面链接来参与公开讨论:

登录查看更多
1

相关内容

Yann Lecun 纽约大学《深度学习(PyTorch)》课程(2020)PPT
专知会员服务
182+阅读 · 2020年3月16日
一网打尽!100+深度学习模型TensorFlow与Pytorch代码实现集合
【模型泛化教程】标签平滑与Keras, TensorFlow,和深度学习
专知会员服务
21+阅读 · 2019年12月31日
《动手学深度学习》(Dive into Deep Learning)PyTorch实现
专知会员服务
120+阅读 · 2019年12月31日
【干货】大数据入门指南:Hadoop、Hive、Spark、 Storm等
专知会员服务
96+阅读 · 2019年12月4日
【书籍】深度学习框架:PyTorch入门与实践(附代码)
专知会员服务
167+阅读 · 2019年10月28日
开源书:PyTorch深度学习起步
专知会员服务
51+阅读 · 2019年10月11日
机器学习入门的经验与建议
专知会员服务
94+阅读 · 2019年10月10日
PyTorch 官方推荐了一份 60 分钟的深度学习指南
技术最前线
20+阅读 · 2019年10月17日
盘一盘 Python 系列 10 - Keras (上)
平均机器
5+阅读 · 2019年8月26日
开发 | PyTorch好助手:PyTorch Hub一键复现各路模型
PyTorch 学习笔记(一):让PyTorch读取你的数据集
极市平台
16+阅读 · 2019年4月24日
PyTorch使用总览
极市平台
5+阅读 · 2019年3月25日
从零开始深度学习第8讲:利用Tensorflow搭建神经网络
PyTorch:60分钟入门学习
全球人工智能
13+阅读 · 2018年5月18日
【强烈推荐】浅谈将Pytorch模型从CPU转换成GPU
机器学习研究会
7+阅读 · 2017年12月24日
3D Deep Learning on Medical Images: A Review
Arxiv
12+阅读 · 2020年4月1日
Arxiv
19+阅读 · 2018年10月25日
Arxiv
19+阅读 · 2018年6月27日
Arxiv
6+阅读 · 2018年3月29日
VIP会员
相关VIP内容
Yann Lecun 纽约大学《深度学习(PyTorch)》课程(2020)PPT
专知会员服务
182+阅读 · 2020年3月16日
一网打尽!100+深度学习模型TensorFlow与Pytorch代码实现集合
【模型泛化教程】标签平滑与Keras, TensorFlow,和深度学习
专知会员服务
21+阅读 · 2019年12月31日
《动手学深度学习》(Dive into Deep Learning)PyTorch实现
专知会员服务
120+阅读 · 2019年12月31日
【干货】大数据入门指南:Hadoop、Hive、Spark、 Storm等
专知会员服务
96+阅读 · 2019年12月4日
【书籍】深度学习框架:PyTorch入门与实践(附代码)
专知会员服务
167+阅读 · 2019年10月28日
开源书:PyTorch深度学习起步
专知会员服务
51+阅读 · 2019年10月11日
机器学习入门的经验与建议
专知会员服务
94+阅读 · 2019年10月10日
相关资讯
PyTorch 官方推荐了一份 60 分钟的深度学习指南
技术最前线
20+阅读 · 2019年10月17日
盘一盘 Python 系列 10 - Keras (上)
平均机器
5+阅读 · 2019年8月26日
开发 | PyTorch好助手:PyTorch Hub一键复现各路模型
PyTorch 学习笔记(一):让PyTorch读取你的数据集
极市平台
16+阅读 · 2019年4月24日
PyTorch使用总览
极市平台
5+阅读 · 2019年3月25日
从零开始深度学习第8讲:利用Tensorflow搭建神经网络
PyTorch:60分钟入门学习
全球人工智能
13+阅读 · 2018年5月18日
【强烈推荐】浅谈将Pytorch模型从CPU转换成GPU
机器学习研究会
7+阅读 · 2017年12月24日
Top
微信扫码咨询专知VIP会员