5.5 正则化

梗直哥提示:对正则化的原理感兴趣,希望深入了解的同学,可以点击选修“解一卷而众篇明”之机器学习核心概念精讲,用具体生动的例子,把正则化的前因后果,数学推导,几何意义,与MAP最大后验的关系等等各种知识给你讲个通透。
5.5.1 L2正则化

5.5.2 代码示例
下面是一个示例,展示了在使用和不使用 L2 正则化的情况下,训练误差和测试误差的变化:
import os
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
import torch
import matplotlib.pyplot as plt
# 生成数据
X_train = torch.randn(1000, 30)
y_train = torch.sin(X_train) + torch.randn(1000, 30) * 0.1
X_test = torch.randn(100, 30)
y_test = torch.sin(X_test) + torch.randn(100, 30) * 0.1
# 假设我们有一个包含两个隐藏层的神经网络
model = torch.nn.Sequential(
torch.nn.Linear(30, 20),
torch.nn.ReLU(),
torch.nn.Linear(20, 10),
torch.nn.ReLU(),
torch.nn.Linear(10, 30)
)
# 定义损失函数和优化器
loss_fn = torch.nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
# 不使用 L2 正则化的情况
train_losses = []
test_losses = []
for epoch in range(50):
# 计算训练损失
y_pred = model(X_train)
loss = loss_fn(y_pred, y_train)
train_losses.append(loss.item())
# 使用优化器更新权重
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 计算测试损失
with torch.no_grad():
y_pred = model(X_test)
loss = loss_fn(y_pred, y_test)
test_losses.append(loss.item())
# 绘制训练损失和测试损失的曲线
plt.plot(train_losses, label='train')
plt.plot(test_losses, label='test')
plt.legend()
plt.show()
# 使用 L2 正则化的情况
model = torch.nn.Sequential(
torch.nn.Linear(30, 20),
torch.nn.ReLU(),
torch.nn.Linear(20, 10),
torch.nn.ReLU(),
torch.nn.Linear(10, 30)
)
#定义损失函数和优化器
loss_fn = torch.nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01, weight_decay=0.1) # 加入 L2 正则化
train_losses = []
test_losses = []
for epoch in range(50):
# 计算训练损失
y_pred = model(X_train)
loss = loss_fn(y_pred, y_train)
train_losses.append(loss.item())
# 使用优化器更新权重
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 计算测试损失
with torch.no_grad():
y_pred = model(X_test)
loss = loss_fn(y_pred, y_test)
test_losses.append(loss.item())
#绘制训练损失和测试损失的曲线
plt.plot(train_losses, label='L2-train')
plt.plot(test_losses, label='L2-test')
plt.legend()
plt.show()


在这个例子中,使用了 PyTorch 的数据生成函数 torch.randn() 和 torch.sin() 来生成训练数据和测试数据。然后构建了一个包含两个隐藏层的神经网络,并使用随机生成的数据进行训练。在第一个循环中,我们没有使用 L2 正则化;在第二个循环中,我们使用了 L2 正则化。
在两个循环中,我们都计算了训练数据和测试数据的损失,并将训练数据和测试数据的损失添加到列表train_losses 和 test_losses 中,然后使用 Matplotlib 绘制了两组损失的曲线。在使用 L2 正则化的情况下,你可以看到训练损失和测试损失的差距变小了,这表明 L2 正则化有助于减小过拟合。
同步更新:
Github/公众号:梗直哥
