L2.3 限制筆記頁數,或考前一天停止補習:正則化與提早停止
本篇重用M1.1從鞋子猜身高:Conditional Expectation·M0.0霧中下山:Gradient 與方向
起點:兩種不讓學生死背的方法
背考古題的學生:過擬合與欠擬合 裡那個把考古題全背下來的學生,有兩種完全不同的干預方式。
限制筆記頁數。 考試允許帶一張 A4 的手寫筆記。一張紙塞不下五年的題目與答案,所以他被迫寫下規則而不是答案。限制的是「他能記住多少」。
考前一天就停止補習。 課照上、筆記照抄,但在他開始逐題背答案之前就把時間切斷。限制的是「他有多少時間去記」。
兩件事的作用點看起來毫無關係——一個限制容量,一個限制時間。但它們的效果是同一個方向:都在阻止模型把有限的資料吃到最後一滴。
這一篇要做兩件事:把三種常見的做法(weight decay、提早停止、dropout)放在同一個座標上比較,然後證明前兩者不只是「效果類似」,而是幾乎同一條式子。
限制容量與限制時間,
為什麼會有同樣的效果?
它們的失效方式也一樣嗎?
課堂提問Q1
把「限制筆記頁數」翻成數學:加一項懲罰之後,最小化的東西變成什麼?那一項是怎麼影響解的——它把解往哪裡拉?以及,為什麼「懲罰參數的大小」會讓函數變平滑?
先想一想,再展開看整理後的答案
寫下來。 原本的目標是經驗風險 ;加上一項對參數大小的懲罰:
是「一頁筆記值多少分」的兌換率。 就是原本的 ERM, 把所有參數壓成零。
它把解往哪裡拉。 平方損失下有 closed form。令 是設計矩陣,,最小點滿足
把它投影到 的特徵向量上( 的特徵值 ),第 個分量是
也就是把無正則化的解逐方向乘上一個介於 與 的縮放。關鍵在那個縮放依賴 :曲率大的方向()幾乎不動,曲率小的方向()幾乎被砍掉。
為什麼這會讓函數變平滑。 曲率小的方向正是「資料沒怎麼約束的方向」——那裡有很多個 在訓練點上一樣好(背考古題的學生:過擬合與欠擬合 說過這就是過擬合的來源)。 在那些方向上選了範數最小的那一個,而範數小的多項式係數對應的函數振盪小。所以「懲罰參數」不是直接懲罰不平滑,而是在資料無法區分的方向上挑一個保守的答案。
這也已經預告了本篇的第二個結果:梯度下降從 出發,也是先把曲率大的方向學好、曲率小的方向要很久才動(霧中下山,一步該走多大:梯度下降的一頁 的每步收縮率是 )。兩件事在同一組方向上做同一種取捨——難怪它們的效果會一樣。
三種做法,同一個座標
把三種常見的正則化放在「它限制了什麼」這一欄上:
- weight decay(/ridge):限制參數的大小。逐方向的縮放 ,資料約束強的方向留著、弱的方向砍掉。
- 提早停止:限制訓練時間。梯度下降 步之後,第 個方向被學到的比例是 ——同樣是強的先學好、弱的還沒動。
- dropout:訓練時隨機把一部分單元設成零,限制模型依賴任何單一路徑的程度。在線性模型上它可以被算成一個與輸入尺度相關的 懲罰;在深層網路上它的效果更接近「同時訓練指數多個共享權重的子網路再平均」。
三者在 十個房仲各看一百間房:Bias 與 Variance 的座標上都往同一邊走:bias² 上升、variance 下降。所以它們共享同一個判準——只有當你目前是 variance 主導時,加它們才會賺;bias 主導時,加多少都是純虧。這一點在本篇最後會被量出來。
為什麼提早停止就是 ridge
把兩者都投影到 的特徵向量上,逐方向比較「學到了多少比例」。
Ridge(上面 Q1 算過):
梯度下降 步(從 出發,二次損失):每一步誤差乘上 ,所以
兩個函數的形狀非常像:都在 大的時候趨近 、 小的時候趨近 ,而轉折點分別在 與 。把兩個轉折點對起來(並注意 的導數帶一個 2):
提早停止不是「來不及訓練完」,它是一個隱含的 正則化,強度由 給。
這條對應有三個立刻可用的推論。一,提早停止的「正則化強度」和學習率綁在一起:同樣停在第 1000 步, 大兩倍等於 小兩倍。二,先大後小的學習率 schedule 同時在改變這個隱含的 ,所以「調 schedule」與「調 weight decay」不是兩個獨立的旋鈕。三,如果你已經用了明確的 weight decay,提早停止能再多買到的東西就有限了。
展開細節兩個比例函數的差別在哪裡,以及它對「谷底很平」的意義
與 不完全相同:前者在 時像 (線性趨零),後者像 (也線性趨零,斜率不同);在 轉折點時前者趨近 的速度是 ,後者是指數的 ,後者收得快得多。
實務上的意思是:提早停止在「已經學好的方向」上比 ridge 更接近無正則化解,在「還沒學到的方向」上兩者行為類似。所以兩條 U 形曲線的谷底高度幾乎一樣(本篇實測 對 ),但曲線的形狀不完全重合——本篇最後那張配對表在 小的時候差得比較多( 對 ), 大之後對到小數第三位。
另一個附帶的結論:既然兩條路的谷底幾乎一樣高,而 U 形的谷底通常很平,那麼「 或停止步數要調得多精準」的答案是不太需要。這和 該收資料、換模型,還是多訓幾輪:學習曲線 裡「提早停止不需要精準」是同一件事。
注意weight decay 在 Adam 上不是同一件事
上面的等價是在梯度下降上推的。用 Adam 時,如果把 weight decay 實作成「加在梯度上的一項」,那一項也會被 Adam 的 分母除掉——於是梯度大的座標,實際受到的衰減比較小。衰減強度變成隱含地依賴梯度尺度,而那不是任何人想要的。
AdamW 的修法是把衰減直接寫在更新上,不經過那個分母:
這也是為什麼同一個 在 SGD 與 Adam 之間不能直接搬——兩者的有效衰減強度差一個與梯度尺度有關的因子。細節見 一個 η 不夠用:動量與 Adam 各買到什麼 的 <Details>。
回到情境:什麼時候該加,什麼時候是純虧
判準只有一個:你現在是 variance 主導嗎? 十個房仲各看一百間房:Bias 與 Variance 的三項分解說得很清楚——正則化壓 variance、抬 bias²,所以它只在 variance 那一欄還有東西可壓的時候賺。判斷方法就是 該收資料、換模型,還是多訓幾輪:學習曲線 的兩條曲線:間距大 → 有得賺;兩線已經重合在高原 → 加什麼都是虧。
三者怎麼挑。 weight decay 幾乎沒有額外成本,是預設值;提早停止是免費的(只要有一份驗證集),而且它同時省訓練時間;dropout 在全連接層上有效,在有正規化層的卷積/注意力架構上常常被正規化層取代。實務上三者混用,而且混用之後每一個的最佳強度都會變小——它們在壓同一個東西。
這一切依賴什麼。 一,上面的 closed form 與等價是平方損失+線性模型的結果;非線性模型上只剩「同一個方向」這個定性結論。二, 對所有座標一視同仁,所以它依賴特徵的尺度——沒有標準化過的特徵,同一個 對不同座標的實際強度差好幾個數量級(又一次回到 霧中下山,一步該走多大:梯度下降的一頁 的那件事)。三,bias 項通常不該被衰減(它不控制平滑度,只控制平移)。
回到情境:把兩條路徑量出來
共用 toy()、二十次多項式(刻意選在過擬合區),特徵每欄標準化。
第一段:ridge 的 掃描。
import numpy as np
from ml_toy import toy_1d, truth, NOISE
xs, ys = truth(); x, y = toy_1d(n=30, seed=0); n = len(x); D = 20
mx = np.abs(np.vander(np.linspace(0,1,80), D+1, increasing=True)).max(0)
B = lambda X: np.vander(X, D+1, increasing=True)/mx
A, As = B(x), B(xs)
risk = lambda w: ((As@w - ys)**2).mean() + NOISE**2
for lam in (0, 1e-8, 1e-6, 1e-4, 1e-3, 1e-2, 1e-1, 1, 10):
w = np.linalg.solve(A.T@A + lam*n*np.eye(D+1), A.T@y)
print(f" λ={lam:<8} 訓練 {((A@w-y)**2).mean():.4f} 真實風險 {risk(w):.4f}")
λ=0 訓練 0.0106 真實風險 0.0321
λ=1e-08 訓練 0.0129 真實風險 0.0288
λ=1e-06 訓練 0.0134 真實風險 0.0292
λ=0.0001 訓練 0.0208 真實風險 0.0406
λ=0.001 訓練 0.0578 真實風險 0.0831
λ=0.01 訓練 0.1246 真實風險 0.1709
λ=0.1 訓練 0.1898 真實風險 0.2902
λ=1 訓練 0.3139 真實風險 0.4439
λ=10 訓練 0.3929 真實風險 0.5001
又是一個 U 形,谷底在 ()。 訓練誤差單調上升()——這是必然的,因為 時我們不再最小化訓練誤差。而真實風險先降後升: 從 到 買到 的改善,之後每加一個數量級都在變差, 已經比只用一條直線還糟(背考古題的學生:過擬合與欠擬合 的 是 )。 太大就是欠擬合,而且是自己造出來的。
第二段:提早停止,同一個模型、。
w = np.zeros(D+1); eta = 1.8/np.linalg.eigvalsh(A.T@A/n)[-1]
for t in range(1, 1000001):
w -= eta*(A.T@(A@w - y))/n
第 30 步 訓練 0.1397 真實風險 0.1896
第 100 步 訓練 0.1265 真實風險 0.1617
第 300 步 訓練 0.1008 真實風險 0.1312
第 1,000 步 訓練 0.0546 真實風險 0.0787
第 3,000 步 訓練 0.0294 真實風險 0.0526
第 10,000 步 訓練 0.0194 真實風險 0.0404
第 100,000 步 訓練 0.0137 真實風險 0.0301
第 1,000,000 步 訓練 0.0134 真實風險 0.0289
最好的風險是 ——對照 ridge 的 。兩個完全不同的干預,最佳風險差在小數第四位。
第三段:把兩條路徑逐點配對。 用 (這裡 ):
t= 300 提早停止 0.1312 ridge λ=2.18e-03 → 0.1131
t= 3,000 提早停止 0.0526 ridge λ=2.18e-04 → 0.0493
t= 30,000 提早停止 0.0319 ridge λ=2.18e-05 → 0.0323
t=300,000 提早停止 0.0293 ridge λ=2.18e-06 → 0.0294
後兩列對到小數第三位(/,/)。前兩列差得比較多(/),原因寫在上面的 <Details> 裡:兩個比例函數在「已經學好的方向」上收斂速度不同, 小的時候那個差別還沒被抹平。
提早停止與 weight decay 不是兩個獨立的正則化,是同一條路徑的兩種刻度。
刻意違反:對一個欠擬合的模型加 weight decay。
degree 2: λ=0 0.2668 λ=1e-06 0.2668 λ=0.001 0.2673 λ=0.1 0.3456
degree 20: λ=0 0.0320 λ=1e-06 0.0292 λ=0.001 0.0831 λ=0.1 0.2902
degree 2 那一列沒有任何 能改善:,單調變差。degree 20 那一列則有一個真的谷底()。
原因是 十個房仲各看一百間房:Bias 與 Variance 的三項分解:degree 2 的 variance 只有 ,而 bias² 是 。正則化能壓的是那 ,代價是抬高那已經很大的 ——要壓的東西幾乎不存在,要付的代價卻照付。
這就是實務上最貴的一種誤診:模型表現不好 → 加正則化 → 更差 → 加更多。加正則化之前先做 該收資料、換模型,還是多訓幾輪:學習曲線 的兩條曲線,看間距還有沒有東西可以壓。
兩個刻度,一條路徑
互動 demo:ridge 的 λ 與提早停止的步數走的是同一條路徑,對應關係大約是 λ ≈ 1/(ηt)。
先消化一下
參考文獻
- Hoerl, A. E., Kennard, R. W. Ridge Regression: Biased Estimation for Nonorthogonal Problems. Technometrics 1970.(ridge 的原始論文與逐方向縮放 的來源。)
- Yao, Y., Rosasco, L., Caponnetto, A. On Early Stopping in Gradient Descent Learning. Constructive Approximation 2007.(提早停止作為隱含正則化的嚴格版本,含收斂率與 的對應。)
- Srivastava, N. et al. Dropout: A Simple Way to Prevent Neural Networks from Overfitting. JMLR 2014.(dropout 的原始論文;線性模型上與 的關係、以及「訓練指數多個子網路」的解讀都在這裡。)