一、dropout
dropout 是一种在神经网络训练中常用的正则化技术,旨在防止过拟合。
其基本思想是在每次训练过程中,随机“丢弃”网络中的一些神经元(即将它们的输出设为零),使得网络不会过度依赖某些特定的神经元,从而简化网络。这样可以增加模型的鲁棒性,提高其泛化能力。
具体来说,Dropout 会在每次训练时以一定的概率(通常取0.1、0.5、0.9)暂时移除一些神经元。这样,每次训练时,网络的结构都会有所不同,减少了神经元之间的依赖关系,有助于模型学到更具泛化能力的特征。
在测试阶段,dropout 通常不进行应用,所有神经元都会使用,但会对输出进行缩放,以保持与训练阶段一致的期望值。
二、简单代码实现
import torch
import torch.nn as nn
import torch.optim as optim
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import numpy as np
# 1. 加载 Iris 数据集
iris = load_iris()
X = iris.data # 特征
y = iris.target # 标签
# 数据标准化
scaler = StandardScaler()
X = scaler.fit_transform(X)
# 将数据划分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 转换为 PyTorch tensor
X_train = torch.tensor(X_train, dtype=torch.float32)
X_test = torch.tensor(X_test, dtype=torch.float32)
y_train = torch.tensor(y_train, dtype=torch.long)
y_test = torch.tensor(y_test, dtype=torch.long)
# 2. 使用 Sequential 定义网络
input_dim = 4 # 输入特征数量
hidden_dim1 = 64 # 第一层隐藏层单元数
hidden_dim2 = 32 # 第二层隐藏层单元数
output_dim = 3 # 输出类别数
# 定义模型的层
model = nn.Sequential(
nn.Linear(input_dim, hidden_dim1), # 输入层到第一个隐藏层
nn.ReLU(), # 第一个隐藏层的ReLU激活
nn.Dropout(0.1), # 第一个隐藏层的Dropout,丢弃概率为0.1
nn.Linear(hidden_dim1, hidden_dim2), # 第一个隐藏层到第二个隐藏层
nn.ReLU(), # 第二个隐藏层的ReLU激活
nn.Dropout(0.1), # 第二个隐藏层的Dropout,丢弃概率为0.1
nn.Linear(hidden_dim2, output_dim) # 第二个隐藏层到输出层
)
# 3. 损失函数:交叉熵损失
criterion = nn.CrossEntropyLoss()
# 4. 优化器:使用随机梯度下降(SGD)
optimizer = optim.SGD(model.parameters(), lr=0.02)
# 5. 训练模型
epochs = 2000
for epoch in range(epochs):
# 前向传播
outputs = model(X_train) # 直接通过模型进行前向传播
# 计算损失
loss = criterion(outputs, y_train)
# 反向传播和优化
optimizer.zero_grad() # 清空梯度
loss.backward() # 反向传播计算梯度
optimizer.step() # 更新权重
if epoch % 100 == 0:
print(f'Epoch [{epoch}/{epochs}], Loss: {loss.item():.4f}')
# 6. 在测试集上进行预测
with torch.no_grad(): # 测试时不需要计算梯度
outputs = model(X_test) # 直接通过模型进行前向传播
_, predicted = torch.max(outputs, 1) # 获取预测类别(最大概率的类别)
# 7. 计算准确率
accuracy = (predicted == y_test).sum().item() / y_test.size(0)
print(f'Accuracy on test data: {accuracy * 100:.2f}%')
代码运行结果
三、总结
1、dropout将一些输出项随机置0从而降低模型的复杂度,丢弃概率为超参数,通常取0.1、0.5、0.9这三个数
2、dropout常常作用于隐藏层的输出上,以减少对某一个神经元的依赖。
3、优点:
①防止过拟合:通过随机丢弃神经元,Dropout 减少了神经元间的过度依赖,防止了模型在训练数据上的过拟合。
②增强网络的鲁棒性:在训练时随机丢弃,所以每次都会使用不同的网络结构,使得模型对不同的输入和训练样本具有更好的适应性。
缺点:
①增加训练时间:由于每次迭代时网络的结构都不同,训练可能需要更多的时间来收敛。
②不适用于所有类型的模型:一般在计算机视觉领域使用,因为图片像素输入数据较大,使用dropout可以有效防止过拟合。