MXNet中含有init包,它包含了多种模型初始化方法。

from mxnet import init, nd
from mxnet.gluon import nn net = nn.Sequential()
net.add(nn.Dense(256, activation='relu'))
net.add(nn.Dense(10))
net.initialize() x = nd.random.uniform(shape=(2,20))
y = net(x)

一、访问模型参数

我们知道可以通过[]来访问Sequential类构造出来的网络的特定层。对于带有模型参数的层,我们可以通过Block类的params属性来得到它包含的所有参数。例如我们查看隐藏层的参数:

print(net[0].params)
print(net[0].collect_params())
dense0_ (
Parameter dense0_weight (shape=(256, 20), dtype=float32)
Parameter dense0_bias (shape=(256,), dtype=float32)
)
dense0_ (
Parameter dense0_weight (shape=(256, 20), dtype=float32)
Parameter dense0_bias (shape=(256,), dtype=float32)
)

有意思的是,

print(net.params)
print(net.collect_params())
sequential0_ (

)
sequential0_ (
Parameter dense0_weight (shape=(256, 20), dtype=float32)
Parameter dense0_bias (shape=(256,), dtype=float32)
Parameter dense1_weight (shape=(10, 256), dtype=float32)
Parameter dense1_bias (shape=(10,), dtype=float32)
)

为了访问特定参数,我们既可以通过名字来访问字典里的元素,也可以直接使用它的变量名。下面两种方法是等价的,但通常后者的代码可读性更好,

(net[0].params['dense0_weight'], net[0].weight)

(Parameter dense0_weight (shape=(256, 20), dtype=float32),

Parameter dense0_weight (shape=(256, 20), dtype=float32))

Parameter类

具有方法:.data()/.grad()/.set_data()/.initialize()……
其包含参数权重和它对应的梯度,它们可以分别通过data和grad函数来访问:

net[0].weight.data()
net[0].weight.grad()

声明方法一

至于Parameter类,是指mxnet.gluon.Parameter,声明需要名字和尺寸:

my_param = gluon.Parameter('exciting_parameter_yay', shape=(3, 3))
my_param.initialize()

声明方法二

我们还可以使用Block自带的ParameterDict类的成员变量params。顾名思义,这是一个由字符串类型的参数名字映射到Parameter类型的模型参数的字典。

我们可以通过get函数从ParameterDict创建Parameter,同样的声明需要名字和尺寸:

params = gluon.ParameterDict()
params.get("param2", shape=(2, 3))
params
(
Parameter param2 (shape=(2, 3), dtype=<class 'numpy.float32'>)
)

形如net.params返回的就是一个ParameterDict类,自己的层class书写时,就是用这个方式创建参数并被层class感知(收录进层隶属的ParameterDict类中)。

二、初始化模型参数

当使用默认的模型初始化,Gluon会将权重参数元素初始化为[-0.07, 0.07]之间均匀分布的随机数,偏差参数则全为0. 但经常我们需要使用其他的方法来初始话权重,MXNet的init模块里提供了多种预设的初始化方法。例如下面例子我们将权重参数初始化成均值为0,标准差为0.01的正态分布随机数。

# 非首次对模型初始化需要指定 force_reinit
net.initialize(init=init.Normal(sigma=0.01), force_reinit=True)
  • mxnet.init模块
  • force_reinit为了防止用户失误将参数全部取消

自定义初始化函数

有时候我们需要的初始化方法并没有在init模块中提供,这时我们有两种方法来自定义参数初始化。

一种是实现一个Initializer类的子类

使得我们可以跟前面使用init.Normal那样使用它。在这个方法里,我们只需要实现_init_weight这个函数,将其传入的NDArray修改成需要的内容。下面例子里我们把权重初始化成[-10,-5]和[5,10]两个区间里均匀分布的随机数,教程只讲了weight初始化,后面查看源码还有bias的,以及一些其他的子方法,理论上用时再研究,不过方法二明显更简单易用……

class MyInit(init.Initializer):
def _init_weight(self, name, data):
print('Init', name, data.shape)
data[:] = nd.random.uniform(low=-10, high=10, shape=data.shape)
data *= data.abs() >= 5 net.initialize(MyInit(), force_reinit=True)
net[0].weight.data()[0]
Init dense0_weight (256, 20)
Init dense1_weight (10, 256)
[-5.36596727  7.57739449  8.98637581 -0.          8.8275547   0.
5.98405075 -0. 0. 0. 7.48575974 -0. -0.
6.89100075 6.97887039 -6.11315536 0. 5.46652031 -9.73526287
9.48517227]
<NDArray 20 @cpu(0)>

第二种方法是我们通过Parameter类的set_data函数

可以直接改写模型参数。例如下例中我们将隐藏层参数在现有的基础上加1.

net[0].weight.set_data(net[0].weight.data()+1)
net[0].weight.data()[0]
[ -4.36596727   8.57739449   9.98637581   1.           9.8275547    1.
6.98405075 1. 1. 1. 8.48575974 1. 1.
7.89100075 7.97887039 -5.11315536 1. 6.46652031
-8.73526287 10.48517227]
<NDArray 20 @cpu(0)>

三、共享模型参数

在有些情况下,我们希望在多个层之间共享模型参数。我们在“模型构造”这一节看到了如何在Block类里forward函数里多次调用同一个类来完成。这里将介绍另外一个方法,它在构造层的时候指定使用特定的参数。如果不同层使用同一份参数,那么它们不管是在前向计算还是反向传播时都会共享共同的参数。

原理:层函数params API接收其他层函数的params属性即可

在下面例子里,我们让模型的第二隐藏层和第三隐藏层共享模型参数:

from mxnet import nd
from mxnet.gluon import nn net = nn.Sequential()
shared = nn.Dense(8, activation='relu')
net.add(nn.Dense(8, activation='relu'),
shared,
nn.Dense(8, activation='relu', params=shared.params),
nn.Dense(10))
net.initialize() x = nd.random.uniform(shape=(2,20))
net(x) net[1].weight.data()[0] == net[2].weight.data()[0]

[ 1. 1. 1. 1. 1. 1. 1. 1.]

<NDArray 8 @cpu(0)>

我们在构造第三隐藏层时通过params来指定它使用第二隐藏层的参数。由于模型参数里包含了梯度,所以在反向传播计算时,第二隐藏层和第三隐藏层的梯度都会被累加在shared.params.grad()里。

四、模型延后初始化

从下面jupyter可以看到模型参数实际初始化的时机:既不是调用initialize时,也不是没次运行时,仅仅第一次送入数据运行时会调用函数进行参数初始化,所以MXNet不需要定义指定输入数据尺寸的关键也在这里。

立即初始化参数

基于以上,当模型获悉数据尺寸时不会发生延后,

  • 已经运行过,指定重新初始化时不会延后
  • 定义过程中,指定in_units的模型不会延后

代码如下,

最后一格代码块中,第二个dense层去掉in_uints的话仅仅第一个dense会立即初始化。

数据形状改变时网络行为

如果在下一次net(x)前改变x形状,包括批量大小和特征大小,会发生什么?

批量大小改变不影响,特征大小改变会报错。

『MXNet』第三弹_Gluon模型参数的更多相关文章

  1. 『MXNet』第四弹_Gluon自定义层

    一.不含参数层 通过继承Block自定义了一个将输入减掉均值的层:CenteredLayer类,并将层的计算放在forward函数里, from mxnet import nd, gluon from ...

  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』第三弹重置_Variable对象

    『PyTorch』第三弹_自动求导 torch.autograd.Variable是Autograd的核心类,它封装了Tensor,并整合了反向传播的相关实现 Varibale包含三个属性: data ...

  5. 关于『HTML』:第三弹

    关于『HTML』:第三弹 建议缩放90%食用 盼望着, 盼望着, 第三弹来了, HTML基础系列完结了!! 一切都像刚睡醒的样子(包括我), 欣欣然张开了眼(我没有) 敬请期待Markdown语法系列 ...

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

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

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

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

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

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

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

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

随机推荐

  1. 外观模式Facade pattern

    http://www.runoob.com/design-pattern/facade-pattern.html 外观模式 外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一 ...

  2. 【问题解决】连接mysql 8错误:authentication plugin 'caching_sha2_password

    在刚安装好mysql8,使用native连接的时候报错 authentication plugin 'caching_sha2_password'... 首先确保服务已开启,然后通过cmd命令进入my ...

  3. Java 多线程案例

    同步代码块 SynchronizedTest类,用来表示取票功能 package concurency.chapter6; public class SynchronizedTest implemen ...

  4. hash进阶:使用字符串hash乱搞的姿势

    前言 此文主要介绍hash的各种乱搞方法,hash入门请参照我之前这篇文章 不好意思hash真的可以为所欲为 在开头先放一下题表(其实就是我题解中的hash题目qwq) 查询子串hash值 必备的入门 ...

  5. Bytom设计结构解读

    一.引文 设计Bytom 数据结构,组合了许多技术点,如 patricia tree,utxo, bvm, account model,protobuf,sql,memcache 等.本文会对一些技术 ...

  6. 【ASP.NET】 MVC下拉框联动

    这个case主要是我在做项目的时候遇到一个需要根据input控件输入的内容,动态填充dropdown list中的内容, 实现二者联动的需求.在搜索了一些资源后,这篇博客解决了我的问题,所以记录并转载 ...

  7. VS 编译后 install报错(error MSB3073)

    vs编译出现如下错误: 错误 1 error MSB3073: 命令"setlocal H:\PCL_BACKUP\PCL\CMake\bin\cmake.exe -DBUILD_TYPE= ...

  8. IIS7.5 错误代码0x8007007e HTTP 错误 500.19 - Internal Server Error

    今天在win2008+IIS7.5的环境中部署WCF服务后,一直出现无法打开的页面.具体错误信息如下: HTTP 错误 500.19 - Internal Server Error 无法访问请求的页面 ...

  9. ES6中Promise的入门(结合例子)

    一.Promise的前言 解决回调地狱 //以往回调方式 函数1(function(){ //代码执行...(ajax1) 函数2(function(){ //代码执行...(ajax2) 函数3(f ...

  10. Intent 类型

    Intent 分为两种类型: 显式 Intent:按名称(完全限定类名)指定要启动的组件. 通常,您会在自己的应用中使用显式 Intent 来启动组件,这是因为您知道要启动的 Activity 或服务 ...