L2.3 限制筆記頁數,或考前一天停止補習:正則化與提早停止
兩種不讓學生死背的方法
背考古題的學生:過擬合與欠擬合 裡那個把考古題全背下來的學生,有兩種完全不同的干預方式。
限制筆記頁數。 考試允許帶一張 A4 的手寫筆記。一張紙塞不下五年的題目與答案,所以他被迫寫下規則而不是答案。限制的是「他能記住多少」。
考前一天就停止補習。 課照上、筆記照抄,但在他開始逐題背答案之前就把時間切斷。限制的是「他有多少時間去記」。
一個限制能寫下多少,另一個限制練多久;它們都可能避免死背,也都可能連重要規則一起限制掉。這些做法究竟限制了哪些答案? 我們先用線性模型把這件事算出來,再看什麼時候對新資料有幫助。
限制容量與限制時間,
為什麼會有同樣的效果?
它們的失效方式也一樣嗎?
課堂提問Q1
把「限制筆記頁數」翻成數學:加一項懲罰之後,最小化的東西變成什麼?那一項是怎麼影響解的——它把解往哪裡拉?以及,為什麼「懲罰參數的大小」會讓函數變平滑?
先想一想,再展開看整理後的答案
寫下來。 原本的目標是經驗風險 ;加上一項對參數大小的懲罰:
決定我們願意用多少訓練誤差換取較小的參數。兩項都放 是為了讓梯度公式簡單; 回到最小平方,這裡若所有座標都被懲罰, 會把參數壓向零。
它把解往哪裡拉。 平方損失下有 closed form。令 是設計矩陣,,最小點滿足
把它投影到 的特徵向量上( 的特徵值 ),第 個分量是
也就是把無正則化的解逐方向乘上一個介於 與 的縮放。關鍵在那個縮放依賴 :曲率大的方向()幾乎不動,曲率小的方向()幾乎被砍掉。
參數小,為什麼可能限制振盪? 固定特徵 時,。參數範數因此能限制這組特徵下的變化;但換一種特徵尺度,限制就不同。小曲率代表訓練誤差對某個方向不敏感,不代表那裡所有參數都同樣好;只有零曲率才可能完全無法區分。
這也已經預告了本篇的第二個結果:梯度下降從 出發,也是先把曲率大的方向學好、曲率小的方向要很久才動(霧中下山,一步該走多大:梯度下降的一頁 的每步收縮率是 )。兩件事在同一組方向上做同一種取捨——難怪它們的效果會一樣。
三種做法,同一個座標
把三種常見的正則化放在「它限制了什麼」這一欄上:
- weight decay(/ridge):限制參數的大小。逐方向的縮放 ,資料約束強的方向留著、弱的方向砍掉。
- 提早停止:限制訓練時間。梯度下降 步之後,第 個方向被學到的比例是 ——同樣是強的先學好、弱的還沒動。
- dropout:訓練時隨機把一部分單元設成零,限制模型依賴任何單一路徑的程度。在線性模型上它可以被算成一個與輸入尺度相關的 懲罰;在深層網路上它的效果更接近「同時訓練指數多個共享權重的子網路再平均」。
在簡單線性例子中,這些限制常用偏差換取較低的變異數;但這不是任意深層網路上的單調定理。要判斷值不值得,仍須比較驗證表現,也要排除資料、最佳化與模型容量的問題。
圖說: ridge 與 early stopping 都從原點朝無正則化解前進,並優先學會曲率大的方向。
提早停止與 ridge,限制的是哪些方向?
把兩者都投影到 的特徵向量上,逐方向比較「學到了多少比例」。
Ridge(上面 Q1 算過):
梯度下降 步(從 出發,二次損失):每一步誤差乘上 ,所以
假設 ,這些比例會由零逐漸增加。當 小時,可用指數近似:兩個轉折尺度分別是 與 。把尺度對起來,就得到
提早停止也在篩選特徵方向,但它的縮放因子與 ridge 不同; 是相似尺度,不是讓所有方向完全相等的參數。
這也說明停止步數要和學習率一起看:同樣 1000 步,不同 學到的比例不同。若使用 schedule,就要比較各步縮放因子的乘積;不能直接套一個固定的 。明確正則化與提早停止可以同時使用,是否還有改善要另外驗證。
展開細節兩個比例函數的差別在哪裡,以及它對「谷底很平」的意義
與 不完全相同:前者在 時像 (線性趨零),後者像 (也線性趨零,斜率不同);在 轉折點時前者趨近 的速度是 ,後者是指數的 ,後者收得快得多。
實務上的意思是:提早停止在「已經學好的方向」上比 ridge 更接近無正則化解,在「還沒學到的方向」上兩者行為類似。所以兩條 U 形曲線的谷底高度幾乎一樣(本篇實測 對 ),但曲線的形狀不完全重合——本篇最後那張配對表在 小的時候差得比較多( 對 ), 大之後對到小數第三位。
這個例子的最佳風險接近,只是實驗觀察,不保證其他資料的兩個最佳解也接近。調整時應看驗證曲線的敏感程度,而不是預先假設谷底一定很平。
注意weight decay 在 Adam 上不是同一件事
上面的等價是在梯度下降上推的。用 Adam 時,如果把 weight decay 實作成「加在梯度上的一項」,那一項也會被 Adam 的 分母除掉——於是梯度大的座標,實際受到的衰減比較小。衰減強度變成隱含地依賴梯度尺度,而那不是任何人想要的。
AdamW 的修法是把衰減直接寫在更新上,不經過那個分母:
這也是為什麼同一個 在 SGD 與 Adam 之間不能直接搬——兩者的有效衰減強度差一個與梯度尺度有關的因子。細節見 一個 η 不夠用:動量與 Adam 各買到什麼 的 <Details>。
什麼時候該加,什麼時候是純虧
先問誤差的來源。 訓練誤差低、驗證誤差高時,限制模型值得一試;兩者都高時,先檢查容量、資料與最佳化。這些是線索,不是只靠兩個數字就能確定的 bias–variance 分解。
怎麼比較? 固定資料切分與其他設定,先比較少量強度。提早停止雖可能省訓練時間,選停止時刻仍在使用驗證集;最後表現需要獨立測試集。幾種做法可以混用,但最佳強度沒有必然的大小關係。
這一切依賴什麼。 一,上面的 closed form 與等價是平方損失+線性模型的結果;非線性模型上只剩「同一個方向」這個定性結論。二, 對所有座標一視同仁,所以它依賴特徵的尺度——沒有標準化過的特徵,同一個 對不同座標的實際強度差好幾個數量級(又一次回到 霧中下山,一步該走多大:梯度下降的一頁 的那件事)。三,bias 項通常不該被衰減(它不控制平滑度,只控制平移)。
把兩條路徑量出來
共用 toy()、二十次多項式。下列特徵使用各欄最大絕對值縮放,不是零均值、單位變異數的標準化。高次單項式的 normal equations 仍可能非常病態;表中的數字是實驗紀錄,不應當成精確最小值的證明。
第一段: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
這次掃描的最佳值在 附近;太大的 會把重要方向一起壓掉。若比較的是同一個問題的精確 ridge 最小解,隨 增大,參數範數不增、訓練誤差不減;「不減」允許相等,不代表每一格都嚴格變大。數值病態時還要先確認求解器的誤差。
第二段:提早停止,同一個模型、。
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。
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 的原始論文;線性模型上與 的關係、以及「訓練指數多個子網路」的解讀都在這裡。)