本文咱們來用 TensorFlow 來實現一個深度學習模型,用來實現驗證碼識別的過程,這裏識別的驗證碼是圖形驗證碼,首先咱們會用標註好的數據來訓練一個模型,而後再用模型來實現這個驗證碼的識別。python
這裏咱們使用 python 的 captcha 庫來生成便可,這個庫默認是沒有安裝的,因此這裏咱們須要先安裝這個庫,另外咱們還須要安裝 pillow 庫git
安裝好以後,咱們就能夠用以下代碼來生成一個簡單的圖形驗證碼api
能夠看到圖中的文字正是咱們所定義的內容,這樣咱們就能夠獲得一張圖片和其對應的真實文本,接下來咱們就能夠用它來生成一批訓練數據和測試數據了。數組
在訓練以前確定是要進行數據預處理了,如今咱們首先定義好了要生成的驗證碼文本內容,這就至關於已經有了 label 了,而後咱們再用它來生成驗證碼,就能夠獲得輸入數據 x 了,在這裏咱們首先定義好咱們的輸入詞表,因爲大小寫字母加數字的詞表比較龐大,設想咱們用含有大小寫字母和數字的驗證碼,一個驗證碼四個字符,那麼一共可能的組合是 (26 + 26 + 10) ^ 4 = 14776336 種組合,這個數量訓練起來有點大,因此這裏咱們精簡一下,只使用純數字的驗證碼來訓練,這樣其組合個數就變爲 10 ^ 4 = 10000 種,顯然少了不少。網絡
因此在這裏咱們先定義一個詞表和其長度變量:dom
這裏 VOCAB 就是詞表的內容,即 0 到 9 這 10 個數字,驗證碼的字符個數即 CAPTCHA_LENGTH 是 4,詞表長度是 VOCAB 的長度,即 10。函數
接下來咱們定義一個生成驗證碼數據的方法,流程相似上文,只不過這裏咱們將返回的數據轉爲了 Numpy 形式的數組:學習
這樣調用此方法,咱們就能夠獲得一個 Numpy 數組了,這個實際上是把驗證碼轉化成了每一個像素的 RGB,咱們調用一下這個方法試試:測試
內容以下:編碼
能夠看到它的 shape 是 (60, 160, 3),這其實表明驗證碼圖片的高度是 60,寬度是 160,是 60 x 160 像素的驗證碼,每一個像素都有 RGB 值,因此最後一維即爲像素的 RGB 值。
接下來咱們須要定義 label,因爲咱們須要使用深度學習模型進行訓練,因此這裏咱們的 label 數據最好使用 One-Hot 編碼,即若是驗證碼文本是 1234,那麼應該詞表索引位置置 1,總共的長度是 40,咱們用程序實現一下 One-Hot 編碼和文本的互相轉換:
這裏 text2vec() 方法就是將真實文本轉化爲 One-Hot 編碼,vec2text() 方法就是將 One-Hot 編碼轉回真實文本。
例如這裏調用一下這兩個方法,咱們將 1234 文本轉換爲 One-Hot 編碼,而後在將其轉回來:
這樣咱們就能夠實現文本到 One-Hot 編碼的互轉了。
接下來咱們就能夠構造一批數據了,x 數據就是驗證碼的 Numpy 數組,y 數據就是驗證碼的文本的 One-Hot 編碼,生成內容以下:
這裏咱們定義了一個 getrandomtext() 方法,能夠隨機生成驗證碼文本,而後接下來再利用這個隨機生成的文原本產生對應的 x、y 數據,而後咱們再將數據寫入到 pickle 文件裏,這樣就完成了預處理的操做。
有了數據以後,咱們就開始構建模型吧,這裏咱們仍是利用 traintestsplit() 方法將數據分爲三部分,訓練集、開發集、驗證集:
接下來咱們使用者三個數據集構建三個 Dataset 對象:
而後初始化一個迭代器,並綁定到這個數據集上:
接下來就是關鍵的部分了,在這裏咱們使用三層卷積和兩層全鏈接網絡進行構造,在這裏爲了簡化寫法,直接使用 TensorFlow 的 layers 模塊:
這裏卷積核大小爲 3,padding 使用 SAME 模式,激活函數使用 relu。
通過全鏈接網絡變換以後,y 的 shape 就變成了 [batchsize, nclasses],咱們的 label 是 CAPTCHALENGTH 個 One-Hot 向量拼合而成的,在這裏咱們想使用交叉熵來計算,可是交叉熵計算的時候,label 參數向量最後一維各個元素之和必須爲 1,否則計算梯度的時候會出現問題。詳情參見 TensorFlow 的官方文檔:
https://www.tensorflow.org/apidocs/python/tf/nn/softmaxcrossentropywithlogits
可是如今的 label 參數是 CAPTCHALENGTH 個 One-Hot 向量拼合而成,因此這裏各個元素之和爲 CAPTCHALENGTH,因此咱們須要從新 reshape 一下,確保最後一維各個元素之和爲 1:
這樣咱們就能夠確保最後一維是 VOCAB_LENGTH 長度,而它就是一個 One-Hot 向量,因此各元素之和一定爲 1。
而後 Loss 和 Accuracy 就好計算了:
再接下來執行訓練便可:
在這裏咱們首先初始化 traininitializer,將 iterator 綁定到 Train Dataset 上,而後執行 trainop,得到 loss、acc、gstep 等結果並輸出。
運行訓練過程,結果相似以下:
訓練過程咱們還能夠每隔幾個 Epoch 保存一下模型:
固然也能夠取驗證集上準確率最高的模型進行保存。
驗證時咱們能夠從新 Reload 一下模型,而後進行驗證: