使用 PyTorch Lightning 訓練神經網路,自動辨識 4 個字元的 CAPTCHA 驗證碼圖片。
本專案比較兩種模型架構——前饋神經網路(FFNN)與卷積神經網路(CNN)——在驗證碼辨識任務上的表現。每張 CAPTCHA 包含 4 個字元,字元範圍為數字 0–9 與字母 A–Z,共 36 類。
| 模型 | 字元 1 | 字元 2 | 字元 3 | 字元 4 |
|---|---|---|---|---|
| FFNN | 83.6% | 69.5% | 70.6% | 84.5% |
| CNN | 98.3% | 97.8% | 99.0% | 99.7% |
| 優化器 | 平均字元準確率 | Test Loss |
|---|---|---|
| Adam | 98.05% | 0.207 |
| SGD | 98.80% | 0.198 |
| RMSprop | 97.40% | 0.285 |
最終最佳組合:CNN + SGD,平均字元準確率達 98.8%。
本專案使用的 CAPTCHA 圖片來自台灣高鐵(THSR)訂票網站,由 @maxmilian 以爬蟲方式收集,並手動標記成 label.csv。本專案的影像前處理方式亦參考其作法與以下 YouTube 教學:
由於版權因素,圖片資料集不包含在此 repo 中。如需完整資料,請參考 maxmilian/thsrc_captcha 自行取得。
captcha-recognition-dl/
├── captcha_recognition_model.ipynb # 主要訓練與評估 notebook
├── captcha_preprocessing.ipynb # 影像前處理 notebook
├── image_process.py # 前處理腳本(去雜訊 + 移除干擾線)
├── image_label.csv # 10,000 張驗證碼圖片的標籤
└── requirements.txt
CNN(最佳表現):
- 5 層卷積區塊,通道數逐層增加(1 → 32 → 64 → 128 → 256 → 512)
- 使用 BatchNorm 與 Dropout 防止過擬合
- 4 個獨立分類頭,每個字元位置各一個
FFNN(基準模型):
- 2 層全連接層(隱藏層大小 512)
- 4 個獨立分類頭
原始 CAPTCHA 圖片含有背景雜訊與一條波浪形干擾線,若不處理會大幅影響模型學習效果。前處理分為以下步驟:
1. 縮放(Resize) 將所有圖片統一縮放至 140×48 像素,確保輸入尺寸一致。
2. 去雜訊(Denoising)
使用 OpenCV 的 fastNlMeansDenoisingColored 去除背景雜點,讓字元更清晰。參數設定為強度 30,能有效去除高鐵驗證碼常見的細小噪點。
3. 二值化(Binarization) 使用固定閾值(127)將圖片轉為黑白二值圖,使字元與背景對比更明顯,同時轉為灰階以降低輸入維度。
4. 干擾線移除(Interference Line Removal) 這是最關鍵的步驟。驗證碼圖片左側有一條波浪形弧線橫貫整張圖,直接遮蓋字元。做法是:
- 擷取圖片左側區域(約 x=0~15)偵測弧線的位置(白色像素)
- 用 scikit-learn 的
PolynomialFeatures(degree=2)對這些像素點做二次多項式回歸,擬合出弧線的曲線方程式 - 沿著預測的弧線位置,將對應像素進行反轉(XOR),把弧線從圖片中消除
處理後的圖片存入 processed_images/ 供模型訓練使用。
訓練分為兩個階段:
階段一:架構比較(FFNN vs CNN)
- 兩個模型均以 PyTorch Lightning 實作,訓練 20 epochs
- 資料集切分:80% 訓練 / 10% 驗證 / 10% 測試
- 每個模型有 4 個獨立分類頭,分別預測驗證碼的 4 個字元位置
- 損失函數:CrossEntropyLoss(4 個頭的 loss 加總)
- 優化器:Adam(lr=1e-3)
階段二:優化器比較(以 CNN 為基礎)
- 固定 CNN 架構,分別使用 Adam、SGD(momentum=0.9)、RMSprop 訓練 10 epochs
- 使用 TensorBoard 記錄訓練與驗證 loss 曲線
- 額外實作信心分數門檻(threshold=0.8),對預測機率不足的字元標記為不確定,並統計各優化器的不確定率與常見混淆字元對
pip install -r requirements.txt將 CAPTCHA 圖片放入 captcha_image/,標籤放入 image_label.csv,執行 image_process.py 產生 processed_images/ 後即可開始訓練。
- PyTorch + PyTorch Lightning
- OpenCV
- scikit-learn
- TensorBoard
本專案的模型訓練程式碼由作者原創。
image_label.csv 的標籤資料來自 @maxmilian,依照 Apache License 2.0 授權使用,影像前處理方式亦參考其作法。