1. 正则化概念
正则化是一种防止机器学习模型过拟合的技术,通过在损失函数中添加惩罚项,抑制模型过于复杂,避免其过于拟合训练数据中的噪声。在神经网络的训练过程中,通过限制模型的复杂度,增强其泛化能力,使模型在新数据上的表现更好。常见的正则化方法有以下几种:
- L2正则化(权重衰减):在损失函数中添加权重参数的平方和的惩罚项。
- L1正则化:在损失函数中添加权重参数绝对值和的惩罚项。
- Dropout:在训练过程中随机丢弃一部分神经元,防止神经元之间的共适应性。
2. 两种常见的正则化
2.1 L2正则化
L2正则化,也称为权重衰减,是最常用的正则化方法之一。它通过在损失函数中添加权重参数平方和的惩罚项,防止权重变得过大。损失函数变为
L total = L original + λ ∑ i w i 2 L_{\text{total}} = L_{\text{original}} + \lambda \sum_{i} w_i^2 Ltotal=Loriginal+λi∑wi2
在PyTorch中,可以通过在优化器中设置weight_decay
参数来实现L2正则化。例如:
optimizer = torch.optim.SGD(model.parameters(), lr=0.01, weight_decay=0.01)
2.2 L1正则化
L1正则化通过在损失函数中添加权重参数绝对值和的惩罚项,使得一些权重参数趋向于零,从而实现特征选择。损失函数变为
L total = L original + λ ∑ i ∣ w i ∣ L_{\text{total}} = L_{\text{original}} + \lambda \sum_{i} |w_i| Ltotal=Loriginal+λi∑∣wi∣
L1正则化在PyTorch中需要手动实现,可以在每次优化步骤中对参数施加L1惩罚:
l1_lambda = 0.01
for param in model.parameters():
l1_norm = torch.norm(param, 1)
loss = loss + l1_lambda * l1_norm
3. 结合正则化的优化器实例
3.1 实例
以下是一个结合正则化的应用小实例
import torch
import torchvision
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Linear, Flatten, Sequential
from torch.utils.data import DataLoader
# 加载数据集
dataset = torchvision.datasets.CIFAR10(root="data1", train=False, transform=torchvision.transforms.ToTensor(), download=True)
dataloader = DataLoader(dataset, batch_size=64)
# 定义网络
class NN(nn.Module):
def __init__(self):
super(NN, self).__init__()
self.model1 = Sequential(
Conv2d(3, 32, 5, padding=2),
MaxPool2d(2),
Conv2d(32, 32, 5, padding=2),
MaxPool2d(2),
Conv2d(32, 64, 5, padding=2),
MaxPool2d(2),
Flatten(),
Linear(1024, 64),
Linear(64, 10),
)
def forward(self, x):
x = self.model1(x)
return x
loss = nn.CrossEntropyLoss()
mynn = NN()
# 使用带有正则化的优化器
optimizer = torch.optim.SGD(mynn.parameters(), lr=0.01, weight_decay=0.01)
# 多轮训练
for epoch in range(20):
running_loss = 0.0
for data in dataloader:
imgs, targets = data
outputs = mynn(imgs)
result_loss = loss(outputs, targets)
optimizer.zero_grad()
result_loss.backward()
optimizer.step()
running_loss += result_loss.item()
print(f'Epoch [{epoch+1}/20], Loss: {running_loss:.4f}')
print("--------------ok--------------")
3.2 运行结果
tensor(360.8925, grad_fn=<AddBackward0>)
--------------ok--------------
tensor(357.5002, grad_fn=<AddBackward0>)
--------------ok--------------
tensor(343.6774, grad_fn=<AddBackward0>)
--------------ok--------------
tensor(319.7137, grad_fn=<AddBackward0>)
--------------ok--------------
tensor(311.0411, grad_fn=<AddBackward0>)
--------------ok--------------
tensor(301.4188, grad_fn=<AddBackward0>)
--------------ok--------------
tensor(292.5016, grad_fn=<AddBackward0>)
--------------ok--------------
tensor(284.5493, grad_fn=<AddBackward0>)
--------------ok--------------
tensor(277.0789, grad_fn=<AddBackward0>)
--------------ok--------------
tensor(270.6507, grad_fn=<AddBackward0>)
--------------ok--------------
tensor(264.8946, grad_fn=<AddBackward0>)
--------------ok--------------
tensor(259.5017, grad_fn=<AddBackward0>)
--------------ok--------------
tensor(254.4651, grad_fn=<AddBackward0>)
--------------ok--------------
tensor(249.8820, grad_fn=<AddBackward0>)
--------------ok--------------
tensor(245.7606, grad_fn=<AddBackward0>)
--------------ok--------------
tensor(241.9919, grad_fn=<AddBackward0>)
--------------ok--------------
tensor(238.4926, grad_fn=<AddBackward0>)
--------------ok--------------
tensor(235.1495, grad_fn=<AddBackward0>)
--------------ok--------------
tensor(231.9023, grad_fn=<AddBackward0>)
--------------ok--------------
tensor(228.7519, grad_fn=<AddBackward0>)
--------------ok--------------
3.3 结果分析
- 所有tensor的值都在逐渐减小,从360.8925开始,逐渐降低到接近230的值。
- 每个tensor值与前一个值之间的差值也在逐渐减小,表明这种减小趋势可能在放缓。
- 所有tensor都具有grad_fn=属性,表明这些值是通过反向传播计算得到。
4. 总结
优化器正则化在深度学习中扮演着重要角色,可以有效防止模型过拟合。L2正则化是最常用的方法,通过在损失函数中添加权重参数平方和的惩罚项,使权重参数保持较小值。L1正则化则通过惩罚权重参数的绝对值和,实现特征选择。选择合适的正则化方法和正则化系数,可以显著提升模型的性能。