动手学人工智能-多层感知机3-多层感知机的简洁实现

291 阅读3分钟

在深度学习的世界中,多层感知机(Multilayer Perceptron, MLP)是一种最经典的神经网络结构。它通过叠加隐藏层和激活函数,为模型引入非线性特性,从而能够处理更加复杂的任务。本文我们将探讨如何利用高级 API 简洁地实现一个多层感知机。无论你是初学者还是已有基础,这篇文章都将以通俗易懂的方式带你一步步构建属于自己的多层感知机模型。

1. 模型定义

1.1 模型结构

多层感知机相比于之前的 softmax 回归,多了一层隐藏层。以下是模型的组成部分:

  • 输入层:将 28×28 的图像展平为一个长度为 784 的向量。
  • 隐藏层:包含 256 个隐藏单元,激活函数为 ReLU。
  • 输出层:将隐藏层输出映射到 10 个类别。

以下是使用 PyTorch 高级 API 定义模型的代码:

from torch import nn

# 定义模型
net = nn.Sequential(
    nn.Flatten(),  # 展平输入
    nn.Linear(784, 256),  # 隐藏层
    nn.ReLU(),  # 激活函数
    nn.Linear(256, 10)  # 输出层
)


# 初始化参数
def init_weights(m):
    if type(m) == nn.Linear:
        nn.init.normal_(m.weight, std=0.01)


net.apply(init_weights)

1.2 模型解释

  • nn.Flatten():将二维图像数据展平为一维向量。
  • nn.Linear(784, 256):表示一个全连接层,将输入特征从 784 转换为 256。
  • nn.ReLU():激活函数,用于引入非线性特性。
  • nn.Linear(256, 10):将隐藏层的输出映射到 10 个类别。

1.3 数学公式

  1. 输入数据展平为向量 xR784\mathbf{x} \in \mathbb{R}^{784}
  2. 隐藏层的输出为:
    h=ReLU(W1x+b1)\mathbf{h} = \text{ReLU}(\mathbf{W}_1 \mathbf{x} + \mathbf{b}_1)
  3. 输出层计算分类结果:
    o=W2h+b2\mathbf{o} = \mathbf{W}_2 \mathbf{h} + \mathbf{b}_2

2. 模型训练

2.1 数据加载

我们使用 Fashion-MNIST 数据集,包含 10 类服装图片。以下代码加载数据:

import d2l

batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)

2.2 定义损失函数与优化器

  • 损失函数:使用交叉熵损失函数 CrossEntropyLoss
  • 优化器:采用随机梯度下降法(SGD)。
import torch

loss = nn.CrossEntropyLoss(reduction='none')
trainer = torch.optim.SGD(net.parameters(), lr=0.1)

2.3 模型训练

我们定义了 d2l.train_ch3 (参见前面的文章或 github.com/d2l-ai 函数用于训练和评估模型:

num_epochs = 10
d2l.train_ch3(net, train_iter, test_iter,
              loss, num_epochs, trainer, batch_size)

myplot.png

3. 小结

  • 使用高级 API,我们可以简洁地实现多层感知机。
  • 相比于 softmax 回归,多层感知机增加了一个隐藏层,并引入了激活函数。
  • 多层感知机具有更强的表达能力,适用于更复杂的任务。

完整代码:

import torch
from torch import nn
from d2l import torch as d2l

# 定义模型
net = nn.Sequential(
    nn.Flatten(),
    nn.Linear(784, 256),
    nn.ReLU(),
    nn.Linear(256, 10)
)

# 初始化参数
def init_weights(m):
    if type(m) == nn.Linear:
        nn.init.normal_(m.weight, std=0.01)
net.apply(init_weights)

# 加载数据
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)

# 定义损失函数与优化器
loss = nn.CrossEntropyLoss(reduction='none')
trainer = torch.optim.SGD(net.parameters(), lr=0.1)

# 训练模型
num_epochs = 10
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)

多层感知机的引入,标志着神经网络从简单的线性模型迈向更高的复杂度和表达能力。通过本文的学习,我们不仅掌握了多层感知机的基本原理和实现方法,还体验了高级 API 带来的便捷性。在未来的学习中,这种模块化、简洁的开发方式将帮助我们快速探索更复杂的深度学习模型。从 MLP 开始,让我们继续解锁深度学习的更多可能性!