深入理解L1、L2正則化原理與作用
過節福利,我們來深入理解下L1與L2正則化。
1 正則化的概念
- 正則化(Regularization) 是機器學習中對原始損失函式引入額外資訊,以便防止過擬合和提高模型泛化效能的一類方法的統稱。也就是目標函式變成了 原始損失函式+額外項 ,常用的額外項一般有兩種,英文稱作 \(ℓ1-norm\) 和 \(ℓ2-norm\) ,中文稱作 L1正則化 和 L2正則化 ,或者L1範數和L2範數(實際是L2範數的平方)。
-
L1正則化和L2正則化可以看做是 損失函式的懲罰項 。所謂 懲罰 是指對損失函式中的 某些引數做一些限制 。對於線性迴歸模型, 使用L1正則化的模型叫做Lasso迴歸,使用L2正則化的模型叫做Ridge迴歸(嶺迴歸) 。
-
線性迴歸L1正則化損失函式:
\[\min_w (\sum_{i=1}^{N}(w^Tx_i - y_i)^2 + \lambda \|w\|_1 )........(1)\]
-
線性迴歸L2正則化損失函式:
\[\min_w(\sum_{i=1}^{N}(w^Tx_i - y_i)^2 + \lambda\|w\|_2^2) ........(2)\]
- 一般迴歸分析中迴歸 \(w\) 表示特徵的係數( \(x\) 的引數),從上式可以看到正則化項是對係數做了限制。L1正則化和L2正則化的說明如下:
- L1正則化是指權值向量 \(w\) 中各個元素的絕對值之和,通常表示為 \(\|w\|_1\) 。
- L2正則化是指權值向量 \(w\) 中各個元素的平方和然後再求平方根(可以看到Ridge迴歸的L2正則化項有平方符號),通常表示為 \(\|w\|_2^2\) 。
- 一般都會在正則化項之前新增一個係數 \(\lambda\) 。Python中用 \(\alpha\) 表示,這個係數需要使用者指定(也就是我們要調的超參)。
2 正則化的作用
- L1正則化可以使得引數稀疏化,即得到的引數是一個稀疏矩陣,可以用於特徵選擇。
- 稀疏性 ,說白了就是模型的很多引數是0。通常機器學習中特徵數量很多,例如文字處理時,如果將一個片語(term)作為一個特徵,那麼特徵數量會達到上萬個(bigram)。在預測或分類時,那麼多特徵顯然難以選擇,但是如果代入這些特徵得到的模型是一個稀疏模型,很多引數是0,表示只有少數特徵對這個模型有貢獻,絕大部分特徵是沒有貢獻的,即使去掉對模型也沒有什麼影響,此時我們就可以只關注係數是非零值的特徵。這相當於對模型進行了一次特徵選擇,只留下一些比較重要的特徵,提高模型的泛化能力,降低過擬合的可能。
- L2正則化可以防止模型過擬合(overfitting);一定程度上,L1也可以防止過擬合。
3 L1正則化與稀疏性
- 事實上, ”帶正則項”和“帶約束條件”是等價的 。
-
為了約束w的可能取值空間從而防止過擬合,我們為該最優化問題加上一個約束,就是w的L1範數不能大於m:
\[ \begin{cases} \min \sum_{i=1}^{N}(w^Tx_i - y_i)^2 \\ s.t. \|w\|_1 \leqslant m. \end{cases}........(3) \]
- 問題轉化成了 帶約束條件的凸優化問題 ,寫出拉格朗日函式:
\[ \sum_{i=1}^{N}(w^Tx_i - y_i)^2 + \lambda (\|w\|_1-m)........(4)\] -
設 \(W_*\) 和 \(\lambda_*\) 是原問題的最優解,則根據 \(KKT\) 條件得:
\[ \begin{cases} 0 = \nabla_w[\sum_{i=1}^{N}(W_*^Tx_i - y_i)^2 + \lambda_* (\|w\|_1-m)] \\ 0 \leqslant \lambda_*. \end{cases}........(5) \]
- 仔細看上面第一個式子,與公式(1)其實是等價的,等價於(3)式 。
- 設L1正則化損失函式: \(J = J_0 + \lambda \sum_{w} |w|\) ,其中 \(J_0 = \sum_{i=1}^{N}(w^Tx_i - y_i)^2\) 是 原始損失函式 ,加號後面的一項是L1正則化項, \(\lambda\) 是 正則化係數 。
- 注意到L1正則化是權值的絕對值之和, \(J\) 是帶有絕對值符號的函式,因此 \(J\) 是不完全可微的。機器學習的任務就是要通過一些方法(比如梯度下降)求出損失函式的最小值。當我們在原始損失函式 \(J_0\) 後新增L1正則化項時,相當於對 \(J_0\) 做了一個約束。令 \(L=\lambda \sum_w|w|\) ,則 \(J=J_0+L\) ,此時我們的任務變成在 \(L\) 約束下求出 \(J_0\) 取最小值的解。
- 考慮二維的情況,即只有兩個權值 \(w_1\) 和 \(w_2\) ,此時 \(L=|w_1|+|w_2|\) 對於梯度下降法,求解 \(J_0\) 的過程可以畫出等值線,同時L1正則化的函式 \(L\) 也可以在 \(w_1\) 、 \(w_2\) 的二維平面上畫出來。如下圖:
- 上圖中等值線是 \(J_0\) 的等值線,黑色方形是 \(L\) 函式的圖形。在圖中,當 \(J_0\) 等值線與 \(L\) 圖形首次相交的地方就是最優解。上圖中 \(J_0\) 與 \(L\) 在 \(L\) 的一個頂點處相交,這個頂點就是最優解。注意到這個頂點的值是 \((w_1,w_2)=(0,w_2)\) 。可以直觀想象,因為 \(L\) 函式有很多 突出的角 (二維情況下四個,多維情況下更多), \(J_0\) 與這些角接觸的機率會遠大於與 \(L\) 其它部位接觸的機率,而在這些角上,會有很多權值等於 \(0\) ,這就是為什麼L1正則化可以產生稀疏模型,進而可以用於特徵選擇。
-
而正則化前面的係數 \(\lambda\) ,可以控制 \(L\) 圖形的大小。 \(\lambda\) 越小, \(L\) 的圖形越大(上圖中的黑色方框); \(\lambda\) 越大, \(L\) 的圖形就越小,可以小到黑色方框只超出原點範圍一點點,這是最優點的值 \((w_1,w_2)=(0,w_2)\) 中的 \(w_2\) 可以取到很小的值。
- 同理,又L2正則化損失函式: \(J = J_0 + \lambda \sum_w w^2\) ,同樣可畫出其在二維平面的影象,如下:
-
二維平面下L2正則化的函式圖形是個圓,與方形相比,被磨去了稜角。因此 \(J_0\) 與 \(L\) 相交時使得 \(w_1\) 或 \(w_2\) 等於零的機率小了許多,這就是為什麼L2正則化不具有稀疏性的原因。
4 L2正則化為什麼能防止過擬合
- 擬合過程中通常都傾向於讓權值儘可能小 ,最後構造一個所有引數都比較小的模型。因為一般認為引數值小的模型比較簡單,能適應不同的資料集,也在一定程度上避免了過擬合現象。 可以設想一下對於一個線性迴歸方程,若引數很大,那麼只要資料偏移一點點,就會對結果造成很大的影響;但如果引數足夠小,資料偏移得多一點也不會對結果造成什麼影響 ,專業一點的說法是 抗擾動能力強 。
- 為什麼L2正則化可以獲得值很小的引數?
- (1) 以線性迴歸中的梯度下降法為例。假設要求的引數為 \(\theta\) , \(h \theta (x)\) 是我們的假設函式,那麼線性迴歸的代價函式如下:
\[ J_{\theta} = \frac{1}{2n}\sum_{i=1}^n (h \theta (x^{(i)}) - y^{(i)})^2 ........(6)\] - (2)在梯度下降中 \(\theta\) 的迭代公式為:
\[\theta_j = \theta_j - \alpha \frac{1}{n} \sum_{i=1}^n (h \theta (x^{(i)}) - y^{(i)}) x_j^{(i)}........(7)\] - (3) 其中 \(\alpha\) 是learning rate。 上式是沒有新增L2正則化項的迭代公式,如果在原始代價函式之後新增L2正則化,則迭代公式為:
\[\theta_j = \theta_j(1- \alpha \frac{\lambda}{n}) - \alpha \frac{1}{n} \sum_{i=1}^n (h \theta (x^{(i)}) - y^{(i)}) x_j^{(i)} ........(8)\] - 其中 \(\lambda\) 就是正則化引數 。從上式可以看到,與未新增L2正則化的迭代公式相比,每一次迭代, \(\theta_j\) 都要先乘以一個小於1的因子,從而使得 \(\theta_j\) 不斷減小,因此總得來看, \(\theta\) 是不斷減小的。
最開始也提到L1正則化一定程度上也可以防止過擬合。之前做了解釋,當L1的正則化係數很小時,得到的最優解會很小,可以達到和L2正則化類似的效果。
5 正則化項的引數選擇
- L1、L2的引數 \(\lambda\) 如何選擇好 ?
- 以L2正則化引數為例:從公式(8)可以看到,λ越大, \(\theta_j\) 衰減得越快。另一個理解可以參考L2求解圖, \(\lambda\) 越大,L2圓的半徑越小,最後求得代價函式最值時各引數也會變得很小 ;當然也不是越大越好,太大容易引起欠擬合。
- 經驗
從0開始,逐漸增大 \(\lambda\) 。在訓練集上學習到引數,然後在測試集上驗證誤差。反覆進行這個過程,直到測試集上的誤差最小。一般的說,隨著 \(\lambda\) 從0開始增大,測試集的誤分類率應該是先減小後增大,交叉驗證的目的,就是為了找到誤分類率最小的那個位置。建議一開始將正則項係數λ設定為0,先確定一個比較好的learning rate。然後固定該learning rate,給 \(\lambda\) 一個值(比如1.0),然後根據validation accuracy,將λ增大或者減小10倍,增減10倍是粗調節,當你確定了 \(\lambda\) 的合適的數量級後,比如 \(\lambda= 0.01\) ,再進一步地細調節,比如調節為0.02,0.03,0.009之類。