關於pytorch如何實現正則化在這篇部落格《pytorch實現l2和l1正則化regularization的方法》其實已經給出了差不多正確的方法,但是這篇部落格的**在實現l2正則的時候是有一點小問題的。
首先看一下l2正則的公式:
l os
s=cl
+λ2∑
wi
2loss = cl+\frac \sum w_^
loss=c
l+2λ
∑wi
2其中clcl
cl就是正常的損失(比如交叉熵損失)。實際上在pytorch中,當你使用sgd的時候,其中的乙個引數weight_decay
其實就是l2正則的λ
\lambda
λ係數,只不過pytorch用了一種取巧的方法,實際的loss不會把l2損失計算進去,而是在梯度回傳的時候通過在原先的梯度上面加上λwi
\lambda w_
λwi
來實現一種等價的l2正則。如下面的原始碼所示:
for p in group['params`]:
if p.grad is none:
continue
d_p = p.grad.data
if weight_decay != 0:
d_p.add_(weight_decay, p.data)
所以如果我們想顯式地在損失中顯示l2損失,就可以把sgd中的weight_decay
置為0,然後再自己實現l2正則。還是參考前面提到的部落格給出的實現方式,但是前面那篇部落格在實現l2正則的時候用的l2範數即torch.norm(w, p=2)
,而這個其實是有問題的,因為l2範數其實是∑wi
2\sqrt^}
∑wi2
,跟我們要的不是乙個東西,所以我重寫了一下:
def regularization_loss(self, weight_list_l1, weight_list_l2):
reg_loss = 0
loss1, loss2 = 0, 0
for name, w in weight_list_l1:
loss1 += torch.sum(torch.abs(w))
for name, w in weight_list_l2:
loss2 += torch.sum(torch.pow(w, 2))
reg_loss = self.weight_decay_l1*loss1 + self.weight_decay_l2/2*loss2
return reg_loss
需要說明的是我這裡還實現了l1正則,可以實現對部分引數用l1正則,對另一部分用l2正則,然後對剩下的引數不用任何正則化(因為一般我們對bn層跟bias是不用正則化的,但是sgd的預設實現會對所有引數都施加l2正則化)。 L1與L2正則化
在機器學習中,我們茶廠聽到l1和l2正則化,用他們來防止過擬合,但是在什麼情況下使用它們和它們的原理是什麼樣的可能一知半解。所以在本部落格中將對l1和l2做簡單的介紹和應用場景。如果引數過多,模型過於複雜,容易造成過擬合 overfit 即模型在訓練樣本資料上表現的很好,但在實際測試樣本上表現的較差...
L1與L2正則化
尊重原創,我沒有改動乙個字。過擬合示意圖 我們知道,過擬合就是所謂的模型對可見的資料過度自信,非常完美的擬合上了這些資料,如果具備過擬合的能力,那麼這個方程就可能是乙個比較複雜的非線性方程 正是因為這裡的 x 3 和 x 2 使得這條虛線能夠被彎來彎去,所以整個模型就會特別努力地去學習作用在 x 3...
L1 與 L2 正則化
參考這篇文章 1.l2 正則化直觀解釋 l2 正則化公式非常簡單,直接在原來的損失函式基礎上加上權重引數的平方和 l ein jw2j l ein jwj2 其中,ein 是未包含正則化項的訓練樣本誤差,是正則化引數,可調。但是正則化項是如何推導的?接下來,我將詳細介紹其中的物理意義。我們知道,正則...