《动手学深度学习》mxnet版/第四章学习笔记

第四章

概括深度学习计算的各个重要组成部分,如模型构造、参数的访问和初始化等,自定义层,读取、存储和 使用GPU

  • 模型构造
  • 模型参数的访问、初始化和共享
  • 读写Gluon模型的参数

模型构造

Block类是nn模块里提供的一个模型构造类,可以继承它来定义我们想要的模型。

#这里定义的MLP类重载了Block类的__init__函 数和forward函数。它们分别用于创建模型参数和定义前向计算
from mxnet import nd 
from mxnet.gluon import nn 
class MLP(nn.Block): 
    # 声明带有模型参数的层,这里声明了两个全连接层 
    def __init__(self, **kwargs): 
    # 调用MLP父类Block的构造函数来进行必要的初始化。这样在构造实例时还可以指定其他函数 
    # 参数,如“模型参数的访问、初始化和共享”一节将介绍的模型参数
    super(MLP, self).__init__(**kwargs) 
    self.hidden = nn.Dense(256, activation='relu')# 隐藏层 
    self.output = nn.Dense(10) # 输出层 
    
    # 定义模型的前向计算,即如何根据输入x计算返回所需要的模型输出 
    def forward(self, x): 
        return self.output(self.hidden(x)) 
#实现一个与Sequential类有相同功能的MySequential类
class MySequential(nn.Block): 
    def __init__(self, **kwargs): 
        super(MySequential, self).__init__(**kwargs)
        
    def add(self, block):
    # block是一个Block子类实例,假设它有一个独一无二的名字。我们将它保存在Block类的 
    # 成员变量_children里,其类型是OrderedDict。当MySequential实例调用 
    # initialize函数时,系统会自动对_children里所有成员初始化 
    self._children[block.name] = block def forward(self, x): 
    # OrderedDict保证会按照成员添加时的顺序遍历成员 
    for block in self._children.values(): 
        x = block(x) 
    return x 
    
# 使用起来与Sequential差不多    
net = MySequential() 
net.add(nn.Dense(256, activation='relu')) 
net.add(nn.Dense(10)) 
net.initialize() 
net(X) 

模型参数的访问、初始化和共享

在有些情况下,我们希望在多个层之间共享模型参数

#让模型的第二隐藏层(shared变量)和第三隐藏层共享模型参数
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()
#在构造第三隐藏层时通过params来指定它使用第二隐藏层的参数。因为模型参数里包含了 梯度, 所以在反向传播计算时, 第二隐藏层和第三隐藏层的梯度都会被累加在shared.params.grad()里

读写Gluon模型的参数

Gluon的Block类提供了save_parameters函数和load_parameters函数来读写模型参数。

class MLP(nn.Block): 
    def __init__(self, **kwargs): 
        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))
        
net = MLP() 
net.initialize() 
X = nd.random.uniform(shape=(2, 20)) 
Y = net(X) 
#把该模型的参数存成文件,文件名为mlp.params
filename = 'mlp.params' net.save_parameters(filename) 
#再实例化一次定义好的多层感知机。与随机初始化模型参数不同,我们在这里直接 读取保存在文件里的参数
net2 = MLP() 
net2.load_parameters(filename) 
#因为这两个实例都有同样的模型参数,那么对同一个输入X的计算结果将会是一样的
Y2 = net2(X) 
Y2 == Y 
posted @ 2020-08-20 22:33  wulionce  阅读(246)  评论(0编辑  收藏  举报