玩統計機器學習筆記

正則化與訓練實務Regularization & Training Practice

掌握 L2 懲罰、dropout、資料擴增與提早停止等正則化方法,並學會有系統地調校超參數、檢查梯度與管理 GPU 記憶體。

第 9 章,共 11 章|初版 2019 年 4 月・2026 年 10 月修訂

本章內容
  1. 9.1正則化方法總覽
  2. 9.2L2 與 L1 懲罰
  3. 9.3丟棄法
  4. 9.4資料擴增與提早停止
  5. 9.5超參數調校
  6. 9.6梯度檢查
  7. 9.7實務技巧
  8. 9.8GPU 記憶體
  9. 9.9參考資料

模型在訓練集上表現很好、在開發集上卻差了一截,是深度學習最常見的狀況之一。依照第 1 章的偏誤與變異分析,這代表變異過高,也就是過擬合(overfitting)。最可靠的解法是收集更多資料,但資料往往昂貴,甚至根本無法取得,這時正則化(regularization)就是第一道防線。

這一章前半整理常用的正則化方法,後半則是訓練神經網路時的實務經驗:如何有系統地調校超參數、如何確認反向傳播沒有寫錯、有哪些值得養成的訓練習慣,以及 GPU 記憶體不夠時該怎麼辦。

9.1正則化方法總覽Overview of Regularization

狹義的正則化,是指在損失函數中加入懲罰項;但在深度學習的語境中,「正則化」通常採取更廣的意義:任何能降低過擬合、讓模型在新資料上表現更好的方法,即使它會讓訓練集誤差稍微上升。

方法 做法 特性
懲罰項(L2/L1) 在損失函數加上權重大小的懲罰 最基本,幾乎都會使用;多一個超參數 λ\lambda
Dropout 訓練時隨機關閉部分神經元 在電腦視覺等大型網路中效果顯著
資料擴增 對訓練資料做不改變標籤的變換 近似免費增加資料,但需要額外的設計與運算
提早停止 開發集誤差開始上升時停止訓練 簡單,但同時影響偏誤與變異,不符合正交化

9.2L2 與 L1 懲罰Weight Penalties

L2 正則化

以二元分類的交叉熵成本函數為例,加入 L2 懲罰後的成本函數為:

Jreg=−1m∑i=1m[y(i)log⁡a(i)+(1−y(i))log⁡(1−a(i))]+λ2m∑l=1L∥W[l]∥F2 J_{\text{reg}} = -\frac{1}{m} \sum_{i=1}^{m} \Big[ y^{(i)} \log a^{(i)} + \big(1-y^{(i)}\big) \log\big(1-a^{(i)}\big) \Big] + \frac{\lambda}{2m} \sum_{l=1}^{L} \big\lVert W^{[l]} \big\rVert_F^2

其中 a(i)a^{(i)} 是第 ii 筆資料的模型輸出,mm 是樣本數;∥W[l]∥F2=∑i∑j(wij[l])2\lVert W^{[l]} \rVert_F^2 = \sum_{i}\sum_{j} \big(w^{[l]}_{ij}\big)^2 是第 ll 層權重矩陣所有元素的平方和,也就是弗羅貝尼烏斯範數(Frobenius norm)的平方。λ\lambda 稱為正則化參數,是需要在開發集上調校的超參數:λ\lambda 越大,正則化效果越強。偏差項 b[l]b^{[l]} 的參數量相對很少,通常不納入懲罰。

反向傳播時,懲罰項對 W[l]W^{[l]} 的梯度是 λmW[l]\frac{\lambda}{m} W^{[l]},因為 λ2m\frac{\lambda}{2m} 中的 2 正好與平方微分後的 2 抵消:

dW[l]=1m dZ[l]A[l−1]⊤+λm W[l] dW^{[l]} = \frac{1}{m}\, dZ^{[l]} A^{[l-1]\top} + \frac{\lambda}{m}\, W^{[l]}

為什麼稱為權重衰減

把這個梯度代入更新式並整理:

