# 第二章:訓練過程可能遇到的問題
>上課筆記
* 影片連結
* ==[**機器學習任務攻略**](https://youtu.be/WeHM2xpYQpw)==
---
## 機器學習框架 (Framework of ML)
* **訓練資料 (Training data)**:用於訓練模型。
* 形式:$\{(x^1, \hat y^1), (x^2, \hat y^2), ..., (x^N, \hat y^N)\}$
* 範例:語音辨識 (phoneme -> soup)、影像辨識、人臉辨識、機器翻譯。
* **測試資料 (Testing data)**:用於評估訓練好的模型在新資料上的表現。
* 形式:$\{x^{N+1}, x^{N+2}, ..., x^{N+M}\}$
* 通常會有對應的真實標籤 $\{y^{N+1}, y^{N+2}, ..., y^{N+M}\}$,用於評估模型預測結果。
* 在競賽中,測試資料可能分為**公開 (public)** 和 **私有 (private)** 兩個部分。
* **機器學習的三個步驟**:
1. **寫出帶有未知數的函數 (Function with unknown)**:模型 (Model) 本質上是一個函數,其內部包含未知的參數 $\theta$ (theta)。模型可以表示為 $f_\theta(x)$。
2. **定義損失函數 (Define loss function)**:損失函數 **𝐿** 用於衡量模型在訓練資料上的表現有多「不好」,即預測值與真實值之間的差距總和。$$𝐿(\theta) = \frac{1}{N}\sum_{i=1}^{N}|y^i - \hat{y}^i|$$
3. **最佳化 (Optimization)**:透過演算法 (例如梯度下降 Gradient Descent) 找到使損失函數最小的參數 $\theta$。
$$\theta^* = 𝑎𝑟𝑔 \min \ 𝐿(\theta)$$
* **使用最佳模型標記測試資料**:使用訓練好的最佳參數 $\theta^*$ 的模型 $f_{\theta^*}(x)$ 來預測測試資料的標籤。
---
## 發現訓練資料損失過大 (Large loss on training data)
### 可能原因:
1. **模型偏差 (Model Bias)**:**模型太過簡單**,無法捕捉資料的複雜模式。這就像在大海撈針,但針根本不在海裡。
* **解決方案**:重新設計模型,使其更具彈性 (make your model complex)。
* 增加更多特徵 (More features)。
* 使用深度學習 (Deep Learning),例如增加神經元、層數 (more neurons, layers)。
* 使用更複雜的函數形式。
2. **優化問題 (Optimization Issue)**:模型本身可能足夠複雜,能夠擬合資料,但優化演算法**無法找到使損失函數最小的參數** $\theta^*$。這就像針在海裡,但你找不到它。本課程主要使用梯度下降。
* **解決方案**:
* 嘗試更強大的優化技術 (More powerful optimization technology) (下一堂課會講解)。
* 從較淺層的網路或其他較易於優化的模型開始。如果較深層的網路在訓練資料上沒有獲得更小的損失,則很可能是優化問題。
---
## 模型偏差 vs. 優化問題 (Model Bias v.s. Optimization Issue)

* 比較不同複雜度模型的訓練和測試損失可以幫助判斷是哪種問題。
* 例如,比較 56 層和 20 層網路的訓練和測試損失:
* 如果在訓練資料上,20 層網路的損失小於 56 層網路的損失,這可能表示優化問題,因為更深的網路理應更能擬合訓練資料。
* 可以先用簡單的模型訓練,再用深的模型,如果發現深層模型的訓練損失反而大於淺層模型,則可能是優化問題。

---
## 發現訓練資料損失很小 (Small loss on training data)
當訓練資料的損失很小時,需要觀察測試資料上的損失。
* **測試損失也很小**:恭喜,模型表現良好。
* **測試損失很大**:發生了**過度擬合 (Overfitting)**。
---
## 過度擬合 (Overfitting)
* **定義**:模型在訓練資料上表現非常好 (損失很小),但在測試資料上表現很差 (損失很大)。模型缺乏應變能力,只記住了訓練資料,無法推廣到新資料。
* **極端範例**:一個函數 $f(x)$ 對於訓練資料 $x^i$ 直接輸出其標籤 $\hat y^i$,而對於其他輸入則輸出隨機值。這個函數在訓練資料上的損失為零,但在測試資料上很可能損失很大,因為它沒有學到任何有意義的模式。
* **原因**:模型過於彈性 (flexible model) 或複雜,記住了訓練資料中的雜訊或特例。
* **解決方案**:
1. **簡化模型 (make your model simpler / constrained model)**:
* 減少特徵 (Less features)
* 提前停止訓練 (Early stopping)
* 正規化 (Regularization)
* Dropout
* 減少參數,共享參數 (Less parameters, sharing parameters),例如在[卷積神經網路 (CNN) 中應用](https://hackmd.io/@Jaychao2099/imrobot4#%E8%A7%80%E5%AF%9F%E4%BA%8C%EF%BC%9A%E6%A8%A1%E5%BC%8F%E7%9A%84%E4%BD%8D%E7%BD%AE%E4%B8%8D%E8%AE%8A%E6%80%A7-Pattern-Translation-Invariance)。
* 將模型限制在更簡單的函數形式,例如限制為二次函數。但過度限制可能會回到模型偏差的問題。
2. **增加訓練資料 (more training data)**:提供更多不同的樣本,幫助模型學習更general的模式。但實際應用中可能難以收集更多真實資料。
3. **資料擴增 (Data augmentation)**:對現有的訓練資料進行微小的變動,生成新的「假」資料,例如圖像的旋轉、縮放、平移等。
## 偏差-複雜度權衡 (Bias-Complexity Trade-off)
隨著模型變得更複雜 (例如,更多特徵、更多參數),訓練損失通常會下降,但測試損失可能會先下降後上升,形成一個 U 形曲線。這是因為模型太複雜時會開始過度擬合。
* 目標是選擇一個複雜度「剛剛好」的模型,使得測試損失最小。

## 選擇模型 (Model Selection)
### 將訓練資料分割成訓練集和驗證集 (Cross Validation):
* 訓練集用於訓練不同的模型。
* 驗證集用於在訓練過程中評估模型的表現,並根據驗證集的損失來選擇最佳的模型超參數或決定何時停止訓練。

### N 折交叉驗證 (N-fold Cross Validation):
* 將訓練資料分成 N 份。
* 每次選擇其中一份作為驗證集,其餘 N-1 份作為訓練集,訓練 N 個不同的模型。
* 計算每個模型在對應驗證集上的損失。
* 計算每個模型在所有驗證集上的平均損失,選擇平均損失最小的模型。

### 避免使用公開測試資料選擇模型:
* 如果在 Kaggle 等競賽中,僅根據公開測試集的表現來選擇最終模型,可能會導致模型過度擬合公開測試集,而在私有測試集上表現很差。
* **原因**:公開測試集只是真實測試資料的一個子集,模型可能恰好在公開測試集上表現良好,但在未見過的私有測試集上表現隨機。
* **正確做法**:使用驗證集或交叉驗證來選擇模型。
---
## 不匹配 (Mismatch)
* **定義**:訓練資料和測試資料的資料分布不同。
* **影響**:在這種情況下,即使模型在訓練資料上表現很好,也無法保證在測試資料上表現良好。單純增加訓練資料可能沒有幫助。
* **注意事項**:在大多數作業中,不會遇到這個問題。需要注意資料是如何產生的。
* **範例**:訓練資料是彩色真實動物圖片,測試資料是黑白卡通動物圖騰。在這種情況下,訓練資料的品質就不那麼重要了。

---
## 如何辨別狀況?

---
回[主目錄](https://hackmd.io/@Jaychao2099/aitothemoon/)