原文地址:https://finthon.com/python-tensorflow-cnn-captcha/
近年來,機器學習變得愈加火熱,中國選手柯潔與AlphaGo的人機大戰(zhàn)更是引起熱議。目前,在圖像識別和視覺分析研究中,卷積神經(jīng)網(wǎng)絡(CNN)技術(shù)的使用越來越多。Tensorflow 是由 Google 團隊開發(fā)的神經(jīng)網(wǎng)絡模塊,短短幾年間, 就已經(jīng)有很多次版本的更新。最近我也在自學Tensorflow,想通過卷積神經(jīng)網(wǎng)絡快速識別整塊驗證碼(不分割字符)。期間也碰到許多問題,諸如軟件安裝,Tensorflow版本差異等。一開始學習tensorflow是盲目的,不知如何下手,網(wǎng)上的資料都比較單一,為了回報社會,讓大家少走彎路,我將詳細介紹整個過程。本教程所需要的完整材料,我都會放在這里,密碼:5e91。限于個人水平,如有錯誤請指出!
接下來我將介紹如何使用Python+Tensorflow的CNN技術(shù)快速識別驗證碼。在此之前,介紹我們用到的工具:
1. PyCharm社區(qū)版(python的IDE):寫代碼非常方便,安裝第三方庫(tensorflow 1.2.1)操作簡單。
2. Python3:當我還在猶豫py2還是py3的時候,tensorflow已能支持windows、py3了,并且python3代表未來,建議使用Python3。
3. Photoshop:用于驗證碼的分析和處理(在這里不需要你精通)。
本文將從以下幾個方面來介紹:
驗證碼分析和處理—— tensorflow安裝 —— 模型訓練 —— 模型預測
驗證碼分析和處理
網(wǎng)上搜索驗證碼識別能夠得到很多教程,但大部分都是將驗證碼切割成單個字符訓練,有時候 驗證碼字符大小不一或者發(fā)生重疊,切割驗證碼變得不適用。因此通過CNN技術(shù)將整塊驗證碼進行識別,能使問題變得更加簡單(以下操作對其他驗證碼分析有參考作用)。
在這里我們選擇模擬學習這樣的驗證碼:
該驗證碼來源于這里(正如sci-hub網(wǎng)站所言"to remove all barriers in the way of science",知識就該如此)。
該驗證碼只由六位小寫字母、噪點和干擾線組成,如果能去除噪點和干擾線,能夠大大降低學習的難度。很多驗證碼的噪點和干擾線RGB值和字母的不一致,這個我們能通過Photoshop來分析,使用顏色取樣器工具,分別在圖片噪點、干擾線、空白處和字母處點擊獲得RGB值,如下圖:
分析后發(fā)現(xiàn),只要將圖片二值化只保留字母,就能得到不錯的輸入圖片:
實現(xiàn)代碼如下:
以上就是驗證碼處理方法,為了下面的分析方便,我將處理好的驗證碼打包放到這里,密碼:5e91。
Tensorflow安裝
如果你查看了官方文檔會發(fā)現(xiàn)提供了很多安裝方式,但是還是比較復雜。針對不同的系統(tǒng),不同設備(CPU or GPU)都不一樣,我在這里選擇用pycharm直接安裝tensorflow非常好用,而且跟python版本兼容,不用考慮過多。打開pycharm,在菜單欄里flie-settings-project-project interpreter,選擇python3 interpreter,
然后點擊+按鈕,輸入tensorflow,install package。
至此,tensorflow就在電腦上安裝好了,非常簡單吧,我安裝的時候版本是1.2.1。準備工作全部結(jié)束。
模型訓練
如果你對卷積神經(jīng)網(wǎng)絡或者Python代碼實現(xiàn)還不熟悉,我推薦你先看看《tensorflow實戰(zhàn)》黃 文堅著這本書,比官方文檔詳細多。搞清楚代碼如何實現(xiàn)后,再來看接下來的內(nèi)容(畢竟我也是花了時間走彎路的)。
首先,我們先輸入驗證碼的信息備用,圖片是114*450像素,最大有6個字母,每個字母通過26個0或1表示,比如a表示成10000000000000000000000000,b表示成01000000000000000000000000,以此類推。
接下來定義一個函數(shù),隨機從訓練集(3430張)中提取驗證碼圖片,由于驗證碼經(jīng)過我手動打標簽(碼了6小時),在這里只要獲取驗證碼的名字和圖片就夠了,我默認放在"F:/captcha4/"目錄下,需要注意的是返回的圖片是以矩陣的形式。
接下來定義兩個函數(shù),將名字轉(zhuǎn)變成向量,將向量轉(zhuǎn)變成名字。
生成一個訓練batch,也就是采樣的大小,默認一次采集64張驗證碼作為一次訓練,需要注意通過get_name_and_image()函數(shù)獲得的image是一個含布爾值的矩陣,在這里通過1*(image.flatten())函數(shù)轉(zhuǎn)變成只含0和1的1行114*450列的矩陣。
接下來定義卷積神經(jīng)網(wǎng)絡結(jié)構(gòu),我們采用3個卷積層加1個全連接層的結(jié)構(gòu),在每個卷積層中都選用2*2的最大池化層和dropout層,卷積核尺寸選擇5*5。需要注意的是在全連接層中,我們的圖片114*450已經(jīng)經(jīng)過了3層池化層,也就是長寬都壓縮了8倍,得到15*57大小。
結(jié)構(gòu)建立好后就可以開始訓練了,在這里選擇的sigmoid_cross_entropy_with_logits()交叉熵來比較loss,用adam優(yōu)化器來優(yōu)化。輸出每一步的loss值,每100步,輸出一次準確率。在這里我調(diào)節(jié)當準確率達到99%后,結(jié)束訓練。需要注意的是,keep_prob = 0.5,這個參數(shù)控制著過擬合,當我們機器學習速度過快的時候,可以減小該值,讓機器遺忘的多一點(像人一樣,記得多不一定好,哈哈)。
訓練完成后,你應該會得到如下幾個文件。在這里我花了將近9個小時跑了1800步,達到99.5%的準確率。輸出文件的詳細介紹參考這里。
模型預測
我們的模型訓練成功后,我們就要檢驗一下該模型的預測水平,在這里我們首先要把train_crack_captcha_cnn()函數(shù)注釋掉,然后再定義一個預測模型的函數(shù)crack_captcha(),需要注意為了從預測集中抽數(shù)據(jù),這里的get_name_and_image()函數(shù)調(diào)用"F:/captcha5/"目錄下的10張預測圖片。
預測結(jié)果如下:
經(jīng)過比較,我發(fā)現(xiàn)10張預測的能有4張準確,這還有待改進,但是整體上還是達到了我的要求。畢竟訓練集的準確率有99.5%。如果我調(diào)低keep_prob的值,增加樣本量,增加卷積層,最后的預測效果應該會更好。完整代碼詳見
總之,通過上面這個教程,只是教大家如何通過tensorflow的CNN技術(shù)處理整塊驗證碼,大家可以嘗試著用其他驗證碼試試,但是樣本量越多越好。
總結(jié)
首先本文教大家如何簡單處理驗證碼,然后介紹了tensorflow的快速安裝方式,最后通過實現(xiàn)了CNN下整塊驗證碼的識別,訓練集準確率達到99.5%,測試集準確率在40%左右。如果調(diào)低keep_prob的值,增加樣本量,增加卷積層,最后的預測效果應該會更好。
希望大家以后在tensorflow的學習道路中少點阻礙!!!
可能感興趣
使用Python+Tensorflow的CNN技術(shù)快速識別驗證碼
"笨方法"學習CNN圖像識別(二)—— tfrecord格式高效讀取數(shù)據(jù)
"笨方法"學習CNN圖像識別(三)—— ResNet網(wǎng)絡訓練及預測