W[l]←W[l]−α dW[l]=(1−αλm)W[l]−αm dZ[l]A[l−1]⊤ W^{[l]} \leftarrow W^{[l]} - \alpha\, dW^{[l]} = \Big(1 - \frac{\alpha \lambda}{m}\Big) W^{[l]} - \frac{\alpha}{m}\, dZ^{[l]} A^{[l-1]\top}

每一步在做一般的梯度更新之前,都先把權重乘上一個略小於 1 的係數 (1−αλ/m)(1 - \alpha\lambda/m),讓權重逐步縮小,因此 L2 正則化也稱為權重衰減(weight decay)。

為什麼能減少過擬合

λ\lambda 很大時,最佳化會把權重推向 0 附近。一種直覺是:許多隱藏單元的影響因此變得很小,網路的有效容量下降,表現得更像一個簡單的模型。另一種直覺來自激勵函數:以 tanh 為例,權重小時,z=Wa+bz = Wa + b 也落在 0 附近,而 tanh 在 0 附近幾乎是線性的。每一層都接近線性,整個網路就難以擬合過於曲折的決策邊界,因此較不容易過擬合。

L2 與 L1 的比較

懲罰 形式 對權重的效果 特性
L2 λ2m∥W∥F2\frac{\lambda}{2m}\lVert W \rVert_F^2 權重整體變小,但很少剛好為 0 沒有特徵選擇效果;預設選擇
L1 λm∥W∥1\frac{\lambda}{m}\lVert W \rVert_1 部分權重變成剛好為 0 稀疏解,有特徵選擇效果

兩者的差異來自梯度。L2 懲罰的梯度與權重本身成正比,權重越接近 0,被推回去的力量就越小,所以權重只會變小、很少歸零。L1 懲罰(∥W∥1=∑i,j∣wij∣\lVert W \rVert_1 = \sum_{i,j} \lvert w_{ij} \rvert)的梯度則是固定大小的 ±λ/m\pm\lambda/m,即使權重已經很小,仍以同樣的力道把它推向 0,搭配軟門檻(proximal)等求解方式時,許多權重會剛好變成 0(單純的次梯度下降則只會讓它們在 0 附近擺盪)。在線性模型中,這正是 Ridge 迴歸與 Lasso 迴歸的差別(見第 3 章)。在神經網路中,L1 帶來的稀疏性很少真正節省運算,因此 L2 是預設選擇。

9.3丟棄法Dropout

丟棄法(dropout)在每一次訓練迭代中,讓每個神經元以機率 1−p1 - p 被暫時「關掉」(輸出設為 0),只用其餘的神經元進行前向與反向傳播。pp 稱為保留機率(keep_prob)。每次迭代關掉的神經元都不同,等於每一步都在訓練一個隨機抽樣出來的、較小的子網路。

反向 dropout 的實作

最常見的實作方式是反向 dropout(inverted dropout)。以某一層的激勵值 a 為例:

import numpy as np

keep_prob = 0.8  # 每個神經元被保留的機率

# 前向傳播
d = np.random.rand(*a.shape) < keep_prob  # 布林遮罩,約 80% 為 True
a = a * d / keep_prob                     # 關掉部分神經元,並放大其餘的值

# 反向傳播:使用同一個遮罩
da = da * d / keep_prob

除以 keep_prob 是關鍵:保留下來的神經元輸出被放大 1/p1/p 倍,使得激勵值的期望不變(因為 E[d]=p\mathbb{E}[d] = p,所以 E[a⋅d/p]=a\mathbb{E}[a \cdot d / p] = a)。如此一來,下一層收到的輸入在訓練與測試時尺度一致。

測試時不使用 dropout

測試或部署時不使用 dropout:若預測時也隨機關閉神經元,同一筆資料每次會得到不同的預測結果。由於訓練時已經用 1/p1/p 做了補償,測試時直接使用完整網路即可,不需要再乘上任何與 keep_prob 有關的係數。

為什麼有效

從單一神經元的角度來看,它的任何一個輸入都可能隨時消失,因此不能把權重押在少數幾個輸入上,而必須把權重分散到許多輸入。權重分散的結果,是權重的平方和變小,效果與 L2 正則化類似。另一個角度是:每次迭代訓練不同的子網路,最後的完整網路可以看成大量子網路的近似平均,帶有集成(ensemble)的效果。

