Pytorch實現L1與L2正則化

2021-10-11 08:38:11 字數 1443 閱讀 5904

關於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 是未包含正則化項的訓練樣本誤差,是正則化引數,可調。但是正則化項是如何推導的?接下來,我將詳細介紹其中的物理意義。我們知道,正則...