深度学习入门指南:从BP神经网络到残差网络的实战演进

1次阅读
没有评论

共计 2683 个字符,预计需要花费 7 分钟才能阅读完成。

image.webp

不同神经网络的应用场景

假设我们要处理两个实际问题:

深度学习入门指南:从 BP 神经网络到残差网络的实战演进

  1. 股票价格预测 :这是一个典型的时序预测问题,需要模型能够记住历史数据的趋势。循环神经网络(RNN)因其具有记忆功能,能够很好地处理这种具有时间依赖性的数据。

  2. 手写数字识别 :这是一个图像分类问题,BP 神经网络和残差网络(ResNet)都能胜任。但 ResNet 通过跳跃连接解决了深层网络梯度消失的问题,在更复杂的图像任务中表现更好。

技术对比

1. BP 神经网络基础结构

BP 神经网络由输入层、隐藏层和输出层组成。其前向传播过程可以用以下数学表达式描述:

$$
z^{(l)} = W^{(l)}a^{(l-1)} + b^{(l)}
$$
$$
a^{(l)} = \sigma(z^{(l)})
$$

其中 $\sigma$ 是激活函数,常用 ReLU 或 Sigmoid。

2. RNN 的时序处理机制

RNN 通过循环连接处理序列数据,其核心公式为:

$$
h_t = \sigma(W_{hh}h_{t-1} + W_{xh}x_t + b_h)
$$
$$
y_t = W_{hy}h_t + b_y
$$

这种结构使得网络能够保留之前时间步的信息。

3. ResNet 的跳跃连接

ResNet 通过引入跳跃连接解决了深度网络中的梯度消失问题:

$$
F(x) = H(x) – x
$$
$$
H(x) = F(x) + x
$$

这种结构使得深层网络能够被有效训练。

PyTorch 实现 MNIST 分类

数据预处理

import torch
from torchvision import datasets, transforms

# 数据预处理
transform = transforms.Compose([transforms.ToTensor(),
    transforms.Normalize((0.1307,), (0.3081,))
])

train_dataset = datasets.MNIST('./data', train=True, download=True, transform=transform)
test_dataset = datasets.MNIST('./data', train=False, transform=transform)

# 数据加载器
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=1000, shuffle=False)

BP 神经网络实现

import torch.nn as nn
import torch.nn.functional as F

class BPNet(nn.Module):
    def __init__(self):
        super(BPNet, self).__init__()
        self.fc1 = nn.Linear(784, 128)
        self.fc2 = nn.Linear(128, 10)

    def forward(self, x):
        x = x.view(-1, 784)  # 展平输入
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return F.log_softmax(x, dim=1)

RNN 实现

class RNN(nn.Module):
    def __init__(self):
        super(RNN, self).__init__()
        self.rnn = nn.RNN(28, 128, batch_first=True)
        self.fc = nn.Linear(128, 10)

    def forward(self, x):
        x = x.squeeze(1)  # [batch, 1, 28, 28] -> [batch, 28, 28]
        x = x.permute(0, 2, 1)  # [batch, 28, 28] -> [batch, 28, 28]
        out, _ = self.rnn(x)
        out = self.fc(out[:, -1, :])
        return F.log_softmax(out, dim=1)

ResNet 实现

class ResBlock(nn.Module):
    def __init__(self, in_channels):
        super(ResBlock, self).__init__()
        self.conv1 = nn.Conv2d(in_channels, in_channels, kernel_size=3, padding=1)
        self.conv2 = nn.Conv2d(in_channels, in_channels, kernel_size=3, padding=1)

    def forward(self, x):
        residual = x
        out = F.relu(self.conv1(x))
        out = self.conv2(out)
        out += residual
        return F.relu(out)

class ResNet(nn.Module):
    def __init__(self):
        super(ResNet, self).__init__()
        self.conv1 = nn.Conv2d(1, 16, kernel_size=3, padding=1)
        self.resblock = ResBlock(16)
        self.fc = nn.Linear(16*28*28, 10)

    def forward(self, x):
        x = F.relu(self.conv1(x))
        x = self.resblock(x)
        x = x.view(-1, 16*28*28)
        x = self.fc(x)
        return F.log_softmax(x, dim=1)

避坑指南

1. 梯度消失问题

  • 识别 :训练过程中 loss 不再下降,或者下降非常缓慢
  • 解决
  • 使用 ReLU 激活函数代替 Sigmoid
  • 使用批量归一化 (BatchNorm)
  • 使用残差连接

2. 超参数设置

  • 学习率:一般从 0.001 开始尝试
  • 批量大小:常用 32/64/128
  • 网络深度:从浅层开始逐步增加

3. 训练监控

  • 训练集和验证集的 loss 曲线
  • 准确率变化
  • 梯度变化情况

思考题

  1. 如何根据业务场景特征选择网络类型?
  2. 时序数据优先考虑 RNN 或 LSTM
  3. 图像数据考虑 CNN 或 ResNet
  4. 简单结构化数据可以使用 BP 网络

  5. 在小样本情况下如何调整网络结构?

  6. 减少网络层数和神经元数量
  7. 使用数据增强
  8. 添加正则化项
  9. 使用迁移学习

总结

本文从实际应用场景出发,系统介绍了 BP 神经网络、RNN 和 ResNet 的原理与实现。通过 PyTorch 代码示例展示了三种网络在 MNIST 分类任务上的应用,并提供了训练过程中的调参技巧和常见问题解决方法。希望这些内容能帮助初学者快速掌握不同神经网络的特性和适用场景。

正文完
 0
评论(没有评论)