不同層可以設定不同的保留機率:參數多、容易過擬合的層(例如大型全連接層)可用較低的 pp(如 0.5),參數少的層用較高的 pp,輸入層通常設為 1.0 或接近 1.0。早期的電腦視覺網路(如 AlexNet、VGG)在大型全連接層大量使用 dropout;現代卷積網路則多半改以批次正規化、資料擴增與權重衰減為主,dropout 至多用在分類層之前。

9.4資料擴增與提早停止Data Augmentation & Early Stopping

資料擴增

收集更多資料是降低變異最可靠的方法,但成本很高。資料擴增(data augmentation)是在現有資料上做不改變標籤的變換,產生額外的訓練樣本。以影像為例,常見的做法包括:

  • 水平翻轉
  • 隨機裁切(random crop)與縮放
  • 小角度旋轉
  • 色彩擾動(color jitter):隨機調整亮度、對比與飽和度

擴增出來的資料提供的資訊不如真正的新資料(翻轉後的貓仍是同一隻貓),但幾乎不花收集成本。要注意變換必須合理:例如辨識文字或數字時,水平翻轉會產生不存在的字元;醫學影像的左右方向本身可能就具有意義。設計適合任務的擴增方式需要領域知識與人工嘗試,大量擴增也會增加訓練時間。

提早停止

訓練時同時記錄訓練集與開發集的誤差。隨著迭代次數增加,訓練誤差持續下降,開發集誤差則通常先下降、再開始上升。提早停止(early stopping)就是在開發集誤差最低時停止訓練,或回到當時保存的參數。由於權重從接近 0 的初始值開始,通常越訓練越大,提早停止可以讓權重維持在中等大小,效果與 L2 正則化相近。它的好處是只需要訓練一次,就能沿著訓練過程掃過「不同強度的正則化」,不必像 L2 那樣嘗試許多個 λ\lambda。

9.5超參數調校Hyperparameter Tuning

神經網路的超參數很多,而且沒有一組放諸四海皆準的最佳設定:不同領域、不同資料集,甚至同一個問題在資料量或硬體改變之後,最佳值都可能不同。經驗非常寶貴,但同樣重要的是有系統的搜尋方法。至於偏誤或變異過高時應優先調整哪些旋鈕,請見第 1 章。

符號與重要性

描述網路中某一個數值時,常用的符號是 aj[l]{t}(i)a_j^{[l]\{t\}(i)}:第 ll 層、第 jj 個神經元、第 tt 個小批次中第 ii 筆資料的激勵值。依照 Andrew Ng 的經驗,主要超參數的重要性大致如下:

超參數 符號 優先順序
學習率 α\alpha 第一優先
動量係數 ρ\rho(或 β\beta) 第二優先
小批次大小 BB 第二優先
隱藏單元數 n[l]n^{[l]} 第二優先
隱藏層數 LL 第三優先
學習率衰減 衰減率 rr 第三優先
Adam 的 β1,β2,ϵ\beta_1, \beta_2, \epsilon — 通常使用預設值

學習率幾乎總是最重要的一個:它設定錯誤時,其他超參數再怎麼調整也無濟於事。

隨機搜尋優於網格搜尋

網格搜尋(grid search)在每個超參數上取幾個固定值,再試遍所有組合;隨機搜尋(random search)則在範圍內隨機抽樣組合。超參數很多時,隨機搜尋明顯較有效率(Bergstra & Bengio, 2012),原因是我們事先不知道哪個超參數最重要。假設要調整 α\alpha 與 ϵ\epsilon,用 5×55 \times 5 的網格試了 25 次,但 ϵ\epsilon 幾乎不影響結果,實際上只試了 5 個不同的 α\alpha;隨機搜尋同樣試 25 次,就能試到 25 個不同的 α\alpha。

找到表現較好的區域後,可以縮小範圍,在該區域內更密集地抽樣,這稱為由粗到細(coarse to fine)的搜尋。

在對數尺度上抽樣

隨機抽樣不代表要在範圍內均勻抽樣。例如學習率的合理範圍是 10−410^{-4} 到 11,若均勻抽樣,約 90% 的樣本會落在 0.1 到 1 之間,較小的數量級幾乎沒有被探索。正確的做法是在對數尺度上均勻抽樣:

