權重衰退

導致過擬合,影響模型泛化的因素:

  1. 可調整參數的數量,當可調整參數的數量(自由度)很大時,模型往往容易過擬合。
  2. 參數採用的值,當權重的取值範圍較大時,模型可能更容易過擬合。
  3. 訓練樣本的數量。即使模型很簡單避免了上面條件1的可能性,但是在訓練樣本極少的情況下也很容易造成過擬合現象。而過擬合一個數據量極大的數據集則需要一個非常靈活的模型。

權重衰減

\(L2\)正則化的目的就是爲了讓權重衰減到更小的值,也就是解決上面的第二個因素。它在一定程度上可以減少模型過擬合的問題,所以權重衰減也叫\(L2\)正則化。

多項式擬合帶來的困惑

在多項式擬閤中我們可以通過調整擬合多項式的階數來限制模型的容量,也就是調整上面因素1的方法來解決問題,但是在實際操作中簡單的丟棄特徵對於這項工作來說可能顯得過於僵硬,而且找到一個合適的特徵數量也是一件很奢侈的事情
在訓練參數化機器學習模型的時候,權重衰減也就是\(L2\)正則化是使用最廣泛的解決過擬合的技術之一。這項技術是基於一個基本直覺,即在所有函數\(f\)中,函數\(f=0\)(所有輸入都得到0值)在某種意義上是最簡單的,我們可以通過函數與零的距離來衡量函數的複雜度。但是我們應該如何精確的測量一個函數和零之間的距離呢?沒有一個正確的答案。事實上,整個數學分支,包括函數分析和巴拿赫空間理論,但是致力於解答這個問題。

一種比較簡單的方法是通過線性函數\(f(\mathbf{x}) = \mathbf{w}^\top \mathbf{x}\)中的權重向量的某個範數來衡量其複雜性,例如\(\|\mathbf{w}\|^2_2\)。要保證權重向量比較小,最常用方法是將其範數作爲懲罰項加到最小化損失的問題中。將原來的訓練目標最小化訓練標籤上的預測損失調整爲最小化訓練標籤上的預測損失和懲罰項之和。現在如果將我們的權重向量增長的太大,我們學習算法可能會更集中於最小化權重範數\(\|\mathbf{w}\|^2_2\)。這就是我們想要的。在線性迴歸的例子中。我們的損失函數如下:

\[L(\mathbf{w}, b) = \frac{1}{n}\sum_{i=1}^n \frac{1}{2}\left(\mathbf{w}^\top \mathbf{x}^{(i)} + b - y^{(i)}\right)^2. \]

爲了可以調節懲罰權重的影響大小,我們在這裏加入了一個正則化常數\(\lambda\)來描述這種權衡,這是一個非負超參數,我們使用驗證數據擬合:

\[L(\mathbf{w}, b) + \frac{\lambda}{2} \|\mathbf{w}\|^2_2, \]

\(\lambda=0\)的時候,我們相當於恢復了原來的損失函數。對於\(\lambda>0\),我們限制\(\|\mathbf{w}\|^2_2\)的大小

此外,你可能會問爲什麼我們首先使用\(L_2\)範數,而不是\(L_1\)範數。事實上,這些選擇在整個統計領域中都是有效的和受歡迎的。\(L_2\)正則化線性模型構成經典的嶺迴歸(ridge regression)算法,\(L_1\)正則化線性迴歸是統計學中類似的基本模型,通常被稱爲套索迴歸(lasso regression)。

使用\(L_2\)範數的一個原因是它對權重向量的大分量施加了巨大的懲罰。這使得我們的學習算法偏向於在大量特徵上均勻分佈權重的模型。在實踐中,這可能使它們對單個變量中的觀測誤差更爲魯棒。相比之下,\(L_1\)懲罰會導致模型將其他權重清除爲零而將權重集中在一小部分特徵上。這稱爲特徵選擇(feature selection),這可能是其他場景下需要的。

使用與 :eqref:eq_linreg_batch_update 中的相同符號,\(L_2\)正則化迴歸的小批量隨機梯度下降更新如下式:

