现在位置: 首页 > PyTorch 教程 > 正文

PyTorch torch.nn.Dropout 函数

PyTorch torch.nn 参考手册 PyTorch torch.nn 参考手册


torch.nn.Dropout 是 PyTorch 中用于正则化的模块。

它通过随机将输入元素的置零来减少神经元之间的协同适应,从而防止过拟合。

函数定义

torch.nn.Dropout(p=0.5, inplace=False)

参数说明:

  • p (float): 每个元素被置零的概率。默认为 0.5。
  • inplace (bool): 是否原地执行操作。默认为 False。

使用示例

示例 1: 基本用法

创建并使用 Dropout 层:

实例

import torch
import torch.nn as nn

# 创建 Dropout 层,丢弃概率 0.5
dropout = nn.Dropout(p=0.5)

# 训练模式(Dropout 生效)
dropout.train()

# 创建输入
input_tensor = torch.ones(1, 10)
print("输入:", input_tensor.squeeze().tolist())

# 前向传播多次,观察随机性
for i in range(3):
    output = dropout(input_tensor)
    print(f"第{i+1}次输出:", output.squeeze().tolist())

可以看到,每次调用时随机约一半的元素被置零。

示例 2: 训练 vs 评估模式

Dropout 在训练和评估时的行为不同:

实例

import torch
import torch.nn as nn

dropout = nn.Dropout(p=0.5)

# 训练模式
dropout.train()
train_output = dropout(torch.ones(4, 10))
print("训练模式 - 激活比例:", (train_output != 0).float().mean().item())

# 评估模式
dropout.eval()
eval_output = dropout(torch.ones(4, 10))
print("评估模式 - 激活比例:", (eval_output != 0).float().mean().item())
print("评估模式输出:", eval_output[0].tolist())

评估时 Dropout 不起作用,输出保持不变。

示例 3: 在神经网络中使用

典型的带 Dropout 的全连接网络:

实例

import torch
import torch.nn as nn

class DropoutNet(nn.Module):
    def __init__(self, input_dim=784, hidden_dim=256, output_dim=10, dropout_rate=0.5):
        super(DropoutNet, self).__init__()
        self.fc1 = nn.Linear(input_dim, hidden_dim)
        self.dropout1 = nn.Dropout(p=dropout_rate)
        self.fc2 = nn.Linear(hidden_dim, hidden_dim)
        self.dropout2 = nn.Dropout(p=dropout_rate)
        self.fc3 = nn.Linear(hidden_dim, output_dim)
        self.relu = nn.ReLU()

    def forward(self, x):
        x = self.relu(self.fc1(x))
        x = self.dropout1(x)  # 第一次 Dropout
        x = self.relu(self.fc2(x))
        x = self.dropout2(x)  # 第二次 Dropout
        x = self.fc3(x)
        return x

model = DropoutNet()

# 训练模式
model.train()
input_data = torch.randn(32, 784)
output = model(input_data)
print("训练模式输出形状:", output.shape)

# 评估模式
model.eval()
output = model(input_data)
print("评估模式输出形状:", output.shape)

示例 4: 在 CNN 中使用 Dropout2d

nn.Dropout2d 按通道丢弃整个特征图:

实例

import torch
import torch.nn as nn

# Dropout2d 按通道丢弃
dropout2d = nn.Dropout2d(p=0.5)

# 输入:batch=1,通道=4,高=4,宽=4
input_tensor = torch.ones(1, 4, 4, 4)
dropout2d.train()

output = dropout2d(input_tensor)
print("Dropout2d 输出形状:", output.shape)
print("非零通道数:", (output.sum(dim=(2, 3)) != 0).sum().item())

示例 5: 不同丢弃率的效果

丢弃率对网络的影响:

实例

import torch
import torch.nn as nn

for p in [0.1, 0.3, 0.5, 0.7]:
    dropout = nn.Dropout(p=p)
    dropout.train()

    # 多次运行取平均
    total_active = 0
    for _ in range(100):
        output = dropout(torch.ones(1000))
        total_active += (output != 0).float().sum().item()

    avg_active = total_active / 100 / 1000
    print(f"p={p} - 平均激活比例: {avg_active:.2%} (期望: {1-p:.2%})")

Dropout 类型对比

类型 丢弃方式 适用场景
nn.Dropout 随机置零单个元素 全连接层、特征向量
nn.Dropout2d 随机置零整个通道 卷积层特征图
nn.Dropout3d 随机置零整个三维通道 3D 卷积特征

常见问题

Q1: Dropout 丢弃率如何选择?

  • 0.1-0.3: 较轻的正则化,适合大数据集
  • 0.4-0.5: 常用的默认值
  • 0.5+: 较强的正则化,适合小数据集

Q2: Dropout 放在哪里?

通常放在全连接层之后、激活函数之后。也可放在激活函数之前。

Q3: 评估时需要关闭 Dropout 吗?

是的,评估时使用 model.eval() 自动关闭 Dropout。


使用场景

nn.Dropout 主要应用场景包括:

  • 防止过拟合: 减少神经元之间的依赖
  • 模型集成: 近似多个网络的效果
  • 全连接层: 最常用于 FC 层
  • 特征丢弃: 提高模型的鲁棒性

注意:Dropout 在训练时开启,评估时一定要切换到 eval 模式,否则输出会不稳定。


PyTorch torch.nn 参考手册 PyTorch torch.nn 参考手册