本系列第 13 篇|這篇回答:模型說它「學會了」,實際上調整了什麼?又是往哪個方向調? 讀完這篇,你應該能:
- 用參數、預測、損失三件事說明訓練在做什麼
- 手算一步梯度下降,並說明學習率太大或太小會發生什麼
- 說明正則化與提早停止為什麼能減輕過擬合,並讀懂訓練與驗證損失曲線
一、學習就是調參數,讓損失變小
訓練就是調整參數,讓預測和答案的差距(損失)越來越小。
詳細說明
說模型學會了,指的是參數(parameter)被調整過。參數一變,預測就變;預測和正確答案的差距被收成損失;訓練要讓這個損失在訓練資料上變小。
模型是帶參數的函數 ŷ = f(x; θ)。θ 是全部參數。最簡單的例子是線性模型 ŷ = w·x + b,參數是權重(weight)w 與偏差(bias)b。訓練前這些參數是隨機值或 0,預測很差。
差距要收成一個能比較的數字,靠的是損失函數(loss function)。迴歸常用均方誤差(MSE):MSE = (1/n) Σ (yᵢ − ŷᵢ)²。每一筆先算答案和預測的差,平方之後再對 n 筆平均。平方使差得更遠的筆,在平均裡佔得更重。
分類常用交叉熵(cross-entropy)。模型給正確類別的機率若是 p,這一筆的損失是 −ln p。p 越接近 1,損失越接近 0。p = 0.5 時,−ln 0.5 ≈ 0.693;p = 0.1 時,−ln 0.1 ≈ 2.303。對正確答案越沒把握,罰得越重。
找出讓訓練資料平均損失最小的參數,就是最佳化(optimization)。
資料學出來的是參數,例如 w 與 b。人在訓練前決定的是超參數(hyperparameter),例如學習率、正則化強度、訓練輪數、樹的深度,用驗證集(validation set)挑選(第 12 篇)。
訓練損失變小,表示這批訓練資料上的平均損失變低。泛化(generalization)問的是沒看過的資料上也表現好。過擬合(overfitting)的定義見第 12 篇。
二、梯度下降、正則化與學習曲線
梯度下降
沿著讓損失下降最快的方向走一小步,步長由學習率決定。
詳細說明
損失對每個參數的偏導數(partial derivative)排成一個向量,就是梯度(gradient)。它指向損失上升最快的方向。梯度下降(gradient descent)沿反方向走一小步:
θ ← θ − η · ∂L/∂θ
η 是學習率(learning rate),決定這一步的長度。
只用一個參數就能把手算走完。令 L(w) = (w − 3)²,最小值在 w = 3,導數 dL/dw = 2(w − 3)。從 w = 0、η = 0.1 出發。
- 梯度 = 2(0 − 3) = −6。w = 0 − 0.1 × (−6) = 0.6。
- 梯度 = 2(0.6 − 3) = −4.8。w = 0.6 − 0.1 × (−4.8) = 0.6 + 0.48 = 1.08。
- 梯度 = 2(1.08 − 3) = −3.84。w = 1.08 − 0.1 × (−3.84) = 1.08 + 0.384 = 1.464。
梯度在起點是負的,上升最快的方向朝向更小的 w;減去「學習率乘上這個負數」,w 就往 3 的方向移動。一步的長度是 η 乘梯度,所以這三步停在 0.6、1.08、1.464,最小值 3 仍在前面。
下面這段程式印出同樣的三步。
w, lr = 0.0, 0.1
for step in range(3):
grad = 2 * (w - 3)
w = w - lr * grad
print(step + 1, round(w, 3))
# 1 0.6
# 2 1.08
# 3 1.464
這三步有固定的縮法。更新後離 3 的距離,等於原距離乘上 (1 − 2η):
w_new − 3 = (w − 3) − η × 2(w − 3) = (1 − 2η)(w − 3)
η = 0.1 時,1 − 2 × 0.1 = 0.8。距離是 3 × 0.8 = 2.4,2.4 × 0.8 = 1.92,1.92 × 0.8 = 1.536。第 3 步的 w = 1.464,而 3 − 1.464 = 1.536。
同一個損失、仍從 w = 0 出發,只改學習率,會出現三種走法。
- η = 0.01:1 − 2 × 0.01 = 0.98。第 1 步 w = 0 − 0.01 × (−6) = 0.06,離 3 為 2.94,也就是 3 × 0.98。方向對,會靠近 3,但每步只消掉 2% 的距離,很慢。
- η = 1:1 − 2 × 1 = −1。距離不縮短,只換到另一側。w = 0 − 1 × (−6) = 6;下一步梯度 = 2(6 − 3) = 6,w = 6 − 1 × 6 = 0。參數在 0 與 6 之間來回,到不了 3。
- η = 1.1:1 − 2 × 1.1 = −1.2。距離越乘越大。w = 0 − 1.1 × (−6) = 6.6,離 3 為 3.6;下一步梯度 = 2(6.6 − 3) = 7.2,w = 6.6 − 1.1 × 7.2 = 6.6 − 7.92 = −1.32,離 3 為 3 − (−1.32) = 4.32。這叫發散(divergence)。實務上會看到損失暴增,或變成 NaN。
每一步用多少筆資料算梯度,有三種設定。全批次梯度下降(full-batch gradient descent)用上全部訓練資料。隨機梯度下降(SGD)每步只用一筆。小批次(mini-batch)每步用一小批,例如 32 筆或 256 筆,實務上最常用。
全部訓練資料都用過一次,叫做一個 epoch。每一次參數更新是一個更新步數(iteration)。更新次數要分開算:10,000 筆、批次大小 100 時,一個 epoch 更新 10,000 ÷ 100 = 100 次。全批次時,一個 epoch 只更新 1 次。
損失曲面是單純碗形時,沿反梯度走會靠近碗底。曲面不是單純碗形時,梯度下降可能停在局部最小值(local minimum),或停在梯度接近 0 的平坦區。動量(momentum)與 Adam 這類最佳化器(optimizer)會參考過去的梯度來調整步伐。
特徵的尺度差很多時,損失曲面會被拉成細長形,梯度下降容易走之字形,收斂變慢。先做標準化(standardization)比較快(第 5 篇)。
正則化與提早停止
正則化懲罰過大的權重;提早停止在驗證損失最低時收手。
詳細說明
訓練損失還能再降時,參數也可能變得很大,只為了貼緊訓練資料。正則化(regularization)在損失上加一項,懲罰參數的大小,讓「訓練損失最小」不再是唯一目標。
L2(ridge,也叫權重衰減 weight decay)寫成 L + λ Σ w²。權重整體變小,但通常不會剛好變成 0。L1(lasso)寫成 L + λ Σ |w|。一部分權重會被壓到剛好 0,那些特徵就不再進入預測,等於自動挑特徵。
λ 是超參數。越大,懲罰越重;太大會欠擬合(underfitting)。
在 scikit-learn 裡,Ridge(alpha=1.0) 是 L2,Lasso(alpha=0.1) 是 L1。這裡的 alpha 就是 λ。
提早停止(early stopping)不改損失的公式,而改停的位置。每個 epoch 結束時看驗證損失。連續若干輪(patience)都沒有再下降,就停止,並採用驗證損失最低那一輪的參數。驗證損失從最低點再往上升的那一段,就是過擬合開始的位置;留下最低點的參數,就不會把這一段一起採用。
讀學習曲線
訓練損失持續下降、驗證損失卻回升,代表開始過擬合。
詳細說明
把每個 epoch 的訓練損失和驗證損失畫在一起,可以看出該停、該繼續,或該回頭查學習率。
- 訓練損失持續下降,驗證損失先降後升:最低點之後開始過擬合。
- 兩條都高,而且走平:這是欠擬合,模型太簡單,或特徵不夠。
- 兩條都還在下降:訓練還可以繼續。
- 損失劇烈震盪,或出現 NaN:多半是學習率太大。
損失函數與評估指標
訓練用可微分的損失,報告用準確率、F1 這類指標。
詳細說明
損失要能對參數微分,才算得出梯度。準確率(accuracy)、F1、召回率(recall)這類評估指標(evaluation metric)是給人看的,也用來在模型之間做選擇。準確率對參數的微小變化是一階一階跳的:猜對的筆數沒有增減時,數值停在原地,梯度幾乎處處為 0。梯度下降用不上這種訊號。
分類在訓練時用交叉熵,寫報告時看準確率或 F1(第 14 篇)。
三、容易混淆的地方
下表每一列是一組容易混在一起的詞:中間是差別,右邊是這組差別在日誌、報告、儀表板或程式碼審查裡的樣子。
| 容易混淆 | 差別在哪 | 實際遇到時的線索 |
|---|---|---|
| 參數與超參數 | 參數由資料學出,例如權重 w、偏差 b。超參數由人在訓練前決定,例如學習率、正則化強度、訓練輪數、樹的深度,並用驗證集挑選。 | 模型建構式或設定檔裡手填的學習率、輪數、樹深,是超參數。訓練結束後才定下的係數,是參數。同事要求「把學習率也交給模型學」時,是把超參數當成參數。 |
| 損失函數與評估指標 | 損失要能對參數微分,用來計算梯度。準確率、F1、召回率給人看,也用來選模型。 | 訓練日誌裡每一步在降的是損失。報告和儀表板上給人看的是準確率或 F1。程式碼審查裡若要求「損失改成準確率,才和報告一致」,就是這組混淆。 |
| 學習率太大與太小 | 太大時步伐會過衝。η = 1 時在兩點間來回,η = 1.1 時距離越拉越大,損失暴增或變成 NaN。太小時方向對但很慢,例如 η = 0.01 時每步把距離乘上 0.98。 | 日誌裡損失劇烈上下跳,或數值變成 NaN,是學習率太大的樣子。損失曲線平滑、走了很多個 epoch 仍幾乎不動,是學習率太小的樣子。 |
| L1 與 L2 | L1 懲罰權重絕對值之和,一部分權重會變成剛好 0,等於自動挑特徵。L2 懲罰權重平方之和,權重變小,通常不會剛好變成 0。兩者的 λ 太大都會欠擬合。 | 係數表裡若有一批特徵的權重是精確的 0,比較像 L1,對應 Lasso。權重普遍變小但仍是非零小數,比較像 L2,對應 Ridge。程式裡的 alpha 就是 λ。 |
| epoch、批次與更新步數 | 一個 epoch 是全部訓練資料用過一次。批次是每步拿來算梯度的那一組樣本。更新步數 =(資料筆數 ÷ 批次大小)× epoch 數。 | 10,000 筆、批次 100 時,日誌可以同時寫著 epoch 1 和 step 100。儀表板若只畫 epoch,第 3 輪看起來會像參數只改了 3 次。 |
| 訓練損失下降與模型變好 | 訓練損失下降,表示更貼合訓練資料。泛化要看沒看過的資料。驗證損失先降後升時,最低點之後開始過擬合。 | 只附訓練損失的報告,曲線可以一路向下。同一份訓練的驗證損失若已經上升,泛化正在變差。同事以「訓練損失還在降」要求加長訓練時,圖上常常缺了驗證那一條。 |
四、基礎練習
下面六個情況用來檢查更新的方向、學習率、正則化、更新次數,以及損失和報告指標怎麼分工。先自己判斷,再展開解析。
第 1 題
某團隊把梯度下降寫進程式之前,先用一個參數核對。損失是 L(w) = (w − 3)²,目前 w = 1,學習率 0.1。依梯度下降更新一步之後,w 是多少?
- (A) 0.6
- (B) 1.4
- (C) 3
- (D) 1.1
看答案與解析
答案:B
梯度 = 2(1 − 3) = −4。w = 1 − 0.1 × (−4) = 1 + 0.4 = 1.4。這一步是參數減掉學習率乘梯度,往損失下降的方向走。
- (A) 0.6 來自沿梯度方向走:1 + 0.1 × (−4) = 0.6,那是往損失上升的方向。
- (C) 3 是這個損失的最小值,梯度下降一步不會直接跳到那裡。
- (D) 1.1 是把學習率當成固定步長,1 + 0.1 = 1.1,沒有乘上梯度。
第 2 題
某工廠用產線感測讀數預測設備是否需要停機保養。模型訓練了 40 個 epoch:訓練損失一路下降,驗證損失在第 12 個 epoch 最低,之後逐漸上升。比較合理的做法是什麼?
- (A) 訓練損失還在下降,應再增加訓練輪數。
- (B) 驗證損失上升是學習率太小造成的,把學習率調大即可。
- (C) 這是欠擬合:模型太簡單,所以驗證損失才上升。
- (D) 大約從第 12 個 epoch 之後開始過擬合,應提早停止,並保留第 12 個 epoch 的參數。
看答案與解析
答案:D
訓練損失一路下降,只說明訓練資料被擬合得更緊。驗證損失在第 12 個 epoch 最低、其後上升,表示大約從第 12 個 epoch 之後開始過擬合。提早停止要採用的,就是驗證損失最低的第 12 個 epoch 的參數。
- (A) 再增加訓練輪數,會繼續走進驗證損失已經上升的那段。
- (B) 學習率太小會讓損失移動很慢,不會造成驗證損失在最低點之後轉為上升。
- (C) 欠擬合時,訓練損失和驗證損失都高而且平;這裡是驗證先降後升,不是那個形態。
第 3 題
某電商正在訓練模型。訓練一開始,損失就劇烈震盪,幾步之後變成 NaN。比較合理的判斷是什麼?
- (A) 資料筆數太多,應先減少資料再訓練。
- (B) 學習率還不夠大,應加大學習率,讓它更快收斂。
- (C) 學習率太大,應把學習率調小。
- (D) 改用 L1 正則化,就能讓損失不再變成 NaN。
看答案與解析
答案:C
一開始就劇烈震盪、接著變成 NaN,多半是學習率太大。以 L(w) = (w − 3)² 來看,η = 1.1 時每步把離 3 的距離乘上 −1.2,距離從 3 到 3.6 再到 4.32,損失會越衝越高。處理是把學習率調小。
- (A) 資料筆數決定一個 epoch 裡更新幾次,不會單獨把損失變成 NaN。
- (B) 震盪和 NaN 已經是步伐太大,再加大學習率會離最小值更遠。
- (D) L1 懲罰的是權重的大小,不處理學習率過大造成的發散。
第 4 題
某醫院整理了 200 個特徵。團隊懷疑只有少數真正有用,希望模型自動把沒用特徵的權重變成剛好 0。比較合適的做法是什麼?
- (A) 用 L1 正則化(lasso)。
- (B) 用 L2 正則化(ridge),它會把沒用特徵的權重收成剛好 0。
- (C) 提高學習率,讓沒用的權重更快變成 0。
- (D) 增加 epoch,訓練久了,沒用的權重會變成 0。
看答案與解析
答案:A
L1 在損失上加 λ Σ |w|,會把一部分權重壓到剛好 0,等於自動挑特徵。200 個特徵裡只有少數有用時,要的就是這個效果。
- (B) L2 加的是 λ Σ w²,權重會變小,但通常不會剛好變成 0。
- (C) 提高學習率只改變每步的長度,不會把沒用特徵的權重收成 0。
- (D) 增加 epoch 只是多更新幾輪,不會使沒用特徵的權重變成剛好 0。
第 5 題
某電商的訓練資料有 50,000 筆,mini-batch 大小 500,訓練 10 個 epoch。參數一共更新幾次?
- (A) 10
- (B) 100
- (C) 500,000
- (D) 1,000
看答案與解析
答案:D
每個 epoch 的更新次數是 50,000 ÷ 500 = 100。訓練 10 個 epoch,參數一共更新 100 × 10 = 1,000 次。
- (A) 10 是把 epoch 數直接當成更新次數。
- (B) 100 只算了一個 epoch,沒有乘上 10。
- (C) 500,000 來自 50,000 × 10,把每一筆都當成一次更新再乘上 epoch 數,沒有先除以批次大小 500。
第 6 題
某團隊做二元分類,判斷一筆訂單會不會取消。有人提議:直接用準確率當損失函數做梯度下降,這樣就和報告指標一致。下面哪個說法站得住?
- (A) 可以。準確率是最好的損失函數,應直接拿來做梯度下降。
- (B) 不行。準確率對參數的微小變化不連續,梯度幾乎處處為 0。訓練用交叉熵,報告再看準確率、F1 等指標。
- (C) 不行。交叉熵只能用於迴歸,分類沒有能做梯度下降的損失。
- (D) 可以。損失越低,報告指標一定越高。
看答案與解析
答案:B
準確率要等猜對的筆數改變才跳一階,參數在兩階之間微調時數值不動,梯度幾乎處處為 0,不能用來做梯度下降。分類訓練用交叉熵:正確類別的機率是 p 時,這一筆是 −ln p,對參數可微分。報告再看準確率、F1 等指標。
- (A) 準確率的梯度幾乎處處為 0,不能因為它和報告用的是同一個名字,就拿來當損失。
- (C) 這篇裡分類訓練用的就是交叉熵;迴歸常用的是均方誤差。交叉熵不是只能用於迴歸。
- (D) 訓練損失下降可以發生在過擬合的階段。那時驗證損失已經上升,報告上的準確率、F1 不必一起變高。
五、重點回顧
- 訓練調整的是參數 θ。模型用
ŷ = f(x; θ)做預測,損失把預測和正確答案的差距收成一個數字,最佳化尋找讓訓練資料平均損失變小的參數。線性模型裡,這些參數就是 w 與 b。 - 梯度由損失對每個參數的偏導數組成,指向損失上升最快的方向。更新式是
θ ← θ − η · ∂L/∂θ。以L(w) = (w − 3)²來說,每步把離 3 的距離乘上 (1 − 2η):η 小則收斂慢,η = 1 會在兩點間來回,η 再大就發散,損失可能暴增或變成 NaN。 - 權重 w、偏差 b 由資料學出。學習率、正則化強度、訓練輪數、樹的深度是超參數,由人在訓練前決定,用驗證集挑選。
- 一個 epoch 是全部訓練資料用過一次。參數更新次數 =(資料筆數 ÷ 批次大小)× epoch 數。10,000 筆、批次 100 時,一個 epoch 更新 100 次。
- L2 把
λ Σ w²加進損失,權重變小但通常不會剛好為 0;L1 加上λ Σ |w|,一部分權重會變成剛好 0。λ 太大會欠擬合。提早停止在驗證損失連續若干輪未再下降時停住,並保留驗證損失最低那一輪的參數。 - 訓練損失持續下降、驗證損失先降後升,最低點之後是過擬合;兩條都高且平是欠擬合;兩條都還在降,則可以繼續訓練;劇烈震盪或 NaN 多半是學習率太大。分類訓練用可微分的交叉熵;準確率一階一階跳,梯度幾乎處處為 0,和 F1、召回率一起留到報告。