一、不含参数层

通过继承Block自定义了一个将输入减掉均值的层:CenteredLayer类,并将层的计算放在forward函数里,

from mxnet import nd, gluon
from mxnet.gluon import nn class CenteredLayer(nn.Block):
def __init__(self, **kwargs):
super(CenteredLayer, self).__init__(**kwargs) def forward(self, x):
return x - x.mean() # 直接使用这个层
layer = CenteredLayer()
# layer(nd.array([1, 2, 3, 4, 5])) # 构建更复杂模型
net = nn.Sequential()
net.add(nn.Dense(128))
net.add(nn.Dense(10))
net.add(CenteredLayer()) # 初始化、运行……
net.initialize()
y = net(nd.random.uniform(shape=(4, 8)))

二、含参数层

注意,本节实现的自定义层不能自动推断输入尺寸,需要手动指定

见上节『MXNet』第三弹_Gluon模型参数在自定义层的时候我们常使用Block自带的ParameterDict类添加成员变量params,如下,

from mxnet import gluon
from mxnet.gluon import nn class MyDense(nn.Block):
def __init__(self, units, in_units, **kwargs):
super(MyDense, self).__init__(**kwargs)
self.weight = self.params.get('weight', shape=(in_units, units))
self.bias = self.params.get('bias', shape=(units,)) def forward(self, x):
linear = nd.dot(x, self.weight.data()) + self.bias.data()
return nd.relu(linear) # 实际运行
dense = MyDense(5, in_units=10)

如果不想使用ParameterDict类则需要一下操作

# self.weight = self.params.get('weight', shape=(in_units, units))
self.weight = gluon.Parameter('weight', shape=(in_units, units))
self.params.update({'weight':self.weight})

否则在net.initialize()初始化时是初始化不到ParameterDict外变量的。

有关这一点详见下面:

    def __init__(self, conv_arch, dropout_keep_prob, **kwargs):
super(SSD, self).__init__(**kwargs)
self.vgg_conv = nn.Sequential()
self.vgg_conv.add(repeat(*conv_arch[0], pool=False))
[self.vgg_conv.add(repeat(*conv_arch[i])) for i in range(1, len(conv_arch))]
# 迭代器对象只能进行单次迭代,所以将之转化为tuple,否则识别参数处迭代后forward再次迭代直接跳出循环
# self.vgg_conv = tuple([repeat(*conv_arch[i])
# for i in range(len(conv_arch))])
# 只能识别实例属性直接为mx层函数或者mx序列对象的参数,如果使用其他容器,需要将参数收集进参数字典
# _ = [self.params.update(block.collect_params()) for block in self.vgg_conv] def forward(self, x, feat_layers):
end_points = {'block0': x}
for (index, block) in enumerate(self.vgg_conv):
end_points.update({'block{:d}'.format(index+1): block(end_points['block{:d}'.format(index)])})
return end_points

属性对象是mxnet的对象时才能默认识别层中的参数,否则需要显式收集进self.params中。

测试代码:

if __name__ == '__main__':

    ssd = SSD(conv_arch=((2, 64), (2, 128), (3, 256), (3, 512), (3, 512)),
dropout_keep_prob=0.5)
ssd.initialize()
X = mx.ndarray.random.uniform(shape=(1, 1, 304, 304))
import pprint as pp
pp.pprint([x[1].shape for x in ssd(X).items()])

自行验证即可。

