进入更深的层次:模型构造、参数访问、自定义层和使用 GPU。

模型构建

在多层感知机的实现中,我们首先构造 Sequential 实例,然后依次添加两个全连接层。其中第一层的输出大小为 256,即隐藏层单元个数是 256;第二层的输出大小为 10,即输出层单元个数是 10。

我们之前都是用了 Sequential 类来构造模型。这里我们另外一种基于 Block 类的模型构造方法,它让构造模型更加灵活,也将让你能更好的理解 Sequential 的运行机制。

继承 Block 类来构造模型

Block 类是 gluon.nn 里提供的一个模型构造类,我们可以继承它来定义我们想要的模型。例如,我们在这里构造一个同前提到的相同的多层感知机。这里定义的 MLP 类重载了 Block 类的两个函数:init 和 forward.

from mxnet import nd
from mxnet.gluon import nn class MLP(nn.Block):
# 声明带有模型参数的层,这里我们声明了两个全链接层。
def __init__(self, **kwargs):
# 调用 MLP 父类 Block 的构造函数来进行必要的初始化。这样在构造实例时还可以指定其他函数参数,例如后面将介绍的模型参数 params。
super(MLP, self).__init__(**kwargs)
# 隐藏层。
self.hidden = nn.Dense(256, activation='relu')
# 输出层。
self.output = nn.Dense(10)
# 定义模型的前向计算,即如何根据输出计算输出。
def forward(self, x):
return self.output(self.hidden(x))

我们可以实例化 MLP 类得到 net

x = nd.random.uniform(shape=(2,20))
net = MLP()
net.initialize()
net(x)

其中,net(x) 会调用了 MLP 继承至 Block 的 call 函数,这个函数将调用 MLP 定义的 forward 函数来完成前向计算。

我们无需在这里定义反向传播函数,系统将通过自动求导,来自动生成 backward 函数。

注意到我们不是将 Block 叫做层或者模型之类的名字,这是因为它是一个可以自由组建的部件。它的子类既可以一个层,例如 Gluon 提供的 Dense 类,也可以是一个模型,我们定义的 MLP 类,或者是模型的一个部分,例如我们会在之后介绍的 ResNet 的残差块。

Sequential 类继承自 Block 类

当模型的前向计算就是简单串行计算模型里面各个层的时候,我们可以将模型定义变得更加简单,这个就是 Sequential 类的目的,它通过 add 函数来添加 Block 子类实例,前向计算时就是将添加的实例逐一运行。下面我们实现一个跟 Sequential 类有相同功能的类,这样你可以看的更加清楚它的运行机制。

class MySequential(nn.Block):
def __init__(self, **kwargs):
super(MySequential, self).__init__(**kwargs) def add(self, block):
# block 是一个 Block 子类实例,假设它有一个独一无二的名字。我们将它保存在Block 类的成员变量 _children 里,其类型是 OrderedDict.
#当调用initialize 函数时,系统会自动对 _children 里面所有成员初始化。
self._children[block.name] = block def forward(self, x):
# OrderedDict 保证会按照插入时的顺序遍历元素。
for block in self._children.values():
x = block(x)
return x

使用:

net = MySequential()
net.add(nn.Dense(256, activation='relu'))
net.add(nn.Dense(10))
net.initialize()
net(x)

构造复杂的模型

我们构造一个稍微复杂点的网络。在这个网络中,我们通过 get_constant 函数创建训练中不被迭代的参数,即常数参数。在前向计算中,除了使用创建的常数参数外,我们还使用 NDArray 的函数和 Python 的控制流,并多次调用同一层。


class FancyMLP(nn.Block):
def __init__(self, **kwargs):
super(FancyMLP, self).__init__(**kwargs)
# 使用 get_constant 创建的随机权重参数不会在训练中被迭代(即常数参数)。
self.rand_weight = self.params.get_constant(
'rand_weight', nd.random.uniform(shape=(20, 20)))
self.dense = nn.Dense(20, activation='relu') def forward(self, x):
x = self.dense(x)
# 使用创建的常数参数,以及 NDArray 的 relu 和 dot 函数。
x = nd.relu(nd.dot(x, self.rand_weight.data()) + 1)
# 重用全连接层。等价于两个全连接层共享参数。
x = self.dense(x)
# 控制流,这里我们需要调用 asscalar 来返回标量进行比较。
while x.norm().asscalar() > 1:
x /= 2
if x.norm().asscalar() < 0.8:
x *= 10
return x.sum()

使用:

net = FancyMLP()
net.initialize()
net(x)

由于 FancyMLP 和 Sequential 都是 Block 的子类,我们可以嵌套调用他们。

class NestMLP(nn.Block):
def __init__(self, **kwargs):
super(NestMLP, self).__init__(**kwargs)
self.net = nn.Sequential()
self.net.add(nn.Dense(64, activation='relu'),
nn.Dense(32, activation='relu'))
self.dense = nn.Dense(16, activation='relu') def forward(self, x):
return self.dense(self.net(x)) net = nn.Sequential()
net.add(NestMLP(), nn.Dense(20), FancyMLP()) net.initialize()
net(x)