\[\begin{aligned} \mathbf{w} & \leftarrow \left(1- \eta\lambda \right) \mathbf{w} - \frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}} \mathbf{x}^{(i)} \left(\mathbf{w}^\top \mathbf{x}^{(i)} + b - y^{(i)}\right). \end{aligned} \]

根據之前章節所講的,我們根據估計值與觀測值之間的差異來更新\(\mathbf{w}\)。然而,我們同時也在試圖將\(\mathbf{w}\)的大小縮小到零。這就是爲什麼這種方法有時被稱爲權重衰減。我們僅考慮懲罰項,優化算法在訓練的每一步衰減權重。與特徵選擇相比,權重衰減爲我們提供了一種連續的機制來調整函數的複雜度。較小的\(\lambda\)值對應較少約束的\(\mathbf{w}\),而較大的\(\lambda\)值對\(\mathbf{w}\)的約束更大。

是否對相應的偏置\(b^2\)進行懲罰在不同的實現中會有所不同。在神經網絡的不同層中也會有所不同。通常,我們不正則化網絡輸出層的偏置項。

高維線性迴歸

我們通過一個簡單的例子來說明演示權重衰減。

%matplotlib inline
import torch
from torch import nn
from d2l import torch as d2l

$$y = 0.05 + \sum_{i = 1}^d 0.01 x_i + \epsilon \text{ where }
\epsilon \sim \mathcal{N}(0, 0.01^2).$$

\(20\)較小的訓練數據,200較大的特徵維度,很容易發生過擬合。

n_train, n_test, num_inputs, batch_size = 20, 100, 200, 5
true_w, true_b = torch.ones((num_inputs, 1)) * 0.01, 0.05
train_data = d2l.synthetic_data(true_w, true_b, n_train)
train_iter = d2l.load_array(train_data, batch_size)
test_data = d2l.synthetic_data(true_w, true_b, n_test)
test_iter = d2l.load_array(test_data, batch_size, is_train=False)
def init_params():
    w = torch.normal(0, 1, size=(num_inputs, 1), requires_grad=True)
    b = torch.zeros(1, requires_grad=True)
    return [w, b]
def l2_penalty(w):
    return torch.sum(w.pow(2)) / 2
def train(lambd):
    w, b = init_params()
    net, loss = lambda X: d2l.linreg(X, w, b), d2l.squared_loss
    num_epochs, lr = 100, 0.003
    animator = d2l.Animator(xlabel='epochs', ylabel='loss', yscale='log',
                            xlim=[5, num_epochs], legend=['train', 'test'])
    for epoch in range(num_epochs):
        for X, y in train_iter:
            with torch.enable_grad():
                # 增加了L2範數懲罰項,廣播機制使l2_penalty(w)成爲一個長度爲`batch_size`的向量。
                l = loss(net(X), y) + lambd * l2_penalty(w)
            l.sum().backward()
            d2l.sgd([w, b], lr, batch_size)
        if (epoch + 1) % 5 == 0:
            animator.add(epoch + 1, (d2l.evaluate_loss(net, train_iter, loss),
                                     d2l.evaluate_loss(net, test_iter, loss)))
    print('w的L2範數是:', torch.norm(w).item())

[忽略正則化直接訓練]

我們現在用lambd = 0禁用權重衰減後運行這個代碼。注意,這裏訓練誤差有了減少,但測試誤差沒有減少。這意味着出現了嚴重的過擬合。這是過擬合的一個典型例子。

train(lambd=0)
w的L2範數是: 12.022252082824707

[使用權重衰減]

下面,我們使用權重衰減來運行代碼。注意,在這裏訓練誤差增大,但測試誤差減小。這正是我們期望從正則化中得到的效果。

train(lambd=3)
w的L2範數是: 0.35783883929252625

可以看到隨着\(\lambda\)的增大,\(\|\mathbf{w}\|^2\)在下降。

train(lambd=10)
w的L2範數是: 0.02848632261157036

train(lambd=1)
w的L2範數是: 3.9273383617401123

train(lambd=50)
w的L2範數是: 0.008260481990873814

L2範數實際上是\(\|\mathbf{w}\|_2=\sqrt{\sum_{i=1}^Nx^2_i}\),即元素的平方之和再開方。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章