- 深度学习
- 机器学习
- 人工智能
【免费下载链接】mxnet
Lightweight, Portable, Flexible Distributed/Mobile Deep Learning with Dynamic, Mutation-aware Dataflow Dep Scheduler; for Python, R, Julia, Scala, Go, Javascript and more
本文以 Apache MXNet 的 Gluon 命令式接口为主线,与 PyTorch 进行全流程逐项对比:从安装方式、张量操作、MNIST 多层感知机(MLP)训练,到自动微分、自定义网络块、多卡与分布式训练、监控与模型序列化。读完本文,你将掌握两个框架核心 API 的一一对应关系,能够把 PyTorch 代码快速改写为 MXNet Gluon 代码,并理解 Gluon 在梯度语义、惰性求值与混合编程(Hybridize)上的设计差异。
说明:本文中涉及性能对比的数值均引用原文档所引用的公开基准(2019 年 4 月 NVIDIA 深度学习训练/推理性能基准),属于特定软硬件与版本下的历史数据,请结合当前环境自行实测验证。
一、为什么从 PyTorch 迁移到 MXNet
PyTorch 因其易于理解的 API 与完全命令式的编程风格广受欢迎。Apache MXNet 的 Gluon API 在提供与 PyTorch 相当的简洁性与灵活性的同时,还允许通过hybridize()将命令式网络转换为符号图执行,从而利用符号图的性能优化能力。
两者的核心差异不在于"能用",而在于设计哲学:
- 术语差异:PyTorch 沿用 Torch 的命名习惯,把多维矩阵称为 Tensor;MXNet 沿用 NumPy 的约定,称为 NDArray。
- 梯度累积语义:PyTorch 默认累积梯度,每批训练前需手动
zero_grad();MXNet Gluon 默认直接覆盖写入新梯度(grad_req='write'),无需每批清空。 - 执行模型:MXNet 采用惰性求值(lazy evaluation),Python 线程把算子推入后端引擎后立即返回,因此批结束处需要显式同步(如
asnumpy()、wait_to_read()、metric.update(...))。
其余代码结构高度相似,从一个框架迁移到另一个框架非常直接。
二、安装方式对比
PyTorch 默认使用 conda 安装,例如:
# !conda install pytorch-cpu -c pytorchMXNet 使用 pip 安装 CPU 版本:
# !pip install mxnetGPU 版本需要指定 CUDA 版本号。例如安装支持 CUDA 9.2 的版本:
# !pip install mxnet-cuda92从仓库的 docker/Dockerfiles 目录可以看到,官方镜像同样按 CUDA 8.0 / 9.0 / 9.2 划分(如Dockerfile.mxnet.python.gpu.cu92),印证了"按 CUDA 版本选择安装包"的发布约定。具体 pip 包名与可用 CUDA 版本请以当前发布渠道为准。
三、数据操作:Tensor 与 NDArray
两个框架都以多维矩阵为数据基础。下面的代码创建一个 5×3 的全 1 矩阵,逐元素加 1 后打印结果。
PyTorch:
import torch x = torch.ones(5,3) y = x + 1 yMXNet:
from mxnet import nd x = nd.ones((5,3)) y = x + 1 y除包名不同外,最主要的差异是:MXNet 的 shape 参数必须像 NumPy 一样以元组(括号包裹)传入,即nd.ones((5,3))而非nd.ones(5,3)。
两个框架都提供丰富的张量创建与操作函数。完整的 API 对照表见本文"附录:PyTorch 与 Gluon API 对照"一节。
四、模型训练四步走:MNIST 上的 MLP 对比
下面以 MNIST 手写数字分类任务为例,在两个框架中分别训练一个单隐藏层多层感知机(MLP),整个过程分为四步。
4.1 读取数据
PyTorch:
from torchvision import datasets, transforms trans = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.13,), (0.31,))]) pt_train_data = torch.utils.data.DataLoader(datasets.MNIST( root='.', train=True, download=True, transform=trans), batch_size=128, shuffle=True, num_workers=4)MXNet:
from mxnet import gluon from mxnet.gluon.data.vision import datasets, transforms trans = transforms.Compose([transforms.ToTensor(), transforms.Normalize(0.13, 0.31)]) mx_train_data = gluon.data.DataLoader( datasets.MNIST(train=True).transform_first(trans), batch_size=128, shuffle=True, num_workers=4)两个框架都支持自动下载 MNIST 并只取训练集。主要区别在于:MXNet 使用transform_first(trans)方法,明确表示变换只作用于数据批次中的第一个元素(图片),而不作用于第二个元素(标签);PyTorch 则是把 transform 直接传给datasets.MNIST(..., transform=trans)。
从源码看,DataLoader与Dataset是 MXNet 数据加载的基础组件,位于 python/mxnet/gluon/data 包中:DataLoader类定义于 dataloader.py,内置视觉数据集(MNIST、CIFAR10、CIFAR100、ImageFolderDataset)定义于 vision/datasets.py。
4.2 创建模型
PyTorch:
import torch.nn as pt_nn pt_net = pt_nn.Sequential( pt_nn.Linear(28*28, 256), pt_nn.ReLU(), pt_nn.Linear(256, 10))MXNet:
import mxnet.gluon.nn as mx_nn mx_net = mx_nn.Sequential() mx_net.add(mx_nn.Dense(256, activation='relu'), mx_nn.Dense(10)) mx_net.initialize()两者都用Sequential容器逐层堆叠网络。MXNet 与 PyTorch 的差异体现在三点:
- 输入尺寸推断:PyTorch 必须在
Linear的第一个参数显式指定输入大小(如28*28);MXNet 的Dense只需指定输出单元数,输入大小在第一次前向传播后自动推断。 - 激活函数内联:MXNet 可直接在全连接层和卷积层中指定激活函数(如
Dense(256, activation='relu')),PyTorch 通常把ReLU作为独立层。 - 显式初始化:MXNet 在定义模型结构后,必须显式调用
mx_net.initialize()。
从源码看,Dense是HybridBlock的子类,构造函数签名为Dense(units, activation=None, use_bias=True, flatten=True, ...),见 basic_layers.py。
若需要更灵活的执行模型(而非简单的顺序堆叠),PyTorch 可以继承nn.Module并自定义forward();MXNet 对应继承nn.Block并重写forward()。
4.3 损失函数与优化算法
PyTorch:
pt_loss_fn = pt_nn.CrossEntropyLoss() pt_trainer = torch.optim.SGD(pt_net.parameters(), lr=0.1)MXNet:
mx_loss_fn = gluon.loss.SoftmaxCrossEntropyLoss() mx_trainer = gluon.Trainer(mx_net.collect_params(), 'sgd', {'learning_rate': 0.1})代码差异很小。MXNet 侧的关键点:
- 使用
gluon.Trainer类,把优化算法名(如'sgd')作为字符串参数传入,配合优化器参数字典{'learning_rate': 0.1}。 - 使用
net.collect_params()收集网络全部参数(对应 PyTorch 的net.parameters()),见 block.py。
Trainer类定义于 trainer.py,其构造函数签名支持kvstore、compression_params、update_on_kvstore等分布式与梯度压缩相关参数;交叉熵损失SoftmaxCrossEntropyLoss定义于 loss.py。
4.4 训练循环
PyTorch:
import time for epoch in range(5): total_loss = .0 tic = time.time() for X, y in pt_train_data: pt_trainer.zero_grad() loss = pt_loss_fn(pt_net(X.view(-1, 28*28)), y) loss.backward() pt_trainer.step() total_loss += loss.mean() print('epoch %d, avg loss %.4f, time %.2f' % ( epoch, total_loss/len(pt_train_data), time.time()-tic))MXNet:
from mxnet import autograd for epoch in range(5): total_loss = .0 tic = time.time() for X, y in mx_train_data: with autograd.record(): loss = mx_loss_fn(mx_net(X), y) loss.backward() mx_trainer.step(batch_size=128) total_loss += loss.mean().asscalar() print('epoch %d, avg loss %.4f, time %.2f' % ( epoch, total_loss/len(mx_train_data), time.time()-tic))注意:由于权重初始化值与数据打乱顺序不同,每次运行的结果会略有差异。MXNet 侧需要注意的六点差异:
- 无需手动展平:MXNet 的
Dense层默认flatten=True,前向传播时不必像 PyTorch 那样调用X.view(-1, 28*28)把 4-D 输入展平为 2-D。 - 自动微分作用域:MXNet 需要在
autograd.record()作用域内完成前向计算,以便反向传播时自动求导。 - 无需每次清空梯度:MXNet 默认
grad_req='write',新梯度直接写入覆盖,不像 PyTorch 需要trainer.zero_grad()。 - step 需要步长:
trainer.step()必须传入更新步长(通常是 batch size),即mx_trainer.step(batch_size=128),见 trainer.py。 - 显式转标量:
total_loss += loss.mean().asscalar()把多维数组转为 Python 标量。 - 速度差异需谨慎解读:原文档示例中 MXNet 快约两倍,但作者明确提醒:这类玩具级对比的结论需要谨慎对待。
五、自动微分(Autograd)深度对比
5.1 Variable 包装 vs autograd 作用域
PyTorch 用Variable(..., requires_grad=True)声明需要梯度的张量;MXNet 用attach_grad()声明、autograd.record()作用域记录计算图:
| 功能 | PyTorch | MXNet Gluon |
|---|---|---|
| 记录计算 | x = Variable(torch.FloatTensor(1), requires_grad=True)y = x * 2y.backward() | x = mx.nd.ones((1,))x.attach_grad()with mx.autograd.record():y = x * 2y.backward() |
5.2 作用域覆盖:pause / train_mode / predict_mode
Dropout、BatchNorm 等算子在训练与推理阶段行为不同。MXNet 通过train_mode与predict_mode作用域控制这一行为;pause作用域用于不需要计算梯度的代码段。这几个作用域在 autograd.py 中均有实现:record(train_mode=True)返回记录作用域,pause(train_mode=False)返回暂停作用域,train_mode()与predict_mode()则只切换训练/推理行为而不改变记录状态。
| 功能 | PyTorch | MXNet Gluon |
|---|---|---|
| 作用域覆盖 | 不可用 | x = mx.nd.ones((1,))with autograd.train_mode():y = mx.nd.Dropout(x)with autograd.predict_mode():z = mx.nd.Dropout(y)w = mx.nd.ones((1,))w.attach_grad()with autograd.record():y = x * wy.backward()with autograd.pause():w += w.grad |
5.3 批结束同步
MXNet 采用惰性求值以换取性能:Python 线程把算子推入后端引擎后立即返回。因此在训练阶段,批结束处必须显式同步,例如调用asnumpy()、wait_to_read()、metric.update(...):
| 功能 | PyTorch | MXNet Gluon |
|---|---|---|
| 批结束同步 | 不可用 | for (data, label) in train_data:with autograd.record():output = net(data)L = loss(output, label)L.backward()trainer.step(data.shape[0])metric.update([label], [output]) |
六、PyTorch Module 与 Gluon Block
6.1 自定义网络块需要 name_scope
自定义Block时,Gluon 要求用self.name_scope()包裹子层的创建,以便为每个参数赋予标识所属模型的恰当名称:
| 功能 | PyTorch | MXNet Gluon |
|---|---|---|
| 自定义块 | class Net(torch.nn.Module):def __init__(self, D_in, D_out):super(Net, self).__init__()self.linear = torch.nn.Linear(D_in, D_out)def forward(self, x):return self.linear(x) | class Net(mx.gluon.Block):def __init__(self, D_in, D_out):super(Net, self).__init__()with self.name_scope():self.dense=mx.gluon.nn.Dense(D_out, in_units=D_in)def forward(self, x):return self.dense(x) |
6.2 参数与初始化
PyTorch 创建层时无需指定参数初始化器,各层有各自的默认初始化;Gluon 中既可以显式指定初始化器,也可以留空,所有参数在调用net.initialize(...)后完成初始化——未指定初始化器的层使用传入initialize的全局默认初始化器。Block.initialize的完整签名(init、ctx、verbose、force_reinit)见 block.py。
| 功能 | PyTorch | MXNet Gluon |
|---|---|---|
| 获取全部参数 | net.parameters() | net.collect_params() |
| 初始化网络 | 不可用 | net.initialize(mx.init.Xavier()) |
| 指定层初始化器 | layer = torch.nn.Linear(20, 10)torch.nn.init.normal(layer.weight, 0, 0.01) | layer = mx.gluon.nn.Dense(10, weight_initializer=mx.init.Normal(0.01)) |
6.3 现有块的用法一致
| 功能 | PyTorch | MXNet Gluon |
|---|---|---|
| 使用现有块 | y=net(x) | y=net(x) |
6.4 HybridBlock:混合化与部分形状推断
HybridBlock同时支持以 Symbol 和 NDArray 前向传播。hybridize()之后,HybridBlock 会生成并缓存表示前向计算的符号图。大部分内置块(Dense、Conv2D、MaxPool2D、BatchNorm 等)都是 HybridBlock。hybridize(active=True, static_alloc=False, static_shape=False)的详细参数见 block.py。
| 功能 | PyTorch | MXNet Gluon |
|---|---|---|
| 部分形状 + 混合化 | 不可用 | net = mx.gluon.nn.HybridSequential()with net.name_scope():net.add(mx.gluon.nn.Dense(10))net.hybridize() |
6.5 SymbolBlock:从符号图构建块
SymbolBlock可以从符号(Symbol)构建网络块,非常适合把预训练模型当作特征提取器使用:
| 功能 | PyTorch | MXNet Gluon |
|---|---|---|
| SymbolBlock | 不可用 | alexnet = mx.gluon.model_zoo.vision.alexnet(pretrained=True, prefix='model_')out = alexnet(inputs)internals = out.get_internals()outputs = [internals['model_dense0_relu_fwd_output']]feat_model = gluon.SymbolBlock(outputs, inputs, params=alexnet.collect_params()) |
Block、HybridBlock、SymbolBlock三个基类在 block.py 中依次定义,构成 Gluon 网络结构的完整继承体系。
七、PyTorch Optimizer 与 Gluon Trainer
7.1 大多数情况下无需调用 zero_grad
PyTorch 优化器(或 Gluon 的 Trainer)中的zero_grad用于清空所有参数的梯度。Gluon 中,当grad_req='write'(默认值)时,每批训练后梯度直接覆盖写入,无需像 PyTorch 那样每批调用zero_grad():
| 功能 | PyTorch | MXNet Gluon |
|---|---|---|
| 清空梯度 | optm = torch.optim.SGD(model.parameters(), lr=0.1)optm.zero_grad()loss_fn(model(input), target).backward()optm.step() | trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': 0.1})with autograd.record():loss = loss_fn(net(data), label)loss.backward()trainer.step(batch_size) |
7.2 多 GPU 训练
| 功能 | PyTorch | MXNet Gluon |
|---|---|---|
| 数据并行 | net = torch.nn.DataParallel(model, device_ids=[0, 1, 2])output = net(data) | ctx = [mx.gpu(i) for i in range(3)]data = gluon.utils.split_and_load(data, ctx)label = gluon.utils.split_and_load(label, ctx)with autograd.record():losses = [loss(net(X), Y) for X, Y in zip(data, label)]for l in losses:l.backward() |
MXNet 侧使用gluon.utils.split_and_load把数据按设备切分,然后分别前向、统一反向,split_and_load位于 python/mxnet/gluon/utils.py。
7.3 分布式训练
| 功能 | PyTorch | MXNet Gluon |
|---|---|---|
| 分布式数据并行 | torch.distributed.init_process_group(...)model = torch.nn.parallel.distributedDataParallel(model, ...) | store = kv.create('dist')trainer = gluon.Trainer(net.collect_params(), ..., kvstore=store) |
MXNet 通过 KVStore 机制实现分布式:创建分布式 KVStore(kv.create('dist'))后把它作为kvstore参数传给Trainer,参数更新即可在多机间协调。
八、训练监控
8.1 预定义评估指标
Gluon 提供多个预定义指标,可在训练中在线评估模型性能,例如mx.metric.Accuracy()。源码中Accuracy、TopKAccuracy、CrossEntropy等指标类均定义于 python/mxnet/metric.py。
| 功能 | PyTorch | MXNet Gluon |
|---|---|---|
| 指标 | 不可用 | metric = mx.metric.Accuracy()with autograd.record():output = net(data)L = loss(ouput, label)loss(ouput, label).backward()trainer.step(batch_size)metric.update(label, output) |
8.2 数据可视化
PyTorch 生态常用 TensorboardX,MXNet 生态对应 MXBoard(mxboard.SummaryWriter),两者 API 风格一致:
| PyTorch | MXNet |
|---|---|
sw = tensorboardX.SummaryWriter() | sw = mxboard.SummaryWriter() |
... | ... |
for name, param in model.named_parameters(): | for name, param in net.collect_params(): |
grad = param.clone().cpu().data.numpy() | grad = param.grad.asnumpy().flatten() |
sw.add_histogram(name, grad, n_iter) | sw.add_histogram(tag=str(param), |
... | values=grad, |
sw.close() | bins=200, |
global_step=i) | |
... | |
sw.close() |
九、数据加载与模型部署
9.1 数据加载组件
Dataset与DataLoader是两个框架数据加载的基础组件:
| 类 | PyTorch | MXNet Gluon |
|---|---|---|
| 数组数据集 | torch.utils.data.TensorDataset(data_tensor, label_tensor) | gluon.data.ArrayDataset(data_array, label_array) |
| 数据加载器 | torch.utils.data.DataLoader(dataset, batch_size=1, shuffle=False, sampler=None, batch_sampler=None, num_workers=0, collate_fn=<function default_collate>, drop_last=False) | gluon.data.DataLoader(dataset, batch_size=None, shuffle=False, sampler=None, last_batch='keep', batch_sampler=None, batchify_fn=None, num_workers=0) |
| 顺序采样器 | torch.utils.data.sampler.SequentialSampler(data_source) | gluon.data.SequentialSampler(length) |
| 随机采样器 | torch.utils.data.sampler.RandomSampler(data_source) | gluon.data.RandomSampler(length) |
注意gluon.data.DataLoader的last_batch参数(默认'keep')对应 PyTorch 的drop_last。常用计算机视觉数据集在mx.gluon.data.vision包中提供:
| 数据集 | PyTorch | MXNet Gluon |
|---|---|---|
| MNIST 手写数字 | torchvision.datasets.MNIST | mx.gluon.data.vision.MNIST |
| CIFAR10 | torchvision.datasets.CIFAR10 | mx.gluon.data.vision.CIFAR10 |
| CIFAR100 | torchvision.datasets.CIFAR100 | mx.gluon.data.vision.CIFAR100 |
| 按文件夹组织的图片 | torchvision.datasets.ImageFolder(root, transform=None, target_transform=None, loader=<function default_loader>) | mx.gluon.data.vision.ImageFolderDataset(root, flag, transform=None) |
9.2 模型序列化
MXNet 的序列化通过save_parameters与load_parameters完成:
| 功能 | PyTorch | MXNet Gluon |
|---|---|---|
| 保存模型参数 | torch.save(the_model.state_dict(), filename) | model.save_parameters(filename) |
| 加载参数 | the_model.load_state_dict(torch.load(PATH)) | model.load_parameters(filename, ctx, allow_missing=False, ignore_extra=False) |
MXNet 的load_parameters额外支持allow_missing(允许缺失参数)与ignore_extra(忽略多余参数),方便网络结构调整后加载历史权重。
附录:PyTorch 与 Gluon API 完整对照
A. Tensor 操作对照
以下为 PyTorch Tensor 与 MXNet NDArray 中函数名存在差异的完整对照表:
| 功能 | PyTorch | MXNet Gluon |
|---|---|---|
| 逐元素反余弦 | x.acos()或torch.acos(x) | nd.arccos(x) |
| 批量矩阵乘积与累加 | torch.addbmm(M, batch1, batch2) | nd.linalg_gemm(M, batch1, batch2)(Leading n-2 维被约减) |
| t1、t2 逐元素相除、乘 v 再加 t | torch.addcdiv(t, v, t1, t2) | t + v*(t1/t2) |
| 矩阵乘积与累加 | torch.addmm(M, mat1, mat2) | nd.linalg_gemm(M, mat1, mat2) |
| 两个向量外积加矩阵 | m.addr(vec1, vec2) | 不可用 |
| 逐元素应用函数 | x.apply_(calllable) | 不可用,但有nd.custom(x, 'op') |
| 逐元素反正弦 | x.asin()或torch.asin(x) | nd.arcsin(x) |
| 逐元素反正切 | x.atan()或torch.atan(x) | nd.arctan(x) |
| 两张量的正切 | x.atan2(y)或torch.atan2(x, y) | 不可用 |
| 批量矩阵乘积 | x.bmm(y)或torch.bmm(x, x) | nd.linalg_gemm2(x, y) |
| 从伯努利分布采样 | x.bernoulli() | 不可用 |
| 用柯西分布随机数填充 | x.cauchy_() | 不可用 |
| 按给定维切分张量 | x.chunk(num_of_chunk) | nd.split(x, num_outputs=num_of_chunk) |
| 将张量值限制在 min 与 max 之间 | x.clamp(min, max) | nd.clip(x, min, max) |
| 返回张量的副本 | x.clone() | x.copy() |
| 叉积 | x.cross(y) | 不可用 |
| 沿轴累积乘积 | x.cumprod(1) | 不可用 |
| 沿轴累积求和 | x.cumsum(1) | 不可用 |
| 首元素地址 | x.data_ptr() | 不可用 |
| 创建对角张量 | x.diag() | 不可用 |
| 计算张量的范数 | x.dist() | nd.norm(x)(仅计算 L2 范数) |
| 计算高斯误差函数 | x.erf() | 不可用 |
| 广播/扩展到新形状 | x.expand(3,4) | x.broadcast_to([3, 4]) |
| 用指数分布采样填充 | x.exponential_() | nd.random_exponential() |
| 逐元素取模 | x.fmod(3) | nd.module(x, 3) |
| 张量的小数部分 | x.frac() | x - nd.trunc(x) |
| 沿 dim 指定轴取值 | torch.gather(x, 1, torch.LongTensor([[0,0],[1,0]])) | nd.gather_nd(x, nd.array([[[0,0],[1,1]],[[0,0],[1,0]]])) |
| 最小二乘与最小范数求解 | B.gels(A) | 不可用 |
| 几何分布采样 | x.geometric_(p) | 不可用 |
| 张量所在设备 | print(x)会打印所在设备 | x.context |
| 重复张量 | x.repeat(4,2) | x.tile(4,2) |
| 张量数据类型 | x.type() | x.dtype |
| 散点写入 | torch.zeros(2, 4).scatter_(1, torch.LongTensor([[2], [3]]), 1.23) | nd.scatter_nd(nd.array([1.23,1.23]), nd.array([[0,1],[2,3]]), (2,4)) |
| 返回张量形状 | x.size() | x.shape |
| 张量元素个数 | x.numel() | x.size |
| 转为 NumPy ndarray | x.numpy() | x.asnumpy() |
| 对称矩阵特征分解 | e, v = a.symeig() | v, e = nd.linalg.syevd(a) |
| 转置 | x.t() | x.T |
| 均匀采样 | torch.uniform_() | nd.sample_uniform() |
| 插入新维度 | x.unsqueeze() | nd.expand_dims(x) |
| 重塑 | x.view(16) | x.reshape((16,)) |
| 按指定张量重塑 | x.view_as(y) | x.reshape_like(y) |
| 类型转换后返回副本 | x.type(type) | x.astype(dtype) |
| 把一个张量的值复制到另一个 | dst.copy_(src) | src.copyto(dst) |
| 指定形状的全 0 张量 | x = torch.zeros(2,3) | x = nd.zeros((2,3)) |
| 指定形状的全 1 张量 | x = torch.ones(2,3) | x = nd.ones((2,3)) |
| 与输入同形状、值为 1 的张量 | y = torch.ones_like(x) | y = nd.ones_like(x) |
B. GPU 操作
与 Tensor 类似,MXNet NDArray 可通过指定 context 复制到 GPU 上运算:
| 功能 | PyTorch | MXNet Gluon |
|---|---|---|
| 复制到 GPU | y = torch.FloatTensor(1).cuda() | y = mx.nd.ones((1,), ctx=mx.gpu(0)) |
| 转为 numpy 数组 | x = y.cpu().numpy() | x = y.asnumpy() |
| 上下文作用域 | with torch.cuda.device(1):y= torch.cuda.FloatTensor(1) | with mx.gpu(1):y = mx.nd.ones((3,5)) |
C. 跨设备复制
| 功能 | PyTorch | MXNet Gluon |
|---|---|---|
| 从 GPU 0 复制到 GPU 1 | x = torch.cuda.FloatTensor(1)y=x.cuda(1) | x = mx.nd.ones((1,), ctx=mx.gpu(0))y=x.as_in_context(mx.gpu(1)) |
| 在不同 GPU 间复制 Tensor/NDArray | y.copy_(x) | x.copyto(y) |
结论
Apache MXNet 的 Gluon API 与 PyTorch 在绝大多数场景下代码高度相似,主要差异集中在两点:一是术语不同(Tensor vs NDArray),二是梯度累积行为不同——PyTorch 累积梯度而 MXNet 默认覆盖梯度。掌握这些差异后,在两个框架之间迁移代码非常直接。
如果希望进一步挖掘 Gluon 的性能优势,可以继续学习两个进阶主题:
- Hybridize 教程:学习如何编写既能以命令式执行、又能转换为符号图执行的混合编程代码,从而获得符号图的性能优化能力。
- 自定义层:学习如何用自定义算子与自定义层扩展 MXNet,实现论文中特有的网络结构。
- 深度学习
- 机器学习
- 人工智能
【免费下载链接】mxnet
Lightweight, Portable, Flexible Distributed/Mobile Deep Learning with Dynamic, Mutation-aware Dataflow Dep Scheduler; for Python, R, Julia, Scala, Go, Javascript and more
相关推荐
从 PyTorch 迁移到 Apache MXNet:Gluon API 逐行对照实战指南
从 PyTorch 迁移到 Apache MXNet:Gluon API 逐行对照实战指南 Apache MXNet 通过 Gluon API 提供了与 PyT
人工智能深度学习机器学习从 PyTorch 迁移到 Apache MXNet:Gluon API 逐模块对照实战指南
从 PyTorch 迁移到 Apache MXNet:Gluon API 逐模块对照实战指南 Apache MXNet 的 Gluon API 为开发者提供了与
深度学习人工智能机器学习分布式训练从 PyTorch 迁移到 Apache MXNet:Gluon API 全面对照指南(MNIST 实战)
从 PyTorch 迁移到 Apache MXNet:Gluon API 全面对照指南(MNIST 实战) 本指南围绕 MXNet 官方 "Moving to
深度学习机器学习人工智能
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考