r036_logo
開發
2025-06-25

模型泛化與正則化(Regularization)

泛化能力 (Promote better generalization)

指的是當模型預測未見過的數據時,表現能力依然良好,因此獲得一個好的泛化能力,是機器學習和深度學習中的最大目標

什麼時候氾化會不好?

當模型在訓練中發生overfitting的時候,模型的氾化能力則逐漸減弱,可以想像成模型過度訓練,導致學習到過多噪音,影響了模型對於測試資料的判斷

什麼是過擬合 (Overfitting)

Overfitting是模型對訓練數據過度擬合,學到過多的噪音 (Noise) 或無關特徵 (Irrelevant Features),導致對未見過的測試數據預測能力下降。

泛化能力提升策略

模型訓練中若出現訓練準確度高、驗證準確度低,表示模型過擬合(overfitting),泛化能力不足。此時目標不是「刻意降低訓練準確度」,而是縮小訓練與驗證之間的差距,提升驗證集及測試集的準確度。

以下為實務中有效的提升泛化能力方法:

1. 正則化方法 (Regularization))

隨機丟棄(Dropout Technique)

Dropout 通過在訓練過程中隨機丟棄 (Drop) 神經網路中的部分神經元,減少神經元之間的相互依賴,從而提升模型的泛化能力。

  • 隨機丟棄:以概率 pp 隨機將部分神經元設為 0,不參與前向傳播和反向傳播。

在Keras中的 Dropout 函數

keras.layers.Dropout(p) # p=0.1 表示 10% 機率隨機丟棄

L1 正則化 (Lasso Regularization)

L1 正則化非常適用於特徵維度較多的情況,或者當我們需要自動進行特徵選擇時。產生稀疏權重矩陣,強制部分權重為 0,實現特徵選擇

在Keras中的

keras.layers.Dense(kernel_regularizer=keras.regularizers.l1),

L2 正則化 (Ridge Regularization)

L2 正則化是最常見的正則化方法,適用於大多數情況,特別是當特徵之間有高度相關性時。約束權重的大小,防止權重過大造成的過擬合

在Keras中的

keras.layers.Dense(kernel_regularizer=keras.regularizers.l2),

L1 / L2 正則化 (Elastic Net)

當特徵數量遠大於樣本數,或特徵間存在較強的相關性時,Elastic Net 可以提供更好的性能。既能產生稀疏矩陣,又能有效限制權重範圍

在Keras中的

keras.layers.Dense(kernel_regularizer=keras.regularizers.l1_l2),

批次正規劃(Batch Normalization, BN)

透過標準化 (Normalization) ,穩定該層神經元的輸出分布。當更新權重時,輸入的分佈會保持一致,加速收斂,減少過擬合,提升模型的訓練速度與穩定性

在 Keras 中,BatchNormalization 層可用於隱藏層中,用來標準化每一層的輸入

    keras.layers.Dense(),     keras.layers.BatchNormalization(),

2. 資料擴增(Data Augmentation)

利用隨機旋轉、平移、翻轉等方式擴充訓練資料,使模型學習更具普遍性的特徵。

from tensorflow.keras.preprocessing.image import ImageDataGenerator datagen = ImageDataGenerator( rotation_range=20, width_shift_range=0.1, height_shift_range=0.1, horizontal_flip=True ) train_generator = datagen.flow_from_directory('train_dir', batch_size=32)

3. 模型簡化(Model Simplification)

減少隱藏層數量或每層神經元數量,降低模型容量,避免過度擬合。

4. 早停(Early Stopping)

當驗證損失 (Validation Loss) 開始上升時,或者驗證準確率 (Validation Accuracy) 不再提升,則停止訓練。具體參數可在程式碼中調整,例如在多少次的上升中停止。

from tensorflow.keras.callbacks import EarlyStopping early_stop = EarlyStopping(monitor='val_loss', patience=3, restore_best_weights=True) model.fit(train_ds, validation_data=val_ds, epochs=50, callbacks=[early_stop])