MXNET:深度学习计算-模型构建的更多相关文章

  1. MXNET:深度学习计算-模型参数

    我们将深入讲解模型参数的访问和初始化,以及如何在多个层之间共享同一份参数. 之前我们一直在使用默认的初始函数,net.initialize(). from mxnet import init, nd ...

  2. 深度学习之TensorFlow构建神经网络层

    深度学习之TensorFlow构建神经网络层 基本法 深度神经网络是一个多层次的网络模型,包含了:输入层,隐藏层和输出层,其中隐藏层是最重要也是深度最多的,通过TensorFlow,python代码可 ...

  3. NVIDIA GPUs上深度学习推荐模型的优化

    NVIDIA GPUs上深度学习推荐模型的优化 Optimizing the Deep Learning Recommendation Model on NVIDIA GPUs 推荐系统帮助人在成倍增 ...

  4. MXNet深度学习库简介

    MXNet深度学习库简介 摘要: MXNet是一个深度学习库, 支持C++, Python, R, Scala, Julia, Matlab以及JavaScript等语言; 支持命令和符号编程; 可以 ...

  5. [笔记] 基于nvidia/cuda的深度学习基础镜像构建流程 V0.2

    之前的[笔记] 基于nvidia/cuda的深度学习基础镜像构建流程已经Out了,以这篇为准. 基于NVidia官方的nvidia/cuda image,构建适用于Deep Learning的基础im ...

  6. mxnet深度学习实战学习笔记-9-目标检测

    1.介绍 目标检测是指任意给定一张图像,判断图像中是否存在指定类别的目标,如果存在,则返回目标的位置和类别置信度 如下图检测人和自行车这两个目标,检测结果包括目标的位置.目标的类别和置信度 因为目标检 ...

  7. 深度学习VGG16模型核心模块拆解

    原文连接:https://blog.csdn.net/qq_40027052/article/details/79015827 注:这篇文章是上面连接作者的文章.在此仅作学习记录作用. 如今深度学习发 ...

  8. Caffe深度学习计算框架

    Caffe | Deep Learning Framework是一个清晰而高效的深度学习框架,其作者是博士毕业于UC Berkeley的 Yangqing Jia,目前在Google工作.Caffe是 ...

  9. 在排序模型方面,点评搜索也经历了业界比较普遍的迭代过程:从早期的线性模型LR,到引入自动二阶交叉特征的FM和FFM,到非线性树模型GBDT和GBDT+LR,到最近全面迁移至大规模深度学习排序模型。

    https://mp.weixin.qq.com/s/wjgoH6-eJQDL1KUQD3aQUQ 大众点评搜索基于知识图谱的深度学习排序实践 原创: 非易 祝升 仲远 美团技术团队 前天    

随机推荐

  1. SpringMVC框架09——@ResponseBody的用法详解

    @ResponseBody可以标注在方法上也可以标注在类上面.简单来说,当标注在方法上时,该方法的返回结果直接转成JSON格式:当标注在类上时,该类中的所有方法的返回结果都转换成JSON格式. 代码示 ...

  2. SpringMvc 文件下载 详解

    最近SSM 需要用到文件下载,以前没用过,在百度上找了好久发现没有一篇博客,对于此段代码进行详细讲解, 这里是本人的个人总结,跟大家分享一下!!!不谢 /** * 文件下载 * ResponseEnt ...

  3. 【xxl-job】轻松实现分布式定时任务demo实例

    [项目描述]前段时间专门独立了一个spring boot服务,用于做和第三方erp系统的对接工作.此服务的第一个需求工作就是可以通过不同的规则,设置不同的定时任务,从而获取erp系统的商品数据.所以, ...

  4. python魔法方法-单目运算及一般算数运算

    在比较的魔法方法中,我们讨论了魔法方法其实就是重载了操作符,例如>.<.==等.而这里,我们继续讨论有关于数值的魔法方法. 1.单目运算符或单目运算函数 __pos__(self) 实现一 ...

  5. SQL LOAD TABLE tbl_name FROM MASTER语法 把表的拷贝从主服务器转移到从属服务器。

    用于把表的拷贝从主服务器转移到从属服务器.本语句的主要作用是调试LOAD DATA FROM MASTER.它要求用于连接主服务器的帐户拥有对主服务器的RELOAD和SUPER权限,并拥有对要载入的主 ...

  6. memcache 在php中的用法

    memcached 的安装方法详见我博客的另一个页面:http://www.cnblogs.com/chrdai/p/6656443.html 用法: 一.memcache 连接命令: 1.memca ...

  7. Java程序员面试中的多线程问题1

    转自:http://blog.jobbole.com/18571/ 很多核心Java面试题来源于多线程(Multi-Threading)和集合框架(Collections Framework), 理解 ...

  8. SourceTree + Beynod Compare解决Git冲突的方法

    https://www.cnblogs.com/yufeng218/p/6523422.html

  9. c# pictureBox1.Image的获得图片路径的三种方法 winform

    代码如下:c# pictureBox1.Image的获得图片路径的三种方法 winform 1.绝对路径:this.pictureBox2.Image=Image.FromFile("D:\ ...

  10. Java学习(一)--面向对象(一)

    面向对象的思想一直指导者我们软件的分析.设计与开发.java语言是一种面向对象的语言.在学习java之前,先回想一以下向过程和面向对象. 一面向过程 面向过程主张按功能来划分系统需求.每一个功能都负责 ...