『MXNet』第四弹_Gluon自定义层的更多相关文章

  1. 『MXNet』第三弹_Gluon模型参数

    MXNet中含有init包,它包含了多种模型初始化方法. from mxnet import init, nd from mxnet.gluon import nn net = nn.Sequenti ...

  2. 『MXNet』第六弹_Gluon性能提升

    一.符号式编程 1.命令式编程和符号式编程 命令式: def add(a, b): return a + b def fancy_func(a, b, c, d): e = add(a, b) f = ...

  3. 『MXNet』第六弹_Gluon性能提升 静态图 动态图 符号式编程 命令式编程

    https://www.cnblogs.com/hellcat/p/9084894.html 目录 一.符号式编程 1.命令式编程和符号式编程 2.MXNet的符号式编程 二.惰性计算 用同步函数实际 ...

  4. 『PyTorch』第四弹_通过LeNet初识pytorch神经网络_下

    『PyTorch』第四弹_通过LeNet初识pytorch神经网络_上 # Author : Hellcat # Time : 2018/2/11 import torch as t import t ...

  5. 『MXNet』第十弹_物体检测SSD

    全流程地址 一.辅助API介绍 mxnet.image.ImageDetIter 图像检测迭代器, from mxnet import image from mxnet import nd data_ ...

  6. 『MXNet』第八弹_数据处理API_下_Image IO专题

    想学习MXNet的同学建议看一看这位博主的博客,受益良多. 在本节中,我们将学习如何在MXNet中预处理和加载图像数据. 在MXNet中加载图像数据有4种方式. 使用 mx.image.imdecod ...

  7. 『MXNet』第八弹_数据处理API_上

    一.Gluon数据加载 下面的两个dataset处理类一般会成对出现,两个都可做预处理,但是由于后面还可能用到原始图片,.ImageFolderDataset不加预处理的话可以满足,所以建议在.Dat ...

  8. 『MXNet』第十一弹_符号式编程初探

    一.符号分类 符号对我们想要进行的计算进行了描述, 下图展示了符号如何对计算进行描述. 我们定义了符号变量A, 符号变量B, 生成了符号变量C, 其中, A, B为参数节点, C为内部节点! mxne ...

  9. 『MXNet』第七弹_多GPU并行程序设计

    资料原文 一.概述思路 假设一台机器上有个GPU.给定需要训练的模型,每个GPU将分别独立维护一份完整的模型参数. 在模型训练的任意一次迭代中,给定一个小批量,我们将该批量中的样本划分成份并分给每个G ...

随机推荐

  1. [转] J2EE基础知识

    Servlet总结 阐述Servlet和CGI的区别? CGI的不足之处: Servlet的优点: Servlet接口中有哪些方法及Servlet生命周期探秘 get和post请求的区别 什么情况下调 ...

  2. python 之 知识点(1)

    在python是使用bif=built in functions 即内置函数 dir(__builtins__) 可以查看所有的内置函数.注:pycharm中无法使用,不知道原因 help(input ...

  3. Shiro学习笔记(二)

    首先还是先搭建工程运行环境  依旧搭建的是Maven工程,如果不是Maven 也可以去网上找jar包然后导入 (我使用Maven主要是找依赖配置文件就行,我自己导jar包的时候就是很容易报错) 还是先 ...

  4. pgAdmin的数据恢复

    DOC 本地添加server 1.设置备份.恢复的exe路径.一般在pgAdmin的安装路径下可以找到 2.恢复restore,备份backup

  5. 1st,Python基础——01

    1 Python介绍 2 Python发展史 3 Python2 or 3? 4 Python安装 就不写了,各路大牛的博客都很详细. 5 Hello World程序 #!/usr/bin/env p ...

  6. C++通过jsoncpp类库读写JSON文件-json用法详解

    介绍: JSON 是常用的数据的一种格式,各个语言或多或少都会用的JSON格式. JSON是一个轻量级的数据定义格式,比起XML易学易用,而扩展功能不比XML差多少,用之进行数据交换是一个很好的选择. ...

  7. JAVA中char和String/值类型和引用类型的区别

    import java.util.*; class test { public static void main(String[] args) { char a[] = {'b', 'a', 'c'} ...

  8. linux运行lnmp 出现502错误

    之前遇到的问题: 安装好之后访问域名出现502错误,打开html文件正常,说明是php出现问题.在wwwlog文件夹查看nginx日志,发现报错原因是找不到/var/run/php5-fpm.sock ...

  9. hdu 3864 D_num Pollard_rho算法和Miller_Rabin算法

    D_num Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Problem De ...

  10. node.js中的http.response.end方法使用说明

    转载自:http://m.jb51.net/article/58468.htm 本文介绍了http.response.end的方法说明.语法.接收参数.使用实例和实现源码,需要的朋友可以参考下 方法说 ...