跳转至

多层感知机

块级架构

模型定义

事实证明,研究讨论“比单个层大”但“比整个模型小”的组件更有价值。

为了实现这些复杂的网络,可以引入神经网络块的概念。 块(block)可以描述单个层、由多个层组成的组件或整个模型本身。

class FixedHiddenMLP(nn.Module):
    def __init__(self):
        super().__init__()
        # 不计算梯度的随机权重参数。因此其在训练期间保持不变
        self.rand_weight = torch.rand((20, 20), requires_grad=False)
        self.linear = nn.Linear(20, 20)

    def forward(self, X):
        X = self.linear(X)
        # 使用创建的常量参数以及relu和mm函数
        X = F.relu(torch.mm(X, self.rand_weight) + 1)
        # 复用全连接层。这相当于两个全连接层共享参数
        X = self.linear(X)
        # 控制流
        while X.abs().sum() > 1:
            X /= 2
        return X.sum()

一个典型的块以类为实现方式,它至少需要具有初始化和前向传播两个属性

使用super().__init__()继承模版,模板可以使用nn.Module或nn.Block

可以使用requires_grad=False取不变的参数,也可以使用self.register_buffer("p", p)

参数管理

对某一层,使用net.state_dict()访问其参数,参数名称允许唯一标识每个参数

层的参数都是参数类的一个实例,使用.data访问具体数据

同时可以通过应用函数来自定义初始化

def init_constant(m):
    if type(m) == nn.Linear:
        nn.init.constant_(m.weight, 1)
        nn.init.zeros_(m.bias)
net.apply(init_constant)
net[0].weight.data[0], net[0].bias.data[0]

在一个块中多次引用已定义的块,可以实现参数共享

当参数绑定时,每次反向传播的梯度会多次累加