进入更深的层次:模型构造、参数访问、自定义层和使用 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. POJ 3903 Stock Exchange 【最长上升子序列】模板题

    <题目链接> 题目大意: 裸的DP最长上升子序列,给你一段序列,求其最长上升子序列的长度,n^2的dp朴素算法过不了,这里用的是nlogn的算法,用了二分查找. O(nlogn)算法 #i ...

  2. 局域网下ARP欺骗、嗅探,以及DNS欺骗

    准备:kali.xp kali ip:192.168.14.157 目标ip:192.168.14.158 目标网关:192.168.14.2 ARP欺骗:arpspoof -t 目标ip -r 目标 ...

  3. 001.网络TCP/IP工程知识点

    一 互联网概述 计算机网络定义:由自主计算机互连起来的集合体. 计算机网络两大部分:硬件:计算机.通信设备.接口设备和传输介质. 软件:通信协议和应用软件. 广域网拓扑结构通常有:网状拓扑结构和环形拓 ...

  4. sleep() 和 wait() 有什么区别?

     sleep:Thread类中定义的方法,表示线程休眠,会自动唤醒: wait:Object中定义的方法,需要手工调用notify()或者notifyAll()方法. sleep是线程类(Thread ...

  5. react和vue的异同点

    一.相似处1.使用Virtual DOM,都有jsx,性能好.2.提供了响应式(reactive)和可组合的视图组件(composable view component).3.将注意力集中保持在核心库 ...

  6. Web前端性能优化——编写高效的JavaScript

    前言 随着计算机的发展,Web富应用时代的到来,Web 2.0早已不再是用div+css高质量还原设计的时代.自Gmail网页版邮件服务的问世开始,Web前端开发也开启了新的纪元.用户需求不断提高,各 ...

  7. BZOJ.2199.[USACO2011 Jan]奶牛议会(2-SAT)

    题目链接 建边不说了.对于议案'?'的输出用拓扑不好判断,直接对每个议案的结果DFS,看是否会出现矛盾 Tarjan也用不到 //964kb 76ms #include <cstdio> ...

  8. javascript加密PHP解密---jsencrypt

    今天偶然发现jsencrypt这玩意,之前做"直播室聊天"时 数据传输明文问题没解决; 一直苦苦寻找技术解决方案今天勉强找了个: 原理:javascript加密PHP解密: 完全依 ...

  9. 阻止默认事件preventDefault与returnValue

    通过阻止默认事件,禁止鼠标右键的使用 document.getElementById('dd').oncontextmenu = function(ev){ event = ev || window. ...

  10. MAC自动脚本

    链接: crontab 详细用法 定时任务 Linux crontab命令 定时任务 用法详解以及no crontab for root解决办法