當前位置:
首頁 > 知識 > CNN識別學庫寶的驗證碼

CNN識別學庫寶的驗證碼

前言

  • 背景

  • 最近在看深度學習相關知識,正好手上一個爬蟲外包有個需求:爬取 學庫寶 的全站數據。官方傳言題目有一千多萬道,其中每道題要查看答案和解析,都需要識別驗證碼(數字+字母,四個字元)。一般的,打碼平台一塊錢可以識別200張,算下來得要5萬的打碼費用,還沒算失敗率。
  • 圖片示例

CNN識別學庫寶的驗證碼

CNN識別學庫寶的驗證碼

CNN識別學庫寶的驗證碼

CNN識別學庫寶的驗證碼

  • 參考

  • 本文參考了《CNN破解簡單驗證碼(Tensorflow實現)》。網上一搜」驗證碼 CNN」,大部分都是類似的文章,用captcha模塊生成驗證碼進行訓練、識別,甚至代碼都是一樣的,真沒意思。後來發現51CTO視頻課程里也有講這個案例,我把它上傳到雲盤了(鏈接: https://pan.baidu.com/s/1iuMfSlWyTm8SbxHYeDoBSQ 密碼: shjm),感覺視頻里的講解比其他博客詳細多了。
  • 代碼

  • GitHub地址:cnn_on_captcha、captcha_identify。
  • 正確率

  • 訓練樣本6500,測試樣本500,識別率達92.4%。

以往的,識別驗證碼的流程一般是先去噪,再切割,然後用最近鄰去分類識別。但是去噪和切割這兩個步驟,經常都不那麼好做。而CNN不需要去噪和切割,直接整張驗證碼拿去訓練和識別。不用做針對性的去噪和切割,可以省去很大工作量。


正文

採集樣本

CNN識別驗證碼有優點也有不足,它其中的一個缺陷就是需要更多的樣本做訓練。文章《識彆扭曲干擾性驗證碼》中提到94%的識別率需要400W張圖片,不知真假,但確實嚇人。

CNN識別學庫寶的驗證碼

難怪網上一搜」CNN 驗證碼識別」,出來的全都是用captcha模塊生成的驗證碼做訓練,敢情他們是找不到訓練樣本呀。

然而我的任務是識別學庫寶的驗證碼,就算不能收集這麼多的驗證碼,也要試一試。採集驗證碼的流程是下載驗證碼 —> 打碼平台打碼 —> 返回給學庫寶判別正誤。有些博客說人工識別並標註驗證碼,有些原始,我用的是雲打碼,採集了7000張驗證碼,費用還不到40元,何苦為難自己。另外,打碼平台識別的結果並不一定百分百正確,必須返回給原網站,根據反饋判斷識別正誤。

採集驗證碼圖片的代碼:crawl_captcha.py,如果要採集其他網站的驗證碼,稍加修改即可。

(圖片可以自行跑上面的代碼採集,我將我採集到的放在雲盤了,可以拿來直接用,鏈接

訓練和測試

模型的訓練和測試,這個沒什麼好說的,CSDN上一搜,千篇一律。我這裡只是將圖片源換成了本地採集好的驗證碼,代碼中調一下圖片大小。

嘗試和改進

嗯,好玩的在這裡。無知的初學者,瞎搗鼓系列。

(注意,要先把訓練樣本和測試樣本(captchas文件夾和test文件夾)放到項目目錄。除了captcha01,其他都要先運行crop_captcha.py將圖片切割成單字元,再進行訓練。)

  1. 初版本

  2. 代碼:captcha01 。
  3. 最初,6500張圖片,不做任何處理,每次隨機抽取64張,訓練2W批次。耗時80分鐘,

    準確率3.4%

    ,低的可憐,不忍直視。
  4. 切割

  5. 代碼:captcha02 。
  6. 看來這點數據量,基本上是沒法直接訓練了。網路模型還沒能學習到驗證碼的特徵,那我們就清除一些無用的雜質和邊緣,將更清楚、更精準的樣本餵給它。去噪我是不想做的,但切割還是比較容易的,把四個字元單獨切割出來,把不必要的圖片邊緣清除掉。這樣可以很大程度地降低模型學習的壓力,而且樣本量也變成原來的四倍了。

CNN識別學庫寶的驗證碼

CNN識別學庫寶的驗證碼

CNN識別學庫寶的驗證碼

CNN識別學庫寶的驗證碼

CNN識別學庫寶的驗證碼

CNN識別學庫寶的驗證碼

CNN識別學庫寶的驗證碼

CNN識別學庫寶的驗證碼

CNN識別學庫寶的驗證碼

CNN識別學庫寶的驗證碼

CNN識別學庫寶的驗證碼

  1. 切割以後總共2.6萬張圖,訓練2W批次,耗時23分鐘,

    準確率82.2%

    (四個字元同時正確)。這準確率立馬上來了,基本上可以拿來用了。
  2. (註:因打碼平台經常將大小寫忽略,故訓練的時候將全部大寫字母作小寫看待。)
  3. 除去pooling層

  4. 代碼:captcha03 。
  5. 切割後的圖片大小為6*18,字元已經精細到1個像素上去了,已經不能再縮減了。而pooling層很重要的一個作用就是在保留主要特徵的同時降低參數(緯度)和計算量,此時這個作用並不大,所以可以考慮把pooling層去掉。

CNN識別學庫寶的驗證碼

CNN識別學庫寶的驗證碼

CNN識別學庫寶的驗證碼

CNN識別學庫寶的驗證碼

  1. 訓練2W批次,耗時37分鐘,

    準確率89.2%

  2. 新增一層網路

  3. 代碼:captcha04 。
  4. 驗證碼的識別,一般的選擇三層卷積就已經有比較好的效果,但我還是好奇四層卷積,識別率將會升降多少。
  5. 訓練2W批次,耗時44分鐘,

    準確率91.2%

  6. 訓練6W批次,耗時135分鐘,

    準確率91.6%

  7. 將第三層的厚度64變成128

  8. 代碼:captcha05 。
  9. 訓練2W批次,耗時53分鐘,

    準確率88.8%

  10. 訓練6W批次,耗時207分鐘,

    準確率92.4%

開啟驗證碼識別服務

好了,模型已經訓練好了。接下來就是使用了。我使用了Django開了一個服務,需要識別驗證碼的時候只需將驗證碼post過去就能返回識別結果了。代碼:captcha_identify 。

啟動命令:python manage.py runserver 127.0.0.1:8000

在爬蟲中,只需要調用下面的方法即可。

def identify(filename):
try:
r = requests.post("http://127.0.0.1:8000/captcha_identify/", files={"image": (filename, open(filename, "rb"), "image/png")})
return r.content
except Exception as e:
return ""
1
2
3
4
5
6

結語

92.4%的識別率,這已經算比較高了,畢竟訓練樣本才這麼些。而且識別率跟雜訊有關,這個網站有些驗證碼的雜訊線條,已經讓字元完全無法識別了。所以識別率提高到一定程度就很難再提高了。

CNN識別學庫寶的驗證碼

CNN識別學庫寶的驗證碼

CNN識別學庫寶的驗證碼

CNN識別學庫寶的驗證碼

本文借鑒captcha驗證碼的識別案例,記錄識別學庫寶驗證碼的過程,目的是總結和分享,學藝不精,純屬搗鼓,錯誤之處各位多批評指出。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 程序員小新人學習 的精彩文章:

Kotlin 類和對象
C 異常處理

TAG:程序員小新人學習 |