Datawhale AI 夏令营(第五期)——向李宏毅学深度学习(进阶)——3

Task3:《深度学习详解》笔记

提示:此处为作者对学习内容的简析和总结



提示:以下是本篇文章正文内容

批量归一化

批量归一化的概念与原理

批量归一化(Batch Normalization, BN)是一种在深度学习中用于加速网络训练并稳定模型性能的技术。其核心思想是通过对网络中间层的激活值进行归一化处理,从而缓解梯度消失或爆炸的问题,尤其是在深层神经网络中。

在深度学习中,网络的各层输出通常会经历非常大的数值变化,导致后续层的梯度更新不稳定,进而影响模型的收敛速度和最终性能。批量归一化通过对每一批次的训练样本计算均值和方差,将数据归一化为均值为0、方差为1的标准正态分布,来稳定网络的训练过程。

归一化的具体公式如下:
x ^ i = x i − μ B σ B 2 + ϵ \hat{x}_i = \frac{x_i - \mu_B}{\sqrt{\sigma_B^2 + \epsilon}} x^i=σB2+ϵ xiμB

其中,𝜇𝐵和 𝜎2𝐵分别是当前批次样本的均值和方差,𝜖是一个很小的常数,用于避免分母为零。

批量归一化的优势

批量归一化不仅提高了网络的训练速度,还允许我们使用更高的学习率,因为归一化后的数据更稳定,不容易导致梯度爆炸。同时,BN 还具有一定的正则化效果,能够在一定程度上减轻过拟合,从而提高模型的泛化能力。

在深度学习的训练过程中,批量归一化能够显著改变损失函数的表面形态,使得损失函数的表面更为平滑,这样梯度下降的过程也更为顺畅。换句话说,BN 能够将原本崎岖不平的损失函数表面“铲平”,使得优化过程更为高效。

批量归一化在测试时的处理

在训练过程中,批量归一化依赖于每一批次数据的均值和方差,而在测试阶段,模型的输入往往是单个样本或较小的批次,此时直接计算均值和方差并不现实。因此,在测试阶段,BN 使用的是训练阶段的滑动平均值(moving average)作为全局的均值和方差。这种处理方式保证了模型在测试阶段的稳定性,并且避免了因批量大小不同导致的性能波动。

批量归一化的实践应用

在实际应用中,批量归一化已经成为深度学习模型中不可或缺的一个部分。无论是卷积神经网络(CNN)还是循环神经网络(RNN),BN 都被广泛应用,并显著提升了模型的训练速度和性能。近年来,除了标准的 BN,还出现了多种变体,如层归一化(Layer Normalization)、实例归一化(Instance Normalization)和组归一化(Group Normalization),这些方法进一步扩展了归一化技术的应用场景和效果。

卷积神经网络

卷积神经网络的基本概念

卷积神经网络(CNN)是一种广泛应用于图像处理的神经网络架构,它通过卷积操作来捕捉图像中的空间特征。传统的神经网络在处理图像时,通常会将图像的像素展平为一个长向量,然后输入到全连接层中。然而,这种处理方式无法有效捕捉图像的空间结构信息,并且会导致参数数量过多,增加模型过拟合的风险。CNN 通过局部感受野、卷积核和共享参数的设计,解决了这一问题。

图像表示与卷积操作

在 CNN 中,图像通常表示为一个三维张量,分别对应图像的高度、宽度和通道数。对于彩色图像,通道数为 3(即 RGB 三个通道)。卷积操作的目的是通过一个小的卷积核(filter)在图像上滑动,提取局部特征。每一个卷积核在图像上进行点积运算,生成一个特征图(feature map),这可以看作是图像的一个新的表示。

卷积操作的数学表达式可以表示为:
y = ∑ i = 1 n ∑ j = 1 m x [ i , j ] ⋅ k [ i , j ] y = \sum_{i=1}^{n} \sum_{j=1}^{m} x[i,j] \cdot k[i,j] y=i=1nj=1mx[i,j]k[i,j]

其中,𝑥[𝑖,𝑗]表示输入图像的像素值,𝑘[𝑖,𝑗]表示卷积核的权重,𝑦是卷积操作后的输出值。

感受野与卷积核的设计

感受野是指神经元在输入图像上所能看到的区域。在卷积神经网络中,每个神经元只关注输入图像的一小部分(即感受野),通过这种方式,可以有效地减少参数数量,并提高模型的训练效率。

通常,感受野的大小由卷积核的尺寸决定。在图像处理中,常用的卷积核尺寸为 3x3 或 5x5,较小的卷积核能够提取更细致的局部特征,而较大的卷积核则可以捕捉更全局的模式。

参数共享与下采样

卷积神经网络中的一个重要特点是参数共享,即多个神经元可以共享相同的权重,这一设计大大减少了模型的参数数量,从而提高了模型的训练效率。例如,在图像处理中,同一个卷积核可以在不同的图像位置滑动,但依然使用相同的参数。虽然这些神经元共享参数,但由于它们接收的输入不同,输出结果仍然会有所差异。参数共享有效地限制了网络的弹性,使得模型更加专注于特定任务,并且在处理图像这种特定的任务时表现良好。

公式方面,上下两个神经元的输出可以表示为:
σ ( w 1 x 1 + w 2 x 2 + ⋯ + 1 ) \sigma(w_1x_1 + w_2x_2 + \cdots + 1) σ(w1x1+w2x2++1)
σ ( w 1 x 1 ′ + w 2 x 2 ′ + ⋯ + 1 ) \sigma(w_1x'_1 + w_2x'_2 + \cdots + 1) σ(w1x1+w2x2++1)
由于输入不同,尽管参数相同,输出仍会有所差异。

下采样(Pooling)是卷积神经网络中的另一个关键技术。下采样通过对特征图进行降维,将图像缩小至原来的1/4,但依然保留图像的主要特征。下采样常用于减小数据量,同时提升计算效率。常见的下采样方法有最大池化和平均池化。在最大池化操作中,我们在每个子区域内选择最大的值作为代表,而平均池化则是取子区域内的平均值。

卷积层与全连接层的关系

卷积层和全连接层是卷积神经网络的两个核心部分。全连接层具有最大的弹性,可以决定是查看整张图像还是仅查看一个范围。通过调节权重,全连接层能够执行多种任务。然而,这种弹性也带来了模型的复杂性,容易导致过拟合。相比之下,卷积层引入了感受野的概念,使得网络只能查看输入图像的一小部分,并且通过参数共享,进一步限制了网络的弹性。这种设计虽然降低了模型的灵活性,但也减少了模型过拟合的风险。

卷积层与滤波器的作用

卷积层的主要作用是提取图像中的特征,而这一过程是通过应用多个滤波器实现的。滤波器本质上是一组参数,通过卷积操作,它们能够识别图像中的特定模式。例如,一个3×3的滤波器在应用于图像时,会与图像的局部区域进行内积操作,产生一个特征值。这一操作在图像上滑动,形成一个特征映射,这些特征映射可以看作是原始图像的另一种表示形式。

假设我们有一个3×3的滤波器,其卷积操作可以表示为:
y = ∑ i = 1 3 ∑ j = 1 3 x [ i , j ] ⋅ k [ i , j ] y = \sum_{i=1}^{3} \sum_{j=1}^{3} x[i,j] \cdot k[i,j] y=i=13j=13x[i,j]k[i,j]

通过应用多个滤波器,卷积层能够生成多个特征映射,每个特征映射对应一个滤波器。这些特征映射可以进一步用于图像分类或其他视觉任务。

汇聚(池化)层的作用与全卷积网络

汇聚层(Pooling Layer)通常与卷积层配合使用,用于进一步减少特征图的尺寸,同时保留最重要的特征。最大池化是一种常用的汇聚方法,它在每个子区域中选择最大的值作为代表。汇聚层的主要作用是降低计算量,但在一些精细任务中,汇聚可能会丢失重要的信息,因此近年来,全卷积网络(Fully Convolutional Networks, FCN)开始流行,它们完全依赖卷积层,不使用汇聚层,从而保留更多的图像细节。

代码实现

下面的代码实现了一个包含卷积层、批量归一化层、汇聚(池化)层和全连接层的简单的卷积神经网络(CNN)。


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

# 定义一个简单的卷积神经网络
class SimpleCNN(nn.Module):
    def __init__(self):
        super(SimpleCNN, self).__init__()
        # 卷积层1:输入通道为1,输出通道为16,卷积核大小为3x3
        self.conv1 = nn.Conv2d(1, 16, kernel_size=3, padding=1)
        # 批量归一化层1
        self.bn1 = nn.BatchNorm2d(16)
        # 卷积层2:输入通道为16,输出通道为32,卷积核大小为3x3
        self.conv2 = nn.Conv2d(16, 32, kernel_size=3, padding=1)
        # 批量归一化层2
        self.bn2 = nn.BatchNorm2d(32)
        # 全连接层
        self.fc1 = nn.Linear(32*7*7, 128)
        self.fc2 = nn.Linear(128, 10)
        
    def forward(self, x):
        # 卷积层1 -> 批量归一化 -> ReLU -> 最大池化
        x = F.relu(self.bn1(self.conv1(x)))
        x = F.max_pool2d(x, 2)
        # 卷积层2 -> 批量归一化 -> ReLU -> 最大池化
        x = F.relu(self.bn2(self.conv2(x)))
        x = F.max_pool2d(x, 2)
        # 扁平化
        x = x.view(-1, 32*7*7)
        # 全连接层1 -> ReLU
        x = F.relu(self.fc1(x))
        # 全连接层2 -> 输出
        x = self.fc2(x)
        return x

# 初始化模型、损失函数和优化器
model = SimpleCNN()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 模拟训练数据并进行训练
for epoch in range(5): 
    optimizer.zero_grad()
    inputs = torch.randn(64, 1, 28, 28) # 模拟64张28x28的灰度图像
    labels = torch.randint(0, 10, (64,)) # 模拟对应的标签

    # 前向传播
    outputs = model(inputs)
    # 计算损失
    loss = criterion(outputs, labels)
    # 反向传播
    loss.backward()
    # 更新参数
    optimizer.step()

    print(f'Epoch [{epoch+1}/5], Loss: {loss.item():.4f}') 

  • 13
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值