如何使用深度學習破解驗證碼 keras 連續驗證碼

openyfs 7年前發布 | 28K 次閱讀 Keras 深度學習

在實現網絡爬蟲的過程中,驗證碼的出現總是會阻礙爬蟲的工作。本期介紹一種利用深度神經網絡來實現的端到端的驗證碼識別方法。通過本方法,可以在不切割圖片、不做模板匹配的情況下實現精度超過90%的識別結果。

本文分為兩個部分,第一個部分介紹如何利用深度神經網絡實現驗證碼的訓練和識別,第二個部分介紹在實現過程中需要克服的工程問題。

一. 基于深度神經網絡的驗證碼識別

驗證碼的識別是從圖片到文字的過程。傳統的算法如OCR正是為了解決此類問題而設計的。然而,在真實情形中,驗證碼通常并不以規則的文字出現,即文字通常會有不同程度的變形,圖像本身也通常會被添加或多或少的噪聲。這些干擾的出現,使得文字分割、模板匹配不再有效,進而OCR算法也很難解析出結果。

近年來,深度神經網絡(DNN)在圖像識別領域已經被證明了強大的識別能力。單個文字的識別是典型的分類問題。通常的做法為訓練一個深度神經網絡,網絡的最后一層分為N種類別,代表字符的數目。比如對于英文字母,最后一層的分類器便是26個。比如經典的LeNet(http://yann.lecun.com/exdb/lenet/)即為解決單個文字識別的網絡:

然而驗證碼通常包含多個字符,如何利用現有的網絡實現這類分類問題呢?實際上這個問題再機器學習中被稱為多標簽訓練問題。和上述每個圖片輸入只對應一個標簽類別對比,這類分類的輸出是多個標簽。我們同樣可以對傳統的神經網絡稍作改變以適應這種情況。

我們以最簡單的英文字母為例介紹這個過程。如圖一所示,此種驗證碼由5個字母組成;每個字母只取大寫,共有26種類別;圖片中有干擾線貫穿文字,使得文字分割比較困難。

圖一. 驗證碼實例

接下來,我們設計如圖二卷積神經網絡:

圖二. 卷積神經網絡

圖二中的網絡和一般的CNN網絡沒有什么特殊之處,前部均是卷積、Pooling層,只有最后在分類時,將26個類別擴增到26*5=130個類別。對于每幅圖片的標簽而言,在這130維的向量中,每26個維度中有一個1,其余為0,編碼了五個字母。接著依然使用交叉熵作為代價函數進而優化此網絡。就這樣,只要對原先的分類網絡做簡單的改變即可解決驗證碼的識別問題。

再如對于數學表達式類型的驗證碼,我們的網絡也只是在編碼上把26分類問題變成了13分類問題。下例中(見圖三)最后一層的分類器便設計為3*13=39個類別。

圖三. 數學式類型驗證碼的識別

按照此種思路我們破解了很多風格的驗證碼,如圖四所示:

圖四. 不同風格驗證碼破解實例

二. 一些需要解決的實際工程問題

(1) 合成訓練數據

前文提到訓練的前提是已經擁有了大量的訓練數據,而實際在識別驗證碼時我們很難獲取足夠多的標注過的訓練數據。所以,我們不得不人工合成訓練數據。這一部分通常可以調用Java或者C#的文字渲染庫來完成。

訓練的數據并不是越多越好,主要的問題在于人工合成的數據未免和真實驗證碼在形態上有些差距,我們都很難合成出一模一樣的結果。字體、字號及變形程度都或多或少與真實數據不同,而這種不同可能直接導致訓練出的網絡面對真實數據時無法發揮作用。

我們的經驗是,針對真實數據的特點,在無法很相似地合成出訓練數據的情況下,要增大樣本的多樣性,實際上也是遵循了深度學習中數據增強(Data Augmentation)的思想。如圖五所示,左邊為真實數據,我們在合成數據時特意增加了每個文字的旋轉、平移,加大了噪聲,使得訓練出的網絡能應對數據足夠的變化,從而可以識別出左圖中真實的例子。否則即便在合成數據上達到了很高的精度,在真實數據上也依然可能精度極低(即在合成數據上過擬合)。

圖五. 合成數據實例

(2) 網絡大小的選擇

針對不同的任務,網絡大小對結果的影響也是巨大的。并非所有的任務都得使用很深的網絡來訓練。理論上說,越深的網絡自由度越大,同時也非常容易過擬合。雖然有weight_decay這樣參數可以一定程度的對抗過擬合,但通常難度依然是很大的。所以一般來說,對于不太復雜的驗證碼應該選擇較小的網絡,只有遇到比較復雜的驗證碼如中文的成語等,我們的經驗才是復雜的網絡下效果才更好。

總之,驗證碼識別可以作為深度學習的一個練手項目來學習,在這個實際項目中可以更容易理解到深度學習理論中諸多概念。

 

 

來自:http://www.cnblogs.com/liinux/p/6267412.html

 

 本文由用戶 openyfs 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!