5.5 正則化

梗直哥提示:對(duì)正則化的原理感興趣,希望深入了解的同學(xué),可以點(diǎn)擊選修“解一卷而眾篇明”之機(jī)器學(xué)習(xí)核心概念精講,用具體生動(dòng)的例子,把正則化的前因后果,數(shù)學(xué)推導(dǎo),幾何意義,與MAP最大后驗(yàn)的關(guān)系等等各種知識(shí)給你講個(gè)通透。
5.5.1 L2正則化

5.5.2 代碼示例
下面是一個(gè)示例,展示了在使用和不使用 L2 正則化的情況下,訓(xùn)練誤差和測(cè)試誤差的變化:
import?os
os.environ["KMP_DUPLICATE_LIB_OK"]?=?"TRUE"
import?torch
import?matplotlib.pyplot?as?plt
# 生成數(shù)據(jù)
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
# 假設(shè)我們有一個(gè)包含兩個(gè)隱藏層的神經(jīng)網(wǎng)絡(luò)
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)
)
# 定義損失函數(shù)和優(yōu)化器
loss_fn?=?torch.nn.MSELoss()
optimizer?=?torch.optim.SGD(model.parameters(), lr=0.01)
# 不使用 L2 正則化的情況
train_losses?=?[]
test_losses?=?[]
for?epoch?in?range(50):
????# 計(jì)算訓(xùn)練損失
????y_pred?=?model(X_train)
????loss?=?loss_fn(y_pred, y_train)
????train_losses.append(loss.item())
????
????# 使用優(yōu)化器更新權(quán)重
????optimizer.zero_grad()
????loss.backward()
????optimizer.step()
????
????# 計(jì)算測(cè)試損失
????with?torch.no_grad():
????????y_pred?=?model(X_test)
????????loss?=?loss_fn(y_pred, y_test)
????????test_losses.append(loss.item())
????
# 繪制訓(xùn)練損失和測(cè)試損失的曲線
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)
)
#定義損失函數(shù)和優(yōu)化器
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):
????# 計(jì)算訓(xùn)練損失
????y_pred?=?model(X_train)
????loss?=?loss_fn(y_pred, y_train)
????train_losses.append(loss.item())
????# 使用優(yōu)化器更新權(quán)重
????optimizer.zero_grad()
????loss.backward()
????optimizer.step()
????
????# 計(jì)算測(cè)試損失
????with?torch.no_grad():
????????y_pred?=?model(X_test)
????????loss?=?loss_fn(y_pred, y_test)
????????test_losses.append(loss.item())
#繪制訓(xùn)練損失和測(cè)試損失的曲線
plt.plot(train_losses, label='L2-train')
plt.plot(test_losses, label='L2-test')
plt.legend()
plt.show()


在這個(gè)例子中,使用了 PyTorch 的數(shù)據(jù)生成函數(shù) torch.randn() 和 torch.sin() 來(lái)生成訓(xùn)練數(shù)據(jù)和測(cè)試數(shù)據(jù)。然后構(gòu)建了一個(gè)包含兩個(gè)隱藏層的神經(jīng)網(wǎng)絡(luò),并使用隨機(jī)生成的數(shù)據(jù)進(jìn)行訓(xùn)練。在第一個(gè)循環(huán)中,我們沒(méi)有使用 L2 正則化;在第二個(gè)循環(huán)中,我們使用了 L2 正則化。
在兩個(gè)循環(huán)中,我們都計(jì)算了訓(xùn)練數(shù)據(jù)和測(cè)試數(shù)據(jù)的損失,并將訓(xùn)練數(shù)據(jù)和測(cè)試數(shù)據(jù)的損失添加到列表train_losses 和 test_losses 中,然后使用 Matplotlib 繪制了兩組損失的曲線。在使用 L2 正則化的情況下,你可以看到訓(xùn)練損失和測(cè)試損失的差距變小了,這表明 L2 正則化有助于減小過(guò)擬合。
同步更新:
Github/公眾號(hào):梗直哥
