# 第二章:訓練過程可能遇到的問題 >上課筆記 * 影片連結 * ==[**機器學習任務攻略**](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) ![image](https://hackmd.io/_uploads/BJ7CN6Rjyg.png) * 比較不同複雜度模型的訓練和測試損失可以幫助判斷是哪種問題。 * 例如,比較 56 層和 20 層網路的訓練和測試損失: * 如果在訓練資料上,20 層網路的損失小於 56 層網路的損失,這可能表示優化問題,因為更深的網路理應更能擬合訓練資料。 * 可以先用簡單的模型訓練,再用深的模型,如果發現深層模型的訓練損失反而大於淺層模型,則可能是優化問題。 ![image](https://hackmd.io/_uploads/HyveSpRskg.png) --- ## 發現訓練資料損失很小 (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 形曲線。這是因為模型太複雜時會開始過度擬合。 * 目標是選擇一個複雜度「剛剛好」的模型,使得測試損失最小。 ![image](https://hackmd.io/_uploads/Hkzjra0oyx.png) ## 選擇模型 (Model Selection) ### 將訓練資料分割成訓練集和驗證集 (Cross Validation): * 訓練集用於訓練不同的模型。 * 驗證集用於在訓練過程中評估模型的表現,並根據驗證集的損失來選擇最佳的模型超參數或決定何時停止訓練。 ![image](https://hackmd.io/_uploads/ByZxU60iJx.png) ### N 折交叉驗證 (N-fold Cross Validation): * 將訓練資料分成 N 份。 * 每次選擇其中一份作為驗證集,其餘 N-1 份作為訓練集,訓練 N 個不同的模型。 * 計算每個模型在對應驗證集上的損失。 * 計算每個模型在所有驗證集上的平均損失,選擇平均損失最小的模型。 ![image](https://hackmd.io/_uploads/SkcMLpCsJl.png) ### 避免使用公開測試資料選擇模型: * 如果在 Kaggle 等競賽中,僅根據公開測試集的表現來選擇最終模型,可能會導致模型過度擬合公開測試集,而在私有測試集上表現很差。 * **原因**:公開測試集只是真實測試資料的一個子集,模型可能恰好在公開測試集上表現良好,但在未見過的私有測試集上表現隨機。 * **正確做法**:使用驗證集或交叉驗證來選擇模型。 --- ## 不匹配 (Mismatch) * **定義**:訓練資料和測試資料的資料分布不同。 * **影響**:在這種情況下,即使模型在訓練資料上表現很好,也無法保證在測試資料上表現良好。單純增加訓練資料可能沒有幫助。 * **注意事項**:在大多數作業中,不會遇到這個問題。需要注意資料是如何產生的。 * **範例**:訓練資料是彩色真實動物圖片,測試資料是黑白卡通動物圖騰。在這種情況下,訓練資料的品質就不那麼重要了。 ![image](https://hackmd.io/_uploads/ryV88p0jJl.png) --- ## 如何辨別狀況? ![image](https://hackmd.io/_uploads/HkF0ynAjke.png) --- 回[主目錄](https://hackmd.io/@Jaychao2099/aitothemoon/)