深度学习Day07 Dropout 随机失活 与 Batch Normalization 批量归一化
·
一、前言
在训练深度学习模型时,小白最常遇到两个问题:
❌ 过拟合:训练集效果很好,测试集一塌糊涂
❌ 训练不稳定:loss 波动大,收敛慢甚至不收敛
为了解决这些问题,深度学习中引入了很多经典技巧,其中最常用、也最重要的就是:
Dropout(随机失活)
Batch Normalization(批量归一化,简称 BN)
二、Dropout:随机失活(防止过拟合)
2.1 Dropout 是什么?
一句话理解 Dropout:
训练时,随机让一部分神经元“休息”,不参与计算
这样可以避免模型过度依赖某些神经元,从而提升泛化能力。
2.2 Dropout 工作原理示意图

2.3 Pytorch 示例
import torch
if __name__ == '__main__':
input_data = torch.randint(1,10,size=(1,4),dtype=torch.float32)
linear1 = torch.nn.Linear(4,5)
# Dropout层,20%概率置0
dropout = torch.nn.Dropout(p=0.2)
x = linear1(input_data)
x = torch.tanh(x)
# Dropout随机失活:经过Dropout随机失活层以后,输出结果值变成0
print("随机失活前:", x)
x = dropout(x)
print("随机失活后:", x)
输出结果
随机失活前的结果 tensor([[ 0.9984, -0.3029, 0.9982, -0.9457, 0.9999]],grad_fn=<TanhBackward0>)
随机失活后的结果 tensor([[ 0.0000, -0.0000, 1.2477, -1.1821, 1.2499]], grad_fn=<MulBackward0>)
2.4 Dropout 使用建议
✅ 常用位置:
-
全连接层(Classifier 部分)
⚠ 注意:
-
卷积层一般少用 Dropout
-
Dropout 不会加速训练,只是防过拟合
三、Batch Normalization:批量归一化(加速训练)
3.1 BN的作用
随着网络变深,会出现:
每一层输入分布不断变化
梯度不稳定
学习率不敢调大
BatchNorm 的核心作用:
把每一层的输入“拉回到稳定分布”
3.2 BatchNorm 前后数据分布变化

3.3 BN 的核心流程
核心流程可分为两步:
Step1:标准化(Normalization)
把一个 batch 的特征变成“均值≈0、方差≈1”的分布:
$$ \hat{x} = \frac{x - \mu}{\sqrt{\sigma^2 + \epsilon}} $$
Step2:再做一次可学习的仿射变换(Affine Transform)
$$ y = \gamma \hat{x} + \beta $$
$\gamma$和$\beta$为可学习参数:
$\gamma$(scale):控制“放大/缩小”
$\beta$(shift):控制“平移/偏置”
3.4 Pytorch示例
def demo1():
# 准备输入的特征数据
# 1张图片,2个颜色通道,图片高度是3,宽度是4
input_2d = torch.randn(size=(1,2,3,4))
print("批量归一化前的数据:",input_2d)
# 批量归一化处理
"""
num_features:在处理图片的时候,该值需要与图片的颜色通道保持一致
eps:小常数,为了避免分母为0
affine:通常都设置为True,表示神经网络自动去调整γ和β
"""
# 创建一个二维批归一化层(torch.nn.BatchNorm2d)实例
# 参数说明:
# num_features: 输入特征图的通道数,设置为2表示处理2通道的输入
# eps: 用于数值稳定性的小常数,防止除零错误,设置为1e-5
# momentum: 动量参数,用于计算运行统计量的动量值,设置为0.1
# affine: 布尔值,控制是否使用可学习的仿射变换参数,设置为True表示启用
# 返回值:
# torch.nn.BatchNorm2d对象,用于对2D输入进行批归一化操作
bn2d = torch.nn.BatchNorm2d(num_features=2,eps=1e-5,momentum=0.1,affine=True)
output = bn2d(input_2d)
print(output)
print(bn2d.weight) # 也就是γ
print(bn2d.bias) # 也就是β
输出结果:
批量归一化前的数据: tensor([[[[-0.2085, 0.7846, -0.1881, -2.7756],
[-0.9371, 0.7341, -1.3063, -1.6797],
[ 0.3303, -0.7707, -0.5810, -0.9489]],
[[ 0.8032, -0.2420, -0.1430, -0.6692],
[-0.1647, -0.1789, 0.8901, -1.0401],
[-1.3928, 0.3604, -0.3477, -0.8258]]]])
tensor([[[[ 0.4288, 1.4415, 0.4495, -2.1893],
[-0.3143, 1.3900, -0.6908, -1.0716],
[ 0.9783, -0.1446, 0.0488, -0.3264]],
[[ 1.5857, 0.0059, 0.1555, -0.6399],
[ 0.1226, 0.1013, 1.7170, -1.2004],
[-1.7335, 0.9164, -0.1539, -0.8766]]]],
grad_fn=<NativeBatchNormBackward0>)
Parameter containing:
tensor([1., 1.], requires_grad=True)
Parameter containing:
tensor([0., 0.], requires_grad=True)
四、Dropout vs BatchNorm 对比总结
| 对比项 | Dropout | BatchNorm |
|---|---|---|
| 主要作用 | 防止过拟合 | 稳定训练、加速收敛 |
| 是否加速训练 | ❌ | ✅ |
| 是否正则化 | ✅ | ⚠ 间接 |
| 常见位置 | 全连接层 | Conv / Linear 后 |
更多推荐
所有评论(0)