Pytorch 解決過擬合問題(L2 權值衰減和 Dropout)
本方法總結自《動手學深度學習》(Pytorch版)github項目
- 部分內容延續 Pytorch 學習(五):Pytorch 實現多層感知機(MLP) 實現方法
上一節用 Pytorch 實現了多層感知器。在解決實際問題時,可能會出現過擬合現象,常用的解決方法有數據增廣和正則化,L2 權值衰減和 Dropout 都屬於正則化的範疇
以均值方差(MSE)損失函數爲例,通常情況下其中, 爲真值, 爲預測結果。L2 正則化通過給損失函數添加權值的 L2 範式懲罰項對其進行約束其中, 爲權值衰減參數。當總損失不變時,損失函數總是期望更小的 ,從而使網絡更簡單,根據奧卡姆剃刀原理,相同的結果下,簡單的更好。
實現方法一:從零實現
# 構建損失
def MSEloss(y_hat, y):
return (y_hat - y.view(-1, 1)) ** 2 / 2
# 權值衰減
def weight_penalty(w):
return (w ** 2).sum() / 2
# 訓練過程中的新 loss
l = MSEloss(y_hat, y) + lambda * weight_penalty(w)
實現方法二:函數調用
import torch.optim as optim
optimizer = optim.SGD(net.parameters(), lr=lr, weight_decay=wd)
Dropout 通過在神經網絡中以概率 p 隨機保留不同的節點(即以概率 1-p 丟棄)來解決過擬合問題。由於每次計算中部分節點不參與,因此網絡整體沒有對數據進行完全學習,從而防止了過擬合。
過擬合示例圖
實現方法一:從零實現
- 我們所實現的 dropout 實際是 inverted dropout
- Dropout 只會在訓練過程使用,測試時不使用。
- 因此在訓練時經過 dropout 層的期望 E(x) = px + (1-p) * 0,測試階段爲 E(x)。
- 爲了保持兩者的輸出期望一直,dropout 需要在測試時添加 output = dropout(x) * p 來對期望進行統一。
- 在訓練階段對結果 output = dropout(x) / p 同樣能達到相同的效果,稱爲 inverted dropout
def dropout(X, drop_prob):
assert 0 <= drop_prob and drop_prob <= 1
X = X.float()
keep_prob = 1 - drop_prob
if keep_prob == 0:
return torch.zeros_like(X)
mask = (troch.randn(X.shape) <= keep_prob).float()
return mask * X / keep_prob
實現方法二:直接調用
- dropout 的參數爲丟棄率,不是保留率
import torch.nn as nn
dropout = nn.dropout(drop_prob)