Python | OpenCV 遷移學習與微調原理
📚 前言
在上一篇 模型選擇與訓練 的章節導覽中,我們了解了整體訓練流程。
這一篇先從最根本的問題開始:深度學習模型到底長什麼樣子?它是怎麼運作的?
只有先搞清楚模型的結構與運作原理,才能理解「遷移學習」到底在做什麼,以及為什麼這樣做。
🧠 深度學習模型長什麼樣?
📌 模型的基本結構
一個深度學習模型可以想像成一條流水線:資料進去,一層一層處理,最後輸出結果。
圖:模型的基本結構 ─ 從輸入圖片開始,經過多層卷積層逐步提取特徵,最後由分類頭輸出結果
📌 每一層在做什麼?
越前面的層,學到的是越基礎、越通用的特徵;越後面的層,學到的是越複雜、越針對特定任務的特徵。
圖:模型每一層在學習什麼? ─ 淺層學習邊緣與顏色,中層學習形狀與紋理,深層學習物件語意
📌 什麼是「分類頭」?
分類頭就是模型的最後一層,它的工作是:拿到前面所有層提取到的特徵,輸出「這張圖屬於哪個類別」的答案。
例如一個在 ImageNet 上訓練的模型,分類頭的輸出是 1000 個類別的機率,因為 ImageNet 有 1000 種物件。
📌 「訓練」在做什麼?
訓練的本質是:不斷調整每一層的參數(權重),讓模型的輸出跟正確答案越來越接近。
1 | 給模型一張貓的圖片 |
訓練需要大量的標註資料、時間與計算資源(GPU)。
📊 不同的學習方式有哪些?
既然訓練這麼耗資源,有沒有更聰明的方法?答案是有的。根據起點不同,有以下幾種學習方式:
圖:常見的模型學習方式比較 ─ 從零訓練、特徵提取、微調、Zero-shot 的資料需求與適用情境
🔎 什麼是遷移學習?
生活比喻
想像你請了一位已在頂級餐廳工作十年的廚師。他已經掌握了刀工、火候、調味等基本功。你不需要重新教他這些基礎,只需要讓他學習你餐廳的幾道特色料理即可。
深度學習的「遷移學習」就是這個概念。
預訓練模型(如 ResNet、MobileNet)是在 ImageNet 這類包含 120 萬張圖片的大型資料集上訓練而成的。它的前幾層已經學會了豐富的通用視覺特徵:邊緣、紋理、形狀……
遷移學習的核心做法:
- 拿一個已經訓練好的模型
- 把最後的分類頭換成自己任務的類別
- 讓模型在自己的資料上繼續學習(而不是從頭學起)
這樣前面幾層「刀工、火候」的基本功就不需要重學,只需要讓模型學會「你餐廳的特色料理」。
遷移學習的三種策略
依照你的資料量與需求,遷移學習有三種做法:
圖:遷移學習的三種策略比較 ─ 特徵提取、微調、全面訓練的適用情境與差異
⚠ 為什麼要凍結前幾層?因為前幾層學到的「邊緣、紋理」是通用的基礎特徵,不需要因為換了任務而重新學習,貿然更動反而可能破壞這些已學好的知識。
如何選擇策略?
1 | 我的每類資料大約有幾張? |
💡 新手建議:不確定時,先從 Feature Extraction 開始。確認流程跑通後,再試 Fine-Tuning 看準確度是否提升。
💻 實作一:查看與替換分類頭
開始動手前,先看清楚模型的分類頭長什麼樣子。
圖:如何替換分類頭 ─ 以 ResNet18(model.fc)和 MobileNetV2(model.classifier[-1])為例,並列出其他常見模型的分類頭位置
🔸 以 ResNet18 為例:
最後一層 fc(Fully Connected)就是分類頭:
1 | # check_model_head.py |
輸出
1 | Linear(in_features=512, out_features=1000, bias=True) |
把 out_features=1000 換成自己的類別數:
1 | # replace_fc.py |
輸出
1 | Linear(in_features=512, out_features=3, bias=True) |

圖:將 ResNet18 的分類頭替換為自訂類別數的線性層
🔸 MobileNetV2
分類頭位置不同,在 classifier[-1]:
1 | # replace_mobilenet_head.py |
輸出
1 | Linear(in_features=1280, out_features=1000, bias=True) |

圖:載入 MobileNetV2 預訓練模型並替換 classifier[-1] 為自訂類別數的線性層
💻 實作二:凍結策略
Feature Extraction(全部凍結,只訓練分類頭)
圖:Feature Extraction(特徵提取)示意圖 ─ 預訓練層全部凍結,只有分類頭會被訓練
1 | # feature_extraction.py |

圖:凍結所有預訓練層並替換分類頭,確認只有 fc 層的參數可被訓練
Fine-Tuning(解凍後幾層 + 分類頭)
圖:Fine-Tuning 微調策略 ─ 大部分層凍結,只解凍 Layer4 並替換分類頭,使用不同學習率訓練
1 | # finetune.py |

圖:凍結前層後解凍 layer4 與分類頭,並為不同層設定不同學習率進行 Fine-Tuning
💡 解凍層數愈多,需要的資料量也愈多。建議先用 Feature Extraction 跑出基準結果,再逐步解凍更多層。
🧠 學習率的設定原則
學習率決定每次更新參數的幅度。幅度太大會破壞預訓練層已學好的特徵,幅度太小則收斂緩慢。
圖:學習率設定原則 ─ 不同訓練階段建議使用的學習率範圍與原因
🔎 如何判斷訓練是否正常?
圖:如何判斷訓練是否正常? ─ 常見現象、可能原因與解決方式(附 Loss 與 Val Loss 白話說明)
⚠️ 注意事項
- 不要一開始就解凍太多層:解凍的層數愈多,模型需要的訓練資料量也愈多。資料不足時解凍太多層,反而會把已學好的特徵破壞掉,準確率不升反降。建議先從 Feature Extraction 跑出基準結果,再逐步嘗試解凍。
- 預訓練層的學習率必須比分類頭小:分類頭是全新的層,需要較大的學習率快速收斂;預訓練層已有學好的特徵,學習率過大會把這些特徵更新掉。Fine-Tuning 時請務必為兩者設定不同的學習率(參考上方
optimizer的寫法)。
🎯 結語
這篇從模型的基本結構出發,說明分類頭的作用與替換方式,再介紹遷移學習的三種策略以及如何根據資料量做選擇。
把握「資料量決定策略、預訓練層學習率要小」這兩個原則,就能在不同情境下正確套用遷移學習。
下一步將進入實際的 PyTorch 微調範例,把這些原理付諸實作。
📖 如在學習過程中遇到疑問,或是想了解更多相關主題,建議回顧一下 Python | OpenCV 系列導讀,掌握完整的章節目錄,方便快速找到你需要的內容。
註:以上參考了
PyTorch 官方文件 — Transfer Learning Tutorial
PyTorch 官方文件 — torchvision.models
CS231n — Transfer Learning
