Python | OpenCV 遷移學習與微調原理
📚 前言
在上一篇 模型選擇與訓練 的章節導覽中,我們了解了整體訓練流程。
這一篇先從最重要的基礎概念開始:遷移學習與微調原理 (Transfer Learning & Fine-Tuning)。
理解這些原理,才能在實際訓練時做出正確的決策,例如「要凍結幾層?」、「學習率要設多少?」、「為什麼我的模型沒有收斂?」
💡 新手提示:這篇的程式碼需要基本的 PyTorch 知識。如果你對 PyTorch 還不熟悉,這篇先著重理解概念即可,不需要每行程式碼都看懂。概念通了,再回來看程式碼會容易很多。
🔎 什麼是遷移學習?
先用一個生活比喻來理解:
想像你請了一位已在頂級餐廳工作十年的廚師。他已經掌握了刀工、火候、調味等基本功。你不需要重新教他這些基礎,只需要讓他學習你餐廳的幾道特色料理即可。
深度學習的「遷移學習」就是這個概念。
預訓練模型(如 ResNet、MobileNet)是在 ImageNet 這類包含 120 萬張圖片的大型資料集上訓練而成的。
在訓練過程中,模型已經學會了豐富的視覺特徵:
1 | 淺層 → 學習邊緣、顏色、紋理等低階特徵(像廚師的刀工) |
遷移學習的核心想法是:這些已經學好的特徵是通用的,不需要重新學習。
我們只需要在模型最後加上針對自己任務的分類頭,讓模型學習「如何用這些特徵來判斷我的類別」。
💡 什麼是「分類頭」? 模型的最後一層,負責把前面提取到的特徵轉換成「這張圖是貓還是狗」的判斷。預訓練模型的分類頭是針對 ImageNet 1000 個類別設計的,我們需要換成自己的類別數。
🧠 Feature Extraction vs Fine-Tuning
遷移學習有兩種主要策略,選擇哪一種取決於你的資料量與任務相似度:
| 策略 | 做法 | 適用情境 |
|---|---|---|
| Feature Extraction | 凍結所有預訓練層,只訓練新的分類頭 | 資料量少(每類 < 200 張)、任務與 ImageNet 相似 |
| Fine-Tuning | 凍結前幾層,解凍後幾層一起訓練 | 資料量中等、需要更高準確度 |
| Full Training | 解凍所有層一起訓練 | 資料量充足(萬張以上)、任務與 ImageNet 差異大 |
1 | Feature Extraction: |
🔎 預訓練模型的分類頭結構
以 ResNet18 為例,最後一層 fc(Fully Connected)就是分類頭:
1 | # check_model_head.py |

圖:載入 ResNet18 預訓練模型並印出最後一層 fc 的結構,確認輸入特徵維度
我們要把 out_features=1000 換成自己的類別數:
1 | # replace_fc.py |

圖:將 ResNet18 的分類頭替換為自訂類別數的線性層
以 MobileNetV2 為例,分類頭在 classifier[-1]:
1 | # replace_mobilenet_head.py |

圖:載入 MobileNetV2 預訓練模型並替換 classifier[-1] 為自訂類別數的線性層
💻 凍結策略的實作
💡 什麼是「凍結」? 告訴模型在訓練時不要修改這些層的參數,保留預訓練時學到的特徵。在 PyTorch 中,把
requires_grad設為False即可讓該層在反向傳播時被略過,不更新權重。
全部凍結(Feature Extraction)
1 | # feature_extraction.py |

圖:凍結所有預訓練層並替換分類頭,確認只有 fc 層的參數可被訓練
解凍後幾層(Fine-Tuning)
1 | # finetune.py |

圖:凍結前層後解凍 layer4 與分類頭,並為不同層設定不同學習率進行 Fine-Tuning
💡 解凍層數愈多,需要的資料量也愈多。建議先用 Feature Extraction 跑出基準結果,再逐步解凍更多層。
🧠 學習率的設定原則
遷移學習中學習率的設定非常關鍵:
| 訓練對象 | 建議學習率 |
|---|---|
| 只訓練分類頭 | 1e-3 ~ 1e-2 |
| 解凍後幾層 | 1e-4 ~ 1e-3 |
| 全部解凍 | 1e-5 ~ 1e-4 |
學習率過大會「破壞」預訓練權重學到的特徵,導致訓練不穩定甚至發散。
🔎 如何判斷訓練是否正常?
| 現象 | 可能原因 | 解決方式 |
|---|---|---|
| Loss 下降但 Val Loss 上升 | 過擬合 | 資料增強、Dropout、減少解凍層數 |
| Loss 幾乎不下降 | 學習率太小或太大 | 調整學習率,檢查資料前處理 |
| Val Acc 很低但 Train Acc 高 | 資料分布不一致 | 確認訓練集與驗證集的前處理一致 |
| Loss 為 NaN | 學習率過大或資料有問題 | 大幅降低學習率,檢查資料是否有異常值 |
⚠️ 注意事項
- 前處理必須與預訓練模型一致:使用 torchvision 預訓練模型時,圖片必須以相同的均值與標準差正規化(
[0.485, 0.456, 0.406]/[0.229, 0.224, 0.225]),否則特徵提取的效果會大打折扣。 - Batch Normalization 的行為:凍結層中的 BatchNorm 在
model.eval()時使用訓練時的統計量,而非當前 batch 的統計量,訓練時需注意呼叫model.train()與model.eval()的時機。 - 類別不均衡:若各類別的訓練資料數量差異大,可在 Loss 中加入
weight參數平衡影響。
🎯 結語
理解遷移學習的原理,是做出正確訓練決策的基礎。
掌握「凍結幾層」、「學習率設多少」這兩個關鍵之後,就能有效率地微調模型,而不是靠試錯。
下一步將進入實際的 PyTorch 微調範例,把這些原理付諸實作。
📖 如在學習過程中遇到疑問,或是想了解更多相關主題,建議回顧一下 Python | OpenCV 系列導讀,掌握完整的章節目錄,方便快速找到你需要的內容。
註:以上參考了
PyTorch 官方文件 — Transfer Learning Tutorial
PyTorch 官方文件 — torchvision.models
CS231n — Transfer Learning
