介绍
需要掌握:Dropout抑制过拟合
torch.nn.Dropout 模块,这是深度学习中常用的 正则化 手段,主要用于防止模型过拟合,在大模型的全连接层、注意力层等位置广泛应用。
作用
在训练过程中,以概率
p,随机丢弃神经元(即:将输入张量的部分元素置为 0),保留的元素会乘以1/(1-p)以保证张量的整体期望不变,提升泛化能力验证/推理阶段会关闭 Dropout,所有元素都保留且不做缩放,保证预测稳定性
为什么要缩放保留的元素?
训练时丢弃了 p 比例的元素,若不缩放,张量的总和会变为原来的 1-p 倍;乘以 1/(1-p) 后,训练和推理阶段的张量期望保持一致,避免推理时输出值整体偏小。
语法
torch.nn.Dropout(p=0.5, inplace=False)
参数:
p:可选,被丢弃的概率(即元素置0的概率),默认0.5(常用值还有0.1、0.2、0.3);inplace:可选,是否原地修改输入张量,默认False(推荐保持默认,避免梯度问题)。
参数选择
- 小模型/数据量少:
p=0.5左右; - 大模型/数据量充足:
p=0.1~0.3(避免过度丢弃导致欠拟合); - 推理阶段:必须关闭(通过
model.eval()),否则会导致预测结果不稳定。
例子
基础使用+训练/推理模式
下面通过完整示例演示 Dropout 的使用,包括训练和推理阶段的差异:
import torch
import torch.nn as nn
# 1. 定义Dropout层(丢弃概率p=0.3)
dropout = nn.Dropout(p=0.3)
# 2. 模拟输入(batch_size=2, feature_dim=5)
x = torch.ones(2, 5) # 输入全1张量,方便观察效果
print("原始输入:")
print(x)
# 输出:
# tensor([[1., 1., 1., 1., 1.],
# [1., 1., 1., 1., 1.]])
# 3. 训练模式(默认):启用Dropout
torch.manual_seed(42) # 固定随机种子,方便复现
x_train = dropout(x)
print("\n训练阶段(Dropout启用):")
print(x_train)
# 输出(部分元素被置0,保留元素乘以1/(1-0.3)≈1.4286):
# tensor([[1.4286, 0.0000, 1.4286, 1.4286, 1.4286],
# [1.4286, 1.4286, 0.0000, 1.4286, 0.0000]])
# 4. 推理模式:关闭Dropout
dropout.eval() # 切换到评估模式
x_eval = dropout(x)
print("\n推理阶段(Dropout关闭):")
print(x_eval)
# 输出(所有元素保留,无缩放):
# tensor([[1., 1., 1., 1., 1.],
# [1., 1., 1., 1., 1.]])
# 5. 重置为训练模式
dropout.train()
进阶:在模型中集成Dropout
Dropout 通常放在全连接层、卷积层或注意力层之后,下面以一个简单的分类模型为例:
import torch.nn.functional as F
class SimpleModel(nn.Module):
def __init__(self, input_dim=10, hidden_dim=20, output_dim=2, dropout_p=0.2):
super().__init__()
self.fc1 = nn.Linear(input_dim, hidden_dim)
self.dropout = nn.Dropout(p=dropout_p) # 定义Dropout层
self.fc2 = nn.Linear(hidden_dim, output_dim)
def forward(self, x):
# 全连接层 → 激活函数 → Dropout → 全连接层
x = F.relu(self.fc1(x))
x = self.dropout(x) # 训练时生效,推理时失效
x = self.fc2(x)
return x
# 测试模型
model = SimpleModel()
x = torch.randn(3, 10) # batch_size=3, input_dim=10
# 训练模式
model.train()
output_train = model(x)
print("\n训练模式输出(Dropout启用):")
print(output_train)
# 推理模式
model.eval()
output_eval = model(x)
print("\n推理模式输出(Dropout关闭):")
print(output_eval)
Dropout在大模型中的使用位置
- Transformer 架构:常放在 Feed Forward Network (FFN) 层之后、残差连接之前;
- 注意力层:部分模型会在注意力输出后加轻量 Dropout(
p=0.1); - 嵌入层:少数模型会在 Token Embedding 后加 Dropout,防止过拟合到特定token。
nn.Dropout vs F.dropout
nn.Dropout:类形式,需实例化后使用(推荐,可随模型一起切换train()/eval()模式);F.dropout:函数形式,需手动指定training参数控制是否启用(如F.dropout(x, p=0.2, training=self.training))。
总结
nn.Dropout(p)是正则化工具,训练时以概率p随机丢弃元素,保留元素缩放1/(1-p),推理时关闭;- 使用时需注意模型模式切换(
train()/eval()),避免推理阶段误启用Dropout; - 在大模型中,Dropout 主要用于 FFN 层等位置,
p通常选0.1~0.3,平衡泛化能力和模型性能。