首页 > 其他 > 详细

Gluon parameters 和 Blocks 命名

时间:2020-06-05 21:16:28      阅读:45      评论:0      收藏:0      [点我收藏+]

API:gluon中每个Parameters或者Block都有前缀prefix,Parameters的名字由用户指定,Block的名字可以由用户指定或自动生成。

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

 

Naming Blocks

创建Block时可以手动施加前缀:

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

mydense_

 

当不给定前缀时,gluon会自动生成:

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

dense0_

 

当创建更多同类型的Blocks时,会自动递增前缀名以免冲突:

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

dense1_

 

Naming Parameters

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>)
)

 

Name scopes

要管理嵌套Block的名称,每个Block都附加一个名称范围name_scope。在名称作用域内创建的所有块的名称前都会加上其父块的前缀。

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 = 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进行实例化,则也会进行递增前缀以免冲突:

model1 = Model()
print(model1.prefix)
print(model1.dense0.prefix)
print(model1.dense1.prefix)
print(model1.mydense.prefix)

model1_ model1_dense0_ model1_dense1_ model1_mydense_

 

强烈推荐手动在最高level的Block指定前缀,例如:model=Molde(prefix=‘mymodel_’)。

以上原则适用于所有的container:

技术分享图片

并且name_scope可以用在__init__里,或者__init__外面,像这样:

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_

 

Saving and loading

由于上面定义的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的参数,想load进model1,那么由于名字不匹配,就可能导致load失败:

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_params 和 save/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]

 

 

Replacing Blocks from networks and fine-tuning

将预训练模型的output为1000类,改为100类的分类层:

alexnet = gluon.model_zoo.vision.alexnet(pretrained=True)
print(alexnet.output)
print(alexnet.output.prefix)
Dense(4096 -> 1000, linear)
alexnet0_dense2_

更改分类层:

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_

 

Gluon parameters 和 Blocks 命名

原文:https://www.cnblogs.com/king-lps/p/13051413.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!