r∼U[−4, 0],α=10r r \sim \mathcal{U}[-4,\, 0], \qquad \alpha = 10^{r}

動量係數 ρ\rho 也是如此。當 ρ\rho 介於 0.9 到 0.999 時,結果對接近 1 的變化特別敏感:ρ\rho 從 0.999 變成 0.9995,平均的步數就從約 1000 步變成約 2000 步(見第 8 章)。因此應該對 1−ρ1 - \rho 在對數尺度上抽樣:令 1−ρ=10r1 - \rho = 10^{r},r∼U[−3, −1]r \sim \mathcal{U}[-3,\, -1]。

兩種調校風格

運算資源有限時,可以專心照顧單一模型:每天觀察學習曲線,逐步調整學習率等設定。資源充足時,則可以同時平行訓練大量不同設定的模型,最後挑出表現最好的一個。Andrew Ng 把這兩種方式分別比喻為熊貓(panda,一次只照顧一隻幼獸)與魚子醬(caviar,一次產下大量魚卵)。

9.6梯度檢查Gradient Checking

自行實作反向傳播時很容易寫錯,而且這類錯誤不一定會讓訓練失敗,只是讓模型學得比較差,很難察覺。梯度檢查(gradient checking)以數值微分來驗證反向傳播算出的梯度是否正確。

中央差分

把所有參數(各層的 W[l]W^{[l]} 與 b[l]b^{[l]})攤平成一個長向量 θ∈Rp\theta \in \mathbb{R}^p。對每一個分量 θk\theta_k,計算:

dθkapprox=J(θ1,…,θk+ϵ,…,θp)−J(θ1,…,θk−ϵ,…,θp)2ϵ d\theta_k^{\text{approx}} = \frac{J(\theta_1, \dots, \theta_k + \epsilon, \dots, \theta_p) - J(\theta_1, \dots, \theta_k - \epsilon, \dots, \theta_p)}{2\epsilon}

這是中央差分(centered difference),誤差為 O(ϵ2)O(\epsilon^2);若只用單邊差分 (J(θ+ϵ)−J(θ))/ϵ\big(J(\theta + \epsilon) - J(\theta)\big)/\epsilon,誤差則是 O(ϵ)O(\epsilon),準確度差很多。ϵ\epsilon 常取 10−710^{-7} 左右。

判斷標準

把數值梯度 dθapproxd\theta^{\text{approx}} 與反向傳播得到的 dθd\theta 比較,使用相對誤差:

∥dθapprox−dθ∥2∥dθapprox∥2+∥dθ∥2 \frac{\lVert d\theta^{\text{approx}} - d\theta \rVert_2}{\lVert d\theta^{\text{approx}} \rVert_2 + \lVert d\theta \rVert_2}

使用相對誤差而非絕對差距,是為了不受梯度本身大小的影響。

相對誤差 判斷
約 10−710^{-7} 或更小 正確
約 10−510^{-5} 可能有問題,需要逐一檢查各分量
約 10−310^{-3} 或更大 很可能有錯誤

若檢查失敗,可以找出差距最大的分量,看它們集中在哪一層、屬於 dWdW 還是 dbdb,藉此縮小錯誤的範圍。

注意事項

  • 只用於除錯:每個分量都需要兩次前向傳播,參數有數百萬個時非常慢。確認正確之後就關閉,不要在訓練過程中執行。
  • 記得包含正則化項:如果成本函數含有 L2 懲罰,JJ 與 dθd\theta 都必須把它算進去。
  • 不能搭配 dropout:dropout 讓 JJ 每次計算的結果都不同,數值梯度失去意義。檢查時先把 keep_prob 設為 1,確認無誤後再開啟 dropout。
  • 使用雙精度浮點數:ϵ\epsilon 很小時,單精度的捨入誤差可能蓋過真正的差距。

9.7實務技巧Training Tips

以下是訓練神經網路時值得養成的習慣:

  • 每個 epoch 重新打亂資料:若每次都以相同順序切出小批次,梯度估計會帶有資料順序造成的偏差。每個 epoch 開始前重新洗牌(shuffle),讓每次的小批次組合都不同。
  • 訓練多少個 epoch:30 個 epoch 可以作為初次嘗試的起點,但並非固定規則。資料量、模型大小與學習率排程都會影響需要的 epoch 數,應以開發集的學習曲線判斷是否已經收斂。
  • 遷移學習(transfer learning):自己的資料不多時,先用在大型資料集(例如 ImageNet)上預訓練好的權重初始化模型,再以自己的資料微調(fine-tune)。這通常比從頭訓練快得多,效果也更好(見第 10 章)。
  • 保存檢查點並重新啟動:定期保存模型參數(checkpoint),訓練中斷時就能從最近的檢查點繼續,不必從頭開始;也可以從表現好的檢查點出發,調整設定後重新訓練幾次,比較結果。

集成與多重裁切

模型集成(model ensembling)是獨立訓練多個模型,預測時取它們輸出的平均;多重裁切(multi-crop)則是在測試時對同一張影像取多個裁切版本(例如四個角落與中央,再加上它們的水平翻轉,共 10 張),分別預測後取平均。兩者通常能讓準確率再提升一些,在競賽與學術基準測試中很常見。

9.8GPU 記憶體GPU Memory

訓練深度網路時,GPU 記憶體常常是最先碰到的限制。需要放進記憶體的內容包括:

  • 模型參數:例如 VGG-16 約有 1.38 億個參數,以 32 位元浮點數儲存約需 550 MB。
  • 梯度與最佳化器狀態:梯度與參數一樣大;動量法另需一份速度,Adam 則需要兩份(一階與二階動差)。
  • 中間激勵值:反向傳播需要用到前向傳播時每一層的輸出,這部分與批次大小成正比,在大型卷積網路中通常佔最多。

以 2019 年前後常見的訓練環境為例,VGG-16 所需的 GPU 記憶體大約如下:

網路 批次大小 所需 GPU 記憶體(約)
VGG-16 64 8 GB
VGG-16 128 14 GB

這些數字會隨框架、輸入尺寸與實作方式而不同,只能作為數量級的參考;但可以看出,批次大小加倍時記憶體需求大幅增加,增加的部分主要來自激勵值。

記憶體不足時,可以考慮以下做法:

  1. 縮小批次大小:最直接的方法。若希望維持原本的有效批次大小,可以使用梯度累積(gradient accumulation),累積數個小批次的梯度後才更新一次參數。批次大小改變時,學習率通常也需要重新調整。
  2. 縮小模型:減少層數或通道數,或改用參數效率較高的架構。
  3. 分散到多張 GPU:資料平行(data parallelism)讓每張 GPU 持有一份完整模型、各自處理批次的一部分;模型大到單張 GPU 放不下時,則用模型平行(model parallelism)把不同的層放到不同的 GPU 上。

此外,混合精度訓練(mixed precision training)以 16 位元浮點數儲存激勵值並進行大部分運算,只在需要精度的地方保留 32 位元,能大幅降低記憶體用量並加快運算,是現今訓練大型模型的標準做法。

9.9參考資料References

  • Goodfellow, Bengio & Courville, Deep Learning, MIT Press, 2016,第 7 章 Regularization for Deep Learning、第 11 章 Practical Methodology。
  • Srivastava, Hinton, Krizhevsky, Sutskever & Salakhutdinov, "Dropout: A Simple Way to Prevent Neural Networks from Overfitting", JMLR, 2014。
  • Bergstra & Bengio, "Random Search for Hyper-Parameter Optimization", JMLR, 2012。
  • Loshchilov & Hutter, "Decoupled Weight Decay Regularization", ICLR 2019。
  • Simonyan & Zisserman, "Very Deep Convolutional Networks for Large-Scale Image Recognition", ICLR 2015(VGG-16)。
  • Micikevicius et al., "Mixed Precision Training", ICLR 2018。
  • deeplearning.ai, Improving Deep Neural Networks: Hyperparameter Tuning, Regularization and Optimization(Coursera 深度學習專項課程第二門課);Stanford CS231n 課程筆記(梯度檢查)。