當前位置:
首頁 > 知識 > 詳解自動識別驗證碼,LSTM大顯身手

詳解自動識別驗證碼,LSTM大顯身手

AI研習社按:本文作者 Slyne_D,原載於作者個人博客,AI研習社已獲授權。文中所有鏈接可點擊文末閱讀全文抵達。

這是去年博主心血來潮實現的一個小模型,現在把它總結一下。由於樓主比較懶,網上許多方法都需要切割圖片,但是樓主思索了一下感覺讓模型有多個輸出就可以了呀,沒必要一定要切割的吧?切不好還需要損失信息啊!本文比較簡單,只基於傳統的驗證碼。

Part 0 模型概覽

從圖片到序列實際上就是 Image2text 也就是 seq2seq 的一種。encoder 是 Image, decoder 是驗證碼序列。由於 keras 不支持傳統的在 decoder 部分每個 cell 輸出需要作為下一個 rnn 的 cell 的輸入 (見下圖),所以我們這裡把 decoder 部分的輸入用 encoder(image)的最後一層複製 N 份作為 decoder 部分的每個 cell 的輸入。

典型的 seq2seq

keras 可以直接實現的 image2text

當然利用 recurrentshop 和 seq2seq,我們也可以實現標準的 seq2seq 的網路結構 (後文會寫)。

Part I 收集數據

網上還是有一些數據集可以用的,包括 dataCastle 也舉辦過驗證碼識別的比賽,都有現成的標註好了的數據集。(然而難點是各種花式驗證碼啊,填字的,滑動的,還有那個基於語義的 reCaptcha~)。

因為我想弄出各種長度的驗證碼,所以我還是在 github 上下載了一個生成驗證碼的 python 包。

下載後,按照例子生成驗證碼 (包含 26 個小寫英文字母):

(目測了一下生成驗證碼的包的代碼,發現主要是在 x,y 軸上做一些變換,加入一些噪音)

Part II 預處理

由於生成的圖片不是相同尺寸的,為了方便訓練我們需要轉換成相同尺寸的。另外由於驗證碼長度不同,我們需要在 label 上多加一個符號來表示這個序列的結束。

處理之後的結果就是圖像 size 全部為 Height=60, Width=250, Channel=3。label 全部用字元 id 表示,並且末尾加上表示 的 id。比如假設 a-z 的 id 為 0-25, 的 id 為 26,那麼對於驗證碼 "abdf" 的 label 也就是 [0,1,3,5,26,26,26,26],"abcdefg" 的 label 為 [0,1,2,3,4,5,6,26]。

由於我們用的是 categorical_crossentropy 來判斷每個輸出的結果,所以對 label 我們還需要把其變成 one-hot 的形式,那麼用 Keras 現成的工具 to_categorical 函數對上面的 label 做一下處理就可以了。比如 abdf 的 label 進一步轉換成:

[[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],

[0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],

[0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],

[0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],

[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],

[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],

[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],

[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]]

Part III 構建模型

不藉助外部包可以實現的模型

藉助 recurrentshop 和 seq2seq 可以實現的結構

Part IV 模型訓練

之前寫過固定長度的驗證碼的序列準確率可以達到 99%,項目可以參考這裡。

另外,我們在用 Keras 訓練的時候會有一個 acc,這個 acc 是指的一個字元的準確率,並不是這一串序列的準確率。也就是說在可以預期的情況下,如果你的一個字元的準確率達到了 99%,那麼如果你的序列長度是 5 的時候,理論上你的序列準確率是 0.99^5 = 0.95, 如果像我們一樣序列長度是 7,則為 0.99^8=0.923。

所以當你要看到實際的驗證集上的準確率的時候,應該自己寫一個 callback 的類來評測,只有當序列中所有的字元都和 label 一樣才可以算正確。

記錄每個 epoch 的模型結果

訓練

Part V 訓練結果

在 39866 張生成的驗證碼上,27906 張作為訓練,11960 張作為驗證集。

第一種模型:

序列訓練了大約 80 輪,在驗證集上最高的準確率為 0.9264, 但是很容易變化比如多跑一輪就可能變成 0.7,主要原因還是因為預測的時候考慮的是整個序列而不是單個字元,只要有一個字元沒有預測準確整個序列就是錯誤的。

第二種模型:

第二個模型也就是上面的 create_imgText,驗證集上的最高準確率差不多是 0.9655(當然我沒有很仔細的去調參,感覺調的好的話兩個模型應該是差不多的,驗證集達到 0.96 之後相對穩定)。

Part VI 其它

看起來還是覺得 keras 實現簡單的模型會比較容易,稍微變形一點的模型就很糾結了,比較好的是基礎的模型用上其他包都可以實現。keras 2.0.x 開始的版本跟 1.0.x 還是有些差異的,而且 recurrentshop 現在也是支持 2.0 版本的。如果在建模型的時候想更 flexible 一點的話,還是用 tensorflow 會比較好,可以調整的東西也比較多,那下一篇可以寫一下 img2txt 的 tensorflow 版本。

Part VII 代碼

完整源代碼:https://github.com/Slyne/CaptchaVariLength

Part VIII 後續

現在的這兩個模型還是需要指定最大的長度,後面有時間會在訓練集最多只有 8 個字元的情況下,利用 rnn 的最後一層進一步對於有 9 個以及以上字元的驗證碼效果,看看是不是可以再進一步的擴展到任意長度。(又立了一個 flag~)

點擊展開全文

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

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


請您繼續閱讀更多來自 唯物 的精彩文章:

AI 也能藝術創作了?Facebook說I CAN
只需 130 行代碼!用 GAN 生成二維樣本的小例子
最容易做的圖像分割教程:用英偉達 DIGITS 進行圖像分割,看一遍你也會做!(上)
AI 助你無碼看片,生成對抗網路大顯身手
《哈利·波特》出版二十周年,教大家用神經網路寫咒語!

TAG:唯物 |

您可能感興趣

PHP 實現簡單驗證碼識別
用 KNN 來進行驗證碼識別
中文項目:快速識別驗證碼,CNN也能為爬蟲保駕護航
驗證碼識別其實很簡單,python圖像處理識別驗證碼
Python驗證碼識別:利用pytesser識別簡單圖形驗證碼
CNN識別學庫寶的驗證碼
不用再輸入繁瑣的驗證碼了?Google隱形reCAPTCHA技術正式版出爐
簡單二十行Python代碼實現驗證碼識別技術!
iOS 12 自動提取驗證碼,是便捷還是「威脅」?
中文點選驗證碼之自動識別
TensorFlow驗證碼識別
iOS 12驗證碼自動填充:體驗很蘋果
指針驗證碼對於iOS越獄意味著什麼?
基於GAN的驗證碼識別工具,0.5秒宣告驗證碼死刑!
iOS 12 貼心小功能:自動填充驗證碼
黑客利用虛假谷歌reCAPTCHA驗證碼發送針對銀行的惡意軟體
iOS 12驗證碼自動填充很方便 但它安全嗎?
iOS 12驗證碼自動填充很方便 但它安全嗎?
iPhone iOS 12功能新亮點,可以自動讀取並輸入簡訊驗證碼
利用機器學習突破基於文本的CAPTCHA驗證碼程序