驗證碼識別競賽解決方案(97%)


前言:這個庫是為驗證碼識別競賽而開發的一個基於pytorch實現的端到端的驗證碼識別系統。前后開發大概有2個月,其中大部分時間都在調參,后期參考kaggle大神經驗,加入了一些trick,但是由於第一個榜截止了,所以沒有得到測試集結果,只有驗證集的參考結果。該庫比較簡單,適合入門競賽,不過調參難度比較大,需要嘗試合適的超參數,如果超參數不合適,可能會導致無法收斂,具體問題具體分析。

1. 競賽背景

基於https://github.com/dee1024/pytorch-captcha-recognition進行改進,原版中數據集采用的captcha庫自動生成的圖片,可以隨意制定生成數量,並且相對而言生成的圖片比較簡單。

本次項目是全國高校計算機能力挑戰賽中的人工智能賽道里的驗證碼識別,該比賽需要識別26(大寫)+26(小寫)+數字(10)= 62個字符,隨機組成的四位驗證碼圖片。訓練集僅有5000張,並且識別的難度系數較大,人眼有時候也很容易識別出錯。

最終庫地址:https://github.com/pprp/captcha.Pytorch

2. 環境要求

  • 顯存:2G以上
  • Ubuntu16.04
  • numpy
  • torch==1.1.0
  • torchnet==0.0.4
  • torchvision==0.2.0
  • tqdm
  • visdom
  • adabound
  • Augmentor

可通過pip install -r requirements.txt進行環境的安裝或者使用以下命令進行安裝

pip install numpy torchnet==0.0.4 torchvision==0.2.0 tqdm visdom adabound Augmentor -i https://mirrors.aliyun.com/pypi/simple

3. 數據集

1575527368225

比賽提供的數據集如上圖所示,120$\times$40的像素的圖片,然后標簽是由圖片名稱提供的。訓練集測試集划分:80%的數據用於訓練集,20%的數據用於測試集。

  • 訓練圖片個數為:3988
  • 測試圖片個數為:1000

訓練的數據還是明顯不夠的,考慮使用數據增強,最終選擇了Augmentor庫作為圖像增強的庫。

安裝方式:pip install Augmentor

API: https://augmentor.readthedocs.io/en/master/index.html

由於驗證碼與普通的分類圖片有一定區別,所以選擇的增強方式有一定局限,經過幾輪實驗,最終選取了distortion類的方法作為具體增強方法,輸入為訓練所用的圖片,輸出設置為原來圖片個數的2倍,具體代碼見dataAug.py, 核心代碼如下:

def get_distortion_pipline(path, num):
    p = Augmentor.Pipeline(path)
    p.zoom(probability=0.5, min_factor=1.05, max_factor=1.05)
    p.random_distortion(probability=1, grid_width=6, grid_height=2, magnitude=3)
    p.sample(num)
    return p

將得到的圖片重命名為auged_train文件夾,最終數據集組成如下:

root 
	- data
		- train:3988張
		- test:1000張
		- auged_train:7976張

增強后的數據集,建議使用dataset2

鏈接:https://pan.baidu.com/s/13BmN7Na4ESTPAgyfBAHMxA

鏈接:https://pan.baidu.com/s/13BmN7Na4ESTPAgyfBAHMxA
提取碼:v4nk

數據集結構的組織,從網盤下載數據以后,按照以下文件夾格式進行組織:

- data
	- train
	- test
	- auged_train

然后就可以訓練了。

4. 庫的組織架構

root 
	- config
		- parameters.py 主要包括超參數,最重要的是learning rate
	- lib
		- center_loss.py 將center loss引入,用於訓練
		- dataset.py 包裝Dataset,針對train文件夾和auged_train文件夾內容各自寫了一個處理類
		- generate_captcha.py 生成簡單的數據集,在沒有官方數據集的情況下
		- optimizer.py RAdam, AdamW, label smooth等新的optimizer
		- scheduler.py 新增了warmup機制
	- model
		- BNNeck.py 基於resnet18使用了bnnect結構,來自羅浩大佬行人檢測中的trick
		- CaptchaNet.py 手工構建的一個簡單網絡,原有庫提供的
		- dense.py 更改backbone,使用dense121作為backbone,其他也可以更改
		- dualpooling.py 在resnet18基礎上添加了dual pooling,增加了信息
		- IBN.py 使用ibn模塊,以resnet18為基礎
		- model.py resnet18,添加dropout
		- res18.py 引入了attention機制和dual pooling
		- senet.py 將senet作為backbone
	- result
		- submission.csv 結果保存
	- utils
		- cutoff.py 數據增強方法,不適合驗證碼,可以用在普通圖片
		- dataAug.py 使用Agumentor進行數據增強
		- Visdom.py 使用visdom記錄log,進行可視化
- predict.py 引入了多模型預測,然后分析結果
- run.py 與predict類似,不過是單模型的預測
- test.py 規定測試模型權重,待測試圖片路徑,對測試集進行測試
- train.py 模型的訓練,每個epoch先訓練所有的train,然后訓練所有的auged_train圖片

5. 訓練結果

最好結果:

ResNet18+Dropout(0.5)+RAdam+DataAugmentation+lr(3e-4) = 98.4%測試集准確率,線上A榜:97%

模型分析:分析四個模型,python predict.py 觀察預測出錯的結果,評判模型好壞,最終選擇了0號模型。

1575530264099

6. 調參過程記錄

調參過程記錄:null代表未記錄

Name item1 item2 item3 item4 item5 測試:線上
baseline0 ResNet18 lr=1e-3 4:1划分 Adam 88%:84%
baseline1 ResNet34 lr=1e-3 4:1划分 Adam 90%:84%
baseline2 ResNet18 lr=1e-3 4:1划分 RAdam null:90%
baseline3 ResNet18 lr=3e-4 4:1划分 RAdam 未收斂
baseline4 ResNet18 lr=1e-1 4:1划分 RAdam 96.4%:87%
baseline5 ResNet18 lr=1e-1 4:1划分 RAdam aug0 98%:93%
baseline6 ResNet18 lr=1e-1 9:1划分 RAdam aug1 60%:null
baseline7 ResNet18 lr=1e-3 4:1划分 RAdam aug2 null:94%
baseline8 ResNet18 lr=1e-3 4:1划分 AdamW aug2 98.4%:92.56%
baseline9 ResNet18 lr=1e-3 4:1划分 RAdam aug3 null:93.52%
baseline10 ResNet18 lr=1e-3 4:1划分 RAdam aug4 null:94.16%
baseline11 ResNet18 lr=1e-3 9:1划分 RAdam aug5 60%:null
baseline12 ResNet18 lr=3.5e-4 4:1划分 RAdam aug2 null:94.72%
baseline13 ResNet18 lr=3.5e-4 decay:6e-4 4:1划分 RAdam aug2 null:95.16%
baseline14 ResNet18 lr=3.5e-4 decay:7e-4 4:1划分 RAdam aug2 bad
baseline15 ResNet18 lr=3.5e-5 decay:6.5e-4 4:1划分 RAdam aug2 null:95%
baseline16 ResNet18 lr=3.5e-5 decay:6.5e-4 4:1划分 RAdam drop(0.5) null:97%

以上的aug代表數據增強:

  • aug0: +distrotion
  • aug1: 9:1划分+擴增3倍
  • aug2: +distortion+zoom
  • aug3: +tilt+擴增兩倍
  • aug4: aug2+aug3混合
  • aug5: 9:1划分 +tilt傾斜

數據增強示意圖:

example1 example2 example3
在這里插入圖片描述 2 3

后期由於錯過了提交時間,只能進行測試集上的測試,主要方案有以下:

  • learning rate scheduler嘗試:CosineAnnealingLR, ReduceLROnPlateau,StepLR,MultiStepLR
  • 更改backbone: senet, densenet
  • 在res18基礎上添加:attention機制,dual pooling, ibn模塊,bnneck等
  • 嘗試center loss,收斂很慢,但是效果應該不錯

還未嘗試的方案:

  • label smooth
  • 多模型ensemble

聯系方式:


后記:整個比賽下來得到了一等獎,整個過程可謂過山車一般,比賽還沒有放榜的時候,覺得問題不會很難,因為提前查看了網上的驗證碼庫,研究了一下發現,大部分驗證碼都很簡單,比較清晰,但是這次驗證碼下來以后就發現難度比較大

  • 數字+大小寫字母,容易混淆
  • 圖片驗證碼難以識別,人眼都難以分辨
  • 選擇架構,直接選取端到端還是先切割然后 做單字符識別
  • 數據量很小, 其他庫可以用captcha進行驗證碼的生成,所以數據量不會受限制,這次訓練一共給了5000,划分完訓練集驗證機以后就只剩下4000圖片用於訓練,數據規模比較小,所以可能對超參數比較敏感,如果選取不合適就會導致模型不收斂。

之后就選擇了一個能達到80%准確率的baseline開始調整,然后在自己的驗證集通過調參能夠達到90%的准確率,然后就開始感覺差不多了,因為里邊確實有很多人眼都識別不清楚。但是還是低估了神經網絡的能力,榜單不斷刷新,直逼100%, 后邊把我從前10擠到了100多,然后這個時候開始正視這個比賽,開始認真調參,更換模型,添加最新的trick等等,其中比較有感觸的是比賽結束前一段時間,突發奇想想加入dropout, dropout可以視作多模型集成,效果可能會好一點,所以加了dropout以后,榜一排名到了30左右,最終也選擇提交這個帶有dropout的模型,最終才得到不錯的結果。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM