Python Gluon参数和模块命名操作教程


Posted in Python onDecember 18, 2019

本文实例讲述了Python Gluon参数和模块命名操作。分享给大家供大家参考,具体如下:

Gluon参数和模块命名教程

在gluon里,每个参数和块都有一个名字(和前缀)。参数名可以由用户指定,block名也可以由用户指定,也可以自动创建。

本教程中,我们将讨论命名方面的最佳实践。首先,import MXNet和Gluon

from __future__ import print_function
import mxnet as mx
from mxnet import gluon

Blocks命名

在创建block时,可以指定一个前缀给它:

mydense = gluon.nn.Dense(100, prefix='mydense_')
print(mydense.prefix)
mydense_

若没有指定前缀,gluon会自动生成一个前缀

dense0 = gluon.nn.Dense(100)
print(dense0.prefix)
dense0_

当你创建更多同类块时,它们将递增后缀命名,以避免冲突:

dense1 = gluon.nn.Dense(100)
print(dense1.prefix)
dense1_

参数命名

blocks中的参数将用过将block的前缀添加到参数的名称来命名:

print(dense0.collect_params())
dense0_ (
 Parameter dense0_weight (shape=(100, 0), dtype=<type 'numpy.float32'>)
 Parameter dense0_bias (shape=(100,), dtype=<type 'numpy.float32'>)
)

名称空间

为了管理嵌套block的名称,每个块附加有一个name_scope(名称空间)。在name_scope中创建的block都会在其名称前加上父block的名称。

我们将定义一个简单的神经网络来说明这点:

class Model(gluon.Block):
 def __init__(self, **kwargs):
  super(Model, self).__init__(**kwargs)
  with self.name_scope():
   self.dense0 = gluon.nn.Dense(20)
   self.dense1 = gluon.nn.Dense(20)
   self.mydense = gluon.nn.Dense(20, prefix='mydense_')
 def forward(self, x):
  x = mx.nd.relu(self.dense0(x))
  x = mx.nd.relu(self.dense1(x))
  return mx.nd.relu(self.mydense(x))

现在实例化这个神经网络

  • 注意:model0.dense0的名称是model0_dense0_而非dense0_
  • 注意:我们指定model.mydense的前缀为mydense_,它的父类前缀会自动生成并添加到前面变成model0_mydense_

这里的名称前缀和变量名model0没有关系,这里就算把model0换成其他变量名比如net,前缀还是model?,? 表示这是一个递增的数字,这里的名称前缀和class Model有关 若将类名Model换成Hodel,那么后面的前缀都会变成 hodel?

model0 = Model()
model0.initialize()
model0(mx.nd.zeros((1, 20)))
print(model0.prefix)
print(model0.dense0.prefix)
print(model0.dense1.prefix)
print(model0.mydense.prefix)
model0_
model0_dense0_
model0_dense1_
model0_mydense_

若我们再次实例化Model,在Dense前会生成一个不同的名称。

  • 注意:model1.dense0的名称依然是dense0_而非dense2_,遵循之前在model0中创建的dense层的命名规则。这是因为每个model的命名空间是相互独立
model1 = Model()
print(model1.prefix)
print(model1.dense0.prefix)
print(model1.dense1.prefix)
print(model1.mydense.prefix)
model1_
model1_dense0_
model1_dense1_
model1_mydense_

建议手动为顶层的model指定一个前缀,即model = Model(prefix=‘mymodel_'),以避免命名时可能出现的混淆。

相同的规则同样适用于像Sequential这类容器block.name_scope 既可以在__init__内使用,也可以在__init__ 外使用:

注意:这里Sequential也有参数prefix,是可以自己指定名称的,不指定的话就叫Sequential

net = gluon.nn.Sequential()
with net.name_scope():
 net.add(gluon.nn.Dense(20))
 net.add(gluon.nn.Dense(20))
print(net.prefix)
print(net[0].prefix)
print(net[1].prefix)
sequential0_
sequential0_dense0_
sequential0_dense1_

gluon.model_zoo也一样

net = gluon.nn.Sequential()
with net.name_scope():
 net.add(gluon.model_zoo.vision.alexnet(pretrained=True))
 net.add(gluon.model_zoo.vision.alexnet(pretrained=True))
print(net.prefix, net[0].prefix, net[1].prefix)
sequential1_ sequential1_alexnet0_ sequential1_alexnet1_

保存和载入

由于model0和model1有不同的前缀,所以它们的参数是有不同名字的:

print(model0.collect_params(), '\n')
print(model1.collect_params())
model0_ (
 Parameter model0_dense0_weight (shape=(20L, 20L), dtype=<type 'numpy.float32'>)
 Parameter model0_dense0_bias (shape=(20L,), dtype=<type 'numpy.float32'>)
 Parameter model0_dense1_weight (shape=(20L, 20L), dtype=<type 'numpy.float32'>)
 Parameter model0_dense1_bias (shape=(20L,), dtype=<type 'numpy.float32'>)
 Parameter model0_mydense_weight (shape=(20L, 20L), dtype=<type 'numpy.float32'>)
 Parameter model0_mydense_bias (shape=(20L,), dtype=<type 'numpy.float32'>)
) 
model1_ (
 Parameter model1_dense0_weight (shape=(20, 0), dtype=<type 'numpy.float32'>)
 Parameter model1_dense0_bias (shape=(20,), dtype=<type 'numpy.float32'>)
 Parameter model1_dense1_weight (shape=(20, 0), dtype=<type 'numpy.float32'>)
 Parameter model1_dense1_bias (shape=(20,), dtype=<type 'numpy.float32'>)
 Parameter model1_mydense_weight (shape=(20, 0), dtype=<type 'numpy.float32'>)
 Parameter model1_mydense_bias (shape=(20,), dtype=<type 'numpy.float32'>)
)

若你尝试将model0的参数载入到model1中,你将会得到一个名称不匹配的错误

model0.collect_params().save('model.params')
try:
 model1.collect_params().load('model.params', mx.cpu())
except Exception as e:
 print(e)

Parameter 'model1_dense0_weight' is missing in file 'model.params', which contains parameters: 'model0_mydense_weight', 'model0_dense1_bias', 'model0_dense1_weight', 'model0_dense0_weight', 'model0_dense0_bias', 'model0_mydense_bias'. Please make sure source and target networks have the same prefix.

为了解决这个问题,我们使用save_parameters/load_parameters而不是 collect_paramssave/load. save_parameters。使用模型结构而非参数名称来匹配参数。

model0.save_parameters('model.params')
model1.load_parameters('model.params')
print(mx.nd.load('model.params').keys())
['dense0.bias', 'mydense.bias', 'dense1.bias', 'dense1.weight', 'dense0.weight', 'mydense.weight']

替换网络中的block并进行fine-turning

有时需要加载一些预训练的模型,并替换其中某些block并进行fine-turning。

For example, the alexnet in model zoo has 1000 output dimensions, but maybe you only have 100 classes in your application.

例如,alexnet有1000个输出维度但你只有100类。

我们首先载入预训练的AlexNet

  • 在Gluon Model Zoo,所有图像分类模型的格式都是特征提取层叫 features ,输出层叫 output.
  • 注意到输出层是一个dense block,有1000个维度的输出
alexnet = gluon.model_zoo.vision.alexnet(pretrained=True)
print(alexnet.output)
print(alexnet.output.prefix)
Dense(4096 -> 1000, linear)
alexnet0_dense2_

改变输出为100维,使用一个新block替换它

with alexnet.name_scope():
 alexnet.output = gluon.nn.Dense(100)
alexnet.output.initialize()
print(alexnet.output)
print(alexnet.output.prefix)
Dense(None -> 100, linear)
alexnet0_dense3_

原文:http://mxnet.incubator.apache.org/versions/master/tutorials/gluon/naming.html

更多关于Python相关内容可查看本站专题:《Python数学运算技巧总结》、《Python图片操作技巧总结》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》及《Python入门与进阶经典教程》

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
分析用Python脚本关闭文件操作的机制
Jun 28 Python
初步剖析C语言编程中的结构体
Jan 16 Python
python 使用get_argument获取url query参数
Apr 28 Python
python中requests使用代理proxies方法介绍
Oct 25 Python
python中实现将多个print输出合成一个数组
Apr 19 Python
python实现微信自动回复及批量添加好友功能
Jul 03 Python
解决Django layui {{}}冲突的问题
Aug 29 Python
Python3将数据保存为txt文件的方法
Sep 12 Python
python3.7 openpyxl 删除指定一列或者一行的代码
Oct 08 Python
pycharm双击无响应(打不开问题解决办法)
Jan 10 Python
关于Python错误重试方法总结
Jan 03 Python
详解matplotlib中pyplot和面向对象两种绘图模式之间的关系
Jan 22 Python
python turtle 绘制太极图的实例
Dec 18 #Python
Python使用gluon/mxnet模块实现的mnist手写数字识别功能完整示例
Dec 18 #Python
简单了解Python读取大文件代码实例
Dec 18 #Python
python 比较2张图片的相似度的方法示例
Dec 18 #Python
使用Python的Turtle库绘制森林的实例
Dec 18 #Python
python3 requests库实现多图片爬取教程
Dec 18 #Python
在notepad++中实现直接运行python代码
Dec 18 #Python
You might like
第1次亲密接触PHP5(2)
2006/10/09 PHP
PHP新手用的Insert和Update语句构造类
2012/03/31 PHP
使用ThinkPHP生成缩略图及显示
2017/04/27 PHP
对于Laravel 5.5核心架构的深入理解
2018/02/22 PHP
js实现ASP分页函数 HTML分页函数
2006/09/22 Javascript
改写一个简单的菜单 弹性大小
2010/12/02 Javascript
目前流行的JavaScript库的介绍及对比
2013/09/29 Javascript
用JavaScript实现用一个DIV来包装文本元素节点
2014/09/09 Javascript
JavaScript数据结构和算法之图和图算法
2015/02/11 Javascript
Js与Jq 获取页面元素值的方法和差异对比
2015/04/30 Javascript
浅谈js构造函数的方法与原型prototype
2016/07/04 Javascript
jQuery中的insertBefore(),insertAfter(),after(),before()区别介绍
2016/09/01 Javascript
jQuery表单元素选择器代码实例
2017/02/06 Javascript
vue axios同步请求解决方案
2017/09/29 Javascript
基于jQuery Ajax实现下拉框无刷新联动
2017/12/06 jQuery
vue中如何实现pdf文件预览的方法
2018/07/12 Javascript
vue中的自定义分页插件组件的示例
2018/08/18 Javascript
如何在Vue项目中添加接口监听遮罩
2021/01/25 Vue.js
[40:03]RNG vs VG 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
Python编码时应该注意的几个情况
2013/03/04 Python
使用python实现递归版汉诺塔示例(汉诺塔递归算法)
2014/04/08 Python
详解Django中的form库的使用
2015/07/18 Python
Python字典数据对象拆分的简单实现方法
2017/12/05 Python
基于windows下pip安装python模块时报错总结
2018/06/12 Python
Python 经典面试题 21 道【不可错过】
2018/09/21 Python
在python里面运用多继承方法详解
2019/07/01 Python
浅析HTML5的WebSocket与服务器推送事件
2016/02/19 HTML / CSS
英国浴室洗脸盆购物网站:Click Basin
2018/06/08 全球购物
Can a struct inherit from another struct? (结构体能继承结构体吗)
2016/09/25 面试题
总经理秘书岗位职责
2014/03/17 职场文书
教师节倡议书
2014/08/30 职场文书
简单的个人租房协议书范本
2014/11/26 职场文书
2015年学校安全工作总结
2015/04/22 职场文书
护士长2015年终工作总结
2015/04/24 职场文书
小学英语教学经验交流材料
2015/11/02 职场文书
golang 实现菜单树的生成方式
2021/04/28 Golang