低代码到底是不是行业毒瘤?一线大厂怎么做的?戳此了解>>> 了解详情
写点什么

介绍 Gluon 这一易于使用的灵活深度学习编程接口

2019 年 11 月 08 日

介绍 Gluon 这一易于使用的灵活深度学习编程接口

原文链接 | 今天,AWS 和 Microsoft 发布了一项新规范,该规范旨在为所有开发人员改进机器学习技术的速度、灵活性和可访问性,而无论他们选择什么样的深度学习框架。这种合作的第一项成果是全新的 Gluon 接口,这是 Apache MXNet 中的一个开源库,让所有技能级别的开发人员都能够设计深度学习模型的原型、构建该模型以及开展训练。该接口极大地简化了创建深度学习模型的过程,而不会影响到训练速度。


下面是 Gluon 的四大优势以及演示这些优势的代码示例:


(1) 简单、容易理解的代码

在 Gluon 中,您可以使用简单、清晰和简洁的代码定义神经网络。您将获得一整套即插即用的神经网络构建块,包括预定义的层、优化程序和初始化程序。利用这些构建块,您无需再纠缠于各种各样复杂的底层实施细节。下面的示例说明了如何使用短短几行代码定义一个简单的神经网络:


Bash


# 第一步是初始化您的模型net = gluon.nn.Sequential()# 接下来,定义您的模型架构with net.name_scope():    net.add(gluon.nn.Dense(128, activation="relu")) # 第一层 - 128 个节点    net.add(gluon.nn.Dense(64, activation="relu")) # 第二层 - 64 个节点    net.add(gluon.nn.Dense(num_outputs)) # 输出层
复制代码


下表说明了神经网络的体系结构:



有关更多信息,请转到本教程,了解如何使用 Gluon 神经网络构建块来构建一个称为多层感知器 (MLP) 的简单神经网络。对于更高级的使用案例来说,从头开始编写神经网络的各个部分也是非常容易的。使用 Gluon,您可以在神经网络中混用和匹配预定义组件和自定义组件。


(2) 灵活的结构

训练神经网络模型会耗费大量计算资源,在某些情况下,可能需要几天甚至几周的时间。许多深度学习框架通过严格定义模型并将其与训练算法分离,减少了这一时间。这种僵化的方法会让复杂性大为增加,也使得调试工作变得非常困难。


Gluon 方法则另辟蹊径。它将训练算法和神经网络模型组合在一起,在开发过程中提供了灵活性,而不会牺牲性能。这种方法的核心是 Gluon


trainer 方法,该方法用于对模型进行训练。


trainer 方法依托于 MXNet


autograd 库,该库用于自动计算导数 (即梯度)。导数 是一种数学运算,用于测量变量的变化率。这是训练算法的必要输入。


autograd 库可以有效地实施这些数学运算,并且对于支持 Gluon 提供的灵活性至关重要。现在,您可以定义由一个简单的嵌套


for 循环构成的训练算法,只需结合使用


autograd 和


trainer 即可。


Bash


epochs = 10
for e in range(epochs): for i, batch in enumerate(train_data): data = batch.data[0] label = batch.label[0] with autograd.record(): # 开始记录导数 output = net(data) # 前向迭代 loss = softmax_cross_entropy(output, label) loss.backward() trainer.step(data.shape[0])
复制代码


这种灵活的结构使您的代码直观且易于调试,为建立更高级的模型奠定了基础。您可以在自己的神经网络中使用熟悉的本机 Python 语言结构,如


for 循环或


if 语句,或者将这些语言结构用作您算法的一部分。通过将模型和算法组合在一起,可以执行模型中的每一行代码,这样能够更容易地确定导致错误的特定代码行。


(3) 动态图表

在某些情况下,神经网络模型可能需要在训练过程中改变形状和大小。尤其是在馈送到神经网络中的数据输入是可变内容的情况下,这是非常必要的,这种情况在自然语言处理 (NLP) 中很常见,其中输入的每个句子都可能有不同的长度。使用 Gluon,神经网络定义可以是动态的,这意味着您可以随时使用所需的任何结构以及任何 Python 本机控制流来构建神经网络。


例如,利用这些动态神经网络结构,可以更轻松地构建树状结构的长短期记忆 (LSTM) 模型,该模型是 NLP 的一大进步,由 Kai Sheng Tai、Richard Socher 和 Chris Manning 在 2015 年提出。树结构 LSTM 是一个强大的模型,例如可以识别两个句子是否具有相同的含义。以下面的情况为例,其中两个句子本质上具有相同的含义:


  • “Michael threw the football in front of the player.”

  • “The ball was thrown short of the target by Michael.”


可以简单地将句子馈送到一个周期性神经网络 (一种流行的序列学习模型) 并进行分类。不过,树结构 LSTM 的独到之处在于,它认为我们经常在语言中遇到一些有关先前学到的知识的问题。例如,句子呈现出语法结构,并且我们有强大的工具从句子中提取这个结构。我们可以使用一个树结构的神经网络来组合这些单词,该神经网络的结构模仿了句子的已知语法树结构,如下图所示。



(斯坦福自然语言处理组)


这就要求为每个示例动态地构建不同的神经网络结构。这对于传统框架来说很难,但是 Gluon 可以处理它,而且不会有任何问题。在下面的代码段中,您可以看到如何在模型训练的每个前向迭代中引入一个循环,同时仍然受益于


autograd 和


trainer 带来的简化。这使得模型能够遍历句子的树结构,从而基于该结构进行学习。


Bash


def forward(self, F, inputs, tree):    children_outputs = [self.forward(F, inputs, child)                        for child in tree.children]    #在模型定义和训练过程中,基于每个    #输入句子的语法结构来构建神经网络
复制代码


(4) 高性能

借助 Gluon 提供的灵活性,您可以轻松地对神经网络模型进行原型设计和试验。然后,当速度变得比灵活性更为重要时 (例如,当您准备好提供所有训练数据时),Gluon 接口使您能够轻松地缓存神经网络模型,以实现高性能和减少内存占用。当您完成原型设计并准备在更大的数据集上进行测试时,您只需要在设置神经网络过程中稍微调整即可。您不能使用


Sequential(如前所示) 来堆叠神经网络层,而必须使用


HybridSequential。它的功能与


Sequential 相同,但可以让您调用经过优化的底层引擎来表示您的部分或全部模型架构。


Bash


net = nn.HybridSequential()with net.name_scope():    net.add(nn.Dense(128, activation="relu")) # 第一层 - 128 个节点    net.add(nn.Dense(64, activation="relu")) # 第二层 - 64 个节点    net.add(nn.Dense(10)) # 输出层
复制代码


接下来,为了编译和优化


HybridSequential,我们可以调用


hybridize 方法:


Bash


net.hybridize()
复制代码


现在,在训练您的模型时,您将能够获得与本机 MXNet 接口几乎相同的高性能,并实现几乎相同的内存节约。


Gluon 入门

要开始使用 Gluon,您可以按照安装最新版本的 MXNet 的以下简单步骤操作,或者可以在云中启动深度学习 Amazon 系统映像 (AMI)。接下来,我们将逐步了解如何使用我们之前讨论过的不同组件来构建和训练一个简单的两层神经网络,该神经网络称为多层感知器。我们建议使用 Python 3.3 或更高版本,并使用 Jupyter 笔记本实施此示例。


第一步,导入 MXNet 并获取


gluon 库以及其他必需的库


autograd 和


ndarray。


Bash


import mxnet as mxfrom mxnet import gluon, autograd, ndarray
复制代码


接下来,获取数据并执行一些预处理。我们将导入常用的 MNIST 数据集,其中包括大量手写数字图像集合以及图像的正确标签。我们还将图片重新整理成数组,以便轻松处理并将数组转换为 MXNet 本机 NDArray 对象类。


Bash


# 使用本机 MXNet utils 函数导入 MNISTdata = mx.test_utils.get_mnist()
# 设置训练数据并重新整理图片train_data = data['train_data'].reshape((-1, 784))train_label = data['train_label']
# 设置测试数据并重新整理图片test_data = data['test_data'].reshape((-1, 784))test_label = data['test_label']
# 将数据转换为 NDArraytrain_data_mx = mx.nd.array(train_data)train_label_mx = mx.nd.array(train_label)test_data_mx = mx.nd.array(test_data)test_label_mx = mx.nd.array(test_label)
复制代码


接下来,我们创建一个迭代器来保存训练数据。迭代器是一个非常有用的对象类,用于遍历大型数据集。在这之前,我们必须先设置批处理大小,它定义神经网络在训练算法的每次迭代期间将要处理的数据量 – 在本示例中为 32。


Bash


batch_size = 32train_data = mx.io.NDArrayIter(train_data_mx, train_label_mx, batch_size,                                   shuffle=True)
复制代码


现在,我们已经准备好定义实际的神经网络。我们将创建两个层:第一层将有 128 个节点,第二层将有 64 个节点。它们都包含一个称为修正线性单元 (ReLU) 的激活函数。激活函数非常重要,因为它们使模型能够表示输入与输出之间的非线性关系。我们还需要设置输出层,其节点数与可能的输出总数相对应。在我们使用 MNIST 的示例中,只有 10 个可能的输出,因为图片只给出 10 个数字 (即 0 到 9)。


Bash


# 第一步是初始化您的模型net = gluon.nn.Sequential()# 接下来,定义您的模型架构with net.name_scope():    net.add(gluon.nn.Dense(128, activation="relu")) # 第一层 - 128 个节点    net.add(gluon.nn.Dense(64, activation="relu")) # 第二层 - 64 个节点    net.add(gluon.nn.Dense(10)) # 输出层
复制代码


在开始模型训练过程之前,我们需要初始化模型的参数并设置损耗和模型优化程序函数。


Bash


# 我们从正态分布中所有模型参数的# 随机值开始,标准偏差为 0.05net.collect_params().initialize(mx.init.Normal(sigma=0.05))
# 我们选择使用 softmax 交叉熵损耗函数# 来测量模型能够预测正确答案的程度softmax_cross_entropy = gluon.loss.SoftmaxCrossEntropyLoss()
# 我们选择使用随机梯度下降 (sgd) 训练算法,# 并将学习速率超参数设置为 .1trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': .1})
复制代码


现在可以定义模型训练算法了。对于每次迭代,有四个步骤:(1) 传入一批数据;(2) 计算由神经网络模型生成的输出与实际真实结果之间的差异 (即损耗);(3) 使用


autograd 计算模型参数与损耗影响有关的导数;(4) 使用


trainer 方法以减少损耗的方式优化参数。我们将 epochs 的数量设置为 10,这意味着我们将遍历整个训练数据集 10 次。


Bash


epochs = 10
for e in range(epochs): for i, batch in enumerate(train_data): data = batch.data[0] label = batch.label[0] with autograd.record(): # 开始记录导数 output = net(data) # 前向迭代 loss = softmax_cross_entropy(output, label) loss.backward() trainer.step(data.shape[0])
复制代码


我们现在有一个经过训练的神经网络模型,下面让我们看看使用我们设定的测试数据的准确度。我们通过将预测值与实际值进行比较来计算准确度。


Bash


acc = mx.metric.Accuracy()# 初始化准确度指标output = net(test_data_mx) # 通过神经网络运行测试数据predictions = ndarray.argmax(output, axis=1) # 测试数据的预测acc.update(preds=predictions, labels=test_label_mx) # 计算准确度print(acc)
复制代码


要详细地了解 Gluon 接口和深度学习,您可以参考一系列全面的教程,其中涵盖了从介绍性内容到深度学习再到如何实施先进的神经网络模型在内的所有内容。


作者介绍:



Vikram Madan 是 AWS 深度学习高级产品经理。他负责开发让深度学习引擎变得更易于使用的产品,工作重点是开源 Apache MXNet 引擎。在业余时间,他喜欢长跑以及看纪录片。


本文转载自 AWS 技术博客。


原文链接:


https://amazonaws-china.com/cn/blogs/china/introducing-gluon-an-easy-to-use-programming-interface-for-flexible-deep-learning/


2019 年 11 月 08 日 08:00217

欲了解 AWS 的更多信息,请访问【AWS 技术专区】

评论

发布
暂无评论
发现更多内容

架构师训练营第三周总结

James-Pang

极客大学架构师训练营

第三周作业一

李海明

单例模式 组合模式

作业03-代码重构

梦子说

极客大学架构师训练营 命题作业

手握美团offer,结果背调红灯,哭了,网友:别小瞧背调公司

程序员生活志

面试 美团 offer 背调

如果你想要说服别人,要诉诸利益,而非诉诸理性

Neco.W

理性 说服 利益 谈判

新来的"大神"用策略模式把if else给"优化"了,技术总监说:能不能想好了再改?

Hollis

Java 设计模式

架构师训练营第 3 周作业

Season

单例模式 极客大学架构师训练营 组合模式

第三章作业

武鹏

极客时间架构师训练营 - week3 - 作业 1

jjn0703

极客时间 极客大学架构师训练营

大厂经验(2):多端可视化埋点解决方案

DeeperMan

前端 采集 埋点

助力经济复苏 联想来酷"618"聚"惠"来袭

Geek_116789

架构师训练营第三周总结

sunnywhy

架构师训练营 Week03 学习心得

架构师训练营 第三周 设计模式作业

且听且吟

极客大学架构师训练营

组合设计模式-打印窗口组件的树状结构

张磊

单例模式的实现方式

互金从业者X

架构师训练营第三周作业

sunnywhy

总结-02-设计模式

梦子说

学习 极客大学架构师训练营

数字化转型必读书单

华章IT

数据中台 中台 数字化转型 行业资讯 银行数字化转型

架构师训练营第三周作业

hiqian

架构训练营 0 期总结 -- 第三周

互金从业者X

作业-02

梦子说

极客大学架构师训练营 作业

设计模式的应用

李海明

总结

架构师训练营 - 学习总结 - 第三讲

吕浩

代码重构

dongge

MySQL-InnoDB 索引

Arthur

架构师训练营第三周作业

James-Pang

极客大学架构师训练营

如何有效实现“科技抗疫”?这家科技巨头正在作出典范

最新动态

你不知道的 Web Workers (上)

阿宝哥

Java Web 前端开发 Web Worker

只看到了别人28岁从字节跳动退休,背后的期权知识你知道吗?

四猿外

创业 程序员 字节跳动 个人成长 期权

架构师训练营第三周作业

王铭铭

极客大学架构师训练营

2021 ThoughtWorks 技术雷达峰会

2021 ThoughtWorks 技术雷达峰会

介绍 Gluon 这一易于使用的灵活深度学习编程接口-InfoQ