CNN+BLSTM+CTC的驗(yàn)證碼識(shí)別從訓(xùn)練到部署

項(xiàng)目地址:https://github.com/kerlomz/captcha_trainer

編譯版下載地址: https://github.com/kerlomz/captcha_trainer/releases/tag/v1.0

注意:若使用云服務(wù)器 (Windows Server版) 遇到閃退,請(qǐng)按照步驟:我的電腦——屬性——管理——添加角色和功能——勾選桌面體驗(yàn),點(diǎn)擊安裝双仍,安裝之后重啟即可懊亡。

2020/06/01編外:

想必各位只是偶然間搜到這篇文章,網(wǎng)上文章參差不齊,標(biāo)題黨很多,能跑起來的開源代碼很少渺氧,對(duì)于能跑起來的代碼友驮,也經(jīng)常遇到以下問題如:內(nèi)存泄漏漂羊,網(wǎng)絡(luò)參數(shù)寫死導(dǎo)致更換訓(xùn)練集報(bào)錯(cuò),網(wǎng)絡(luò)跑其他樣本識(shí)別率低喊儡,沒有調(diào)用示例等等拨与。

再往下看之前,我可以向你們保證艾猜,它絕對(duì)會(huì)是你所見過的所有驗(yàn)證碼有關(guān)的文章中最實(shí)用买喧,最接近生產(chǎn)水平的。

  1. 對(duì)小白: 你可以不需要?jiǎng)邮謱懭魏我恍写a匆赃。
  2. 對(duì)小企業(yè): 它的可用性和穩(wěn)定性是經(jīng)得起考驗(yàn)的淤毛,在性能上也是同行領(lǐng)先的,可以放心入坑算柳。
6A39702C8347047C6749854A40831DE0.gif

因?yàn)樾【幋蛩戕D(zhuǎn)行了低淡,離開這個(gè)行業(yè)之前總要留下點(diǎn)什么證明自己來過,總有人和我說的這個(gè)部署不會(huì)調(diào)用瞬项,可能你們想要的是一行pip就搞定環(huán)境的蔗蹋,所以今天給你們安排了麻瓜OCR(MuggleOCR)。
https://pypi.org/project/muggle-ocr
它整合了簡單驗(yàn)證碼識(shí)別通用模型+印刷文字通用識(shí)別囱淋,并且支持調(diào)用本文框架訓(xùn)練的模型猪杭。調(diào)用只需要三行核心代碼:

import time
# STEP 1
import muggle_ocr
import os
# STEP 2
sdk = muggle_ocr.SDK(model_type=muggle_ocr.ModelType.OCR)
root_dir = r"./imgs"
for i in os.listdir(root_dir):
    n = os.path.join(root_dir, i)
    with open(n, "rb") as f:
        b = f.read()
    st = time.time()
    # STEP 3
    text = sdk.predict(image_bytes=b)
    print(i, text, time.time() - st)

這真的很簡單,應(yīng)付一般的文字識(shí)別和驗(yàn)證碼都足夠了妥衣。(文字識(shí)別過幾天會(huì)更新一下新模型皂吮,畢竟0601模型就跑了半天。

1. 前言

本項(xiàng)目適用于Python3.7税手,GPU>=NVIDIA GTX1050Ti蜂筹,原master分支新增了GUI配置界面以及編譯版本了,是時(shí)候?qū)懸黄碌奈恼铝恕?/p>

長話短說芦倒,開門見山艺挪,網(wǎng)絡(luò)上現(xiàn)有的代碼以教學(xué)研究為主,本項(xiàng)目是為實(shí)用主義者定制的兵扬,只要基本的環(huán)境安裝常識(shí)麻裳,便可很好的訓(xùn)練出期望的模型,重定義幾個(gè)簡單的參數(shù)任何人都能使用深度學(xué)習(xí)技術(shù)訓(xùn)練一個(gè)商業(yè)化成品周霉。

筆者選用的時(shí)下最為流行的CNN+BLSTM+CTC(CRNN)進(jìn)行端到端的不定長驗(yàn)證碼識(shí)別掂器,代碼中預(yù)留了CNNX(搜不到因?yàn)槭切【幾约浩礈惖模?MobileNet/DenseNet121/ResNet50等選項(xiàng)亚皂,可以在配置界面中直接選用俱箱。首先,介紹個(gè)大概吧灭必。


main.png
網(wǎng)格結(jié)構(gòu) predict-CPU predict-GPU 模型大小
CNN5+Bi-LSTM+H64+CTC 15ms 8ms 2mb
CNN5+CrossEntropy 8ms 2ms 1.5mb

H16/H64指的是Bi-LSTM的隱藏神經(jīng)元個(gè)數(shù)UnitsNum狞谱,所以本項(xiàng)目使用GPU訓(xùn)練乃摹,使用CPU進(jìn)行預(yù)測(cè)。預(yù)測(cè)服務(wù)部署項(xiàng)目源碼請(qǐng)移步此處:https://github.com/kerlomz/captcha_platform
部署項(xiàng)目的編譯版下載地址:https://github.com/kerlomz/captcha_platform/releases

2.環(huán)境依賴:

花了超長篇幅介紹了訓(xùn)練環(huán)境的基本搭建跟衅,主要是給尚未入門的讀者看的孵睬,老鳥們隨便跳過,若不希望在環(huán)境上面浪費(fèi)時(shí)間的伶跷,歡迎使用編譯版掰读,可在文章開頭找到下載地址。

關(guān)于CUDA和cuDNN版本的問題叭莫,不少人很糾結(jié)蹈集,這里就列出官方通過pip安裝的TensorFlow的版本對(duì)應(yīng)表:

Linux

Version Python version Compiler Build tools cuDNN CUDA
tensorflow_gpu-1.14.0 3.7 GCC 4.8 Bazel 0.15.0 7.6 9

Windows

Version Python version Compiler Build tools cuDNN CUDA
tensorflow_gpu-1.14.0 3.7 MSVC 2015 update 3 Bazel 0.15.0 7.6 10

如果希望使用上面對(duì)應(yīng)之外的搭配的CUDA和cuDNN,可以自行編譯TensorFlow雇初,或者去Github上搜索TensorFlow Wheel找到第三方編譯的對(duì)應(yīng)版本的whl安裝包拢肆。提前預(yù)警,若是自己編譯將會(huì)苦難重重靖诗,坑很多郭怪,這里就不展開了。

2.1 本項(xiàng)目環(huán)境依賴

目前在以下主流操作系統(tǒng)平臺(tái)均測(cè)試通過:

操作系統(tǒng) 最低支持版本
Ubuntu 16.04
Windows 7 SP1
MacOS N/A

本訓(xùn)練項(xiàng)目主要的環(huán)境依賴清單如下

依賴 最低支持版本
Python 3.7
TensorFlow-GPU 1.14.0
Opencv-Python 4.1.2.30
Numpy 1.16.0
Pillow 4.3.0
PyYaml 3.13
tqdm N/A

2.1.1 Ubuntu 16.04 下的 Python 3.7

1)先安裝Python環(huán)境(有Python 3.7環(huán)境的可以忽略)

sudo apt-get install openssl  
sudo apt-get install libssl-dev
sudo apt-get install libc6-dev gcc  
sudo apt-get install -y make build-essential zlib1g-dev libbz2-dev libreadline-dev $ libsqlite3-dev wget curl llvm tk-dev 
wget https://www.python.org/ftp/python/3.7.6/Python-3.7.6.tgz
tar -vxf Python-3.7.6.tar.xz
cd Python-3.7.6
./configure --prefix=/usr/local  --enable-shared
make -j8
sudo make install -j8

經(jīng)過上面指令就安裝好Python3.7環(huán)境了刊橘,如果提示找不到libpython3.7m.so.1.0就到/usr/local/lib路徑下將該文件復(fù)制一份到/usr/lib和/usr/lib64路徑下鄙才。
2)安裝相關(guān)依賴(這一步Windows和Linux通用)
可以直接在項(xiàng)目路徑下執(zhí)行pip3 install -r requirements.txt安裝所有依賴,注意這一步是安裝在全局Python環(huán)境下的伤为,強(qiáng)烈建議使用虛擬環(huán)境進(jìn)行項(xiàng)目間的環(huán)境隔離咒循,如VirtualenvAnaconda等等。
我一般使用的是Virtualenv绞愚,有修改代碼需要的叙甸,建議安裝PyCharm作為Python IDE

virtualenv -p /usr/bin/python3 venv # venv is the name of the virtual environment.
cd venv/ # venv is the name of the virtual environment.
source bin/activate # to activate the current virtual environment.
cd captcha_trainer # captcha_trainer is the project path.
pip3 install -r requirements.txt

2.1.2 Ubuntu 16.04 下的 CUDA/cuDNN

網(wǎng)上看到過很多教程,我自己也部署過很多次位衩,Ubuntu 16.04遇到的坑還是比較少的裆蒸。14.04支持就沒那么好,如果主板不支持關(guān)閉SecureBoot的話千萬不要安裝Desktop版糖驴,因?yàn)榘惭b好之后一定會(huì)無限循環(huán)在登陸界面無法進(jìn)入桌面僚祷。
網(wǎng)上教程說要加驅(qū)動(dòng)黑名單什么的我直接跳過了,親測(cè)沒那個(gè)必要贮缕。就簡單的幾步:
1. 下載好安裝包
注意下載runfile類型的安裝包辙谜,deb安裝會(huì)自動(dòng)安裝默認(rèn)驅(qū)動(dòng),極有可能導(dǎo)致登陸循環(huán)
NVIDIA 驅(qū)動(dòng)下載:https://www.geforce.cn/drivers
CUDA 下載地址:https://developer.nvidia.com/cuda-downloads
cuDNN 下載地址:https://developer.nvidia.com/cudnn (需要注冊(cè)NVIDIA賬號(hào)且登陸感昼,下載deb安裝包)

2. 關(guān)閉圖形界面
Ctrl+alt+F1進(jìn)入字符界面装哆,關(guān)閉圖形界面

sudo service lightdm stop

3. 安裝Nvidia Driver

命令中的版本自己對(duì)應(yīng)下載的版本改,在上面的下載地址根據(jù)自己的顯卡型號(hào)下載最新版,切記是runfile格式的安裝包蜕琴。

sudo chmod a+x NVIDIA-Linux-x86_64-384.90.run //獲取執(zhí)行權(quán)限
sudo ./NVIDIA-Linux-x86_64-384.90.run –no-x-check –no-nouveau-check –no-opengl-files //安裝驅(qū)動(dòng)

安裝成功以后使用以下命令驗(yàn)證萍桌,如果顯示顯卡信息則表示安裝成功

nvidia-smi

4. 安裝CUDA

1)先安裝一些系統(tǒng)依賴庫

sudo apt-get install freeglut3-dev build-essential libx11-dev libxmu-dev libxi-dev libgl1-mesa-glx libglu1-mesa libglu1-mesa-dev
  1. 執(zhí)行安裝程序,按指示無腦繼續(xù)就好了凌简,如果提示是否安裝驅(qū)動(dòng)選不安裝上炎。
sudo sh cuda_9.0.176_384.81_linux.run

安裝完如果環(huán)境變量沒配上去,就寫到 ~/.bashrc 文件的尾部

export PATH=/usr/local/cuda-9.0/bin${PATH:+:${PATH}}
export LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}

然后在終端執(zhí)行 sudo ldconfig更新雏搂,安裝完畢就可以重啟機(jī)器重啟圖形界面了藕施。

sudo service lightdm start

2.1.3 Windows 系統(tǒng)

在Windows其實(shí)簡單很多,只要到官網(wǎng)下載安裝包無腦安裝就可以了凸郑,下載連接同Ubuntu铅碍,先安裝Python,顯卡驅(qū)動(dòng)线椰,CUDA胞谈,然后下載對(duì)應(yīng)的cuDNN替換到對(duì)應(yīng)路徑即可。

3 使用

在訓(xùn)練之前憨愉,有不少群友經(jīng)常問我“訓(xùn)練4位數(shù)英文數(shù)字需要多少樣本烦绳?”諸如此類的問題,我這里統(tǒng)一做個(gè)回復(fù)配紫,樣本數(shù)量主要是看樣本的特征復(fù)雜度而定径密。

這里可以提供幾個(gè)參考依據(jù): 是否變形?是否旋轉(zhuǎn)躺孝?是否有復(fù)雜背景干擾享扔?是否多種字體?字符集(分類數(shù))多大植袍?位數(shù)(標(biāo)簽數(shù))多少惧眠?

  1. 一般簡單的幾百個(gè)樣本(需要自行調(diào)整 驗(yàn)證集大小驗(yàn)證批次大小 )即可。
  2. 稍微復(fù)雜的幾千個(gè)樣本一般都能搞定于个。
  3. 特別復(fù)雜的幾萬樣本起氛魁。
  4. 中文這種幾千個(gè)分類的一般十萬起。

注:只準(zhǔn)備一百個(gè)不到樣本的親們厅篓,千萬不要嘗試訓(xùn)練測(cè)試秀存,因?yàn)楦九懿黄饋怼?/strong>

入手的第一步環(huán)境搭建好了,那就是準(zhǔn)備跑代碼了羽氮,還是有幾個(gè)必要的條件或链,巧婦難為無米之炊,首先档押,既然是訓(xùn)練澳盐,要先有訓(xùn)練集尤筐,有一個(gè)新手嘗鮮的訓(xùn)練集,是mnist手寫識(shí)別的例子洞就,可以在騰訊云下載:https://share.weiyun.com/5pzGF4V
,現(xiàn)在萬事俱備掀淘,只欠東風(fēng)旬蟋。

3.1 定義一個(gè)模型

本項(xiàng)目基于參數(shù)化配置,不需要改動(dòng)任何代碼革娄,可以通過可視化界面操作訓(xùn)練幾乎任何字符型圖片驗(yàn)證碼倾贰。訓(xùn)練框架界面可以大致劃分為幾個(gè)部分:

  1. Neural Network - 神經(jīng)網(wǎng)絡(luò)區(qū)


    0.png
  2. Project Configuration - 項(xiàng)目配置區(qū)


    1.png
  3. Sample Source - 樣本源配置區(qū)


    2.png
  4. Training Configuration - 訓(xùn)練配置區(qū)


    3.png
  5. Buttons - 功能控制區(qū)


    4.png

依此類推的訓(xùn)練配置的步驟如下:

  1. 神經(jīng)網(wǎng)絡(luò)區(qū) 的配置項(xiàng)看起來很多,對(duì)于新手來說拦惋,可以直接使用默認(rèn)的配置:CNNX+GRU+CTC+C1組合(CNN前置網(wǎng)絡(luò)+GRU+CTC+單通道)匆浙。
  2. 項(xiàng)目配置區(qū) 的配置項(xiàng)在網(wǎng)絡(luò)選好之后配置項(xiàng)目名,按回車或者點(diǎn)擊空白處確認(rèn)厕妖。
  3. 樣本源配置區(qū) 的配置項(xiàng)用來配置樣本源的路徑首尼,訓(xùn)練樣本是根據(jù)此路徑進(jìn)行打包成TFRecords格式,驗(yàn)證樣本可以不指定言秸,使用[Validation Set Num]參數(shù)隨機(jī)從訓(xùn)練集總抽樣成驗(yàn)證集软能。
  4. 訓(xùn)練配置區(qū) 的配置項(xiàng)負(fù)責(zé)定義訓(xùn)練完成的條件如:結(jié)束準(zhǔn)確率,結(jié)束COST举畸,結(jié)束Epochs查排,批次大小
  5. 功能控制區(qū) 的配置項(xiàng),設(shè)置完上面步驟抄沮,先點(diǎn)擊[Make Dataset] 打包樣本跋核,再點(diǎn)擊[Start Training]開始訓(xùn)練。

以下部分有基礎(chǔ)的讀者們可以了解一下:

如若使用CrossEntropy作為解碼器需要注意標(biāo)簽數(shù)LabelNum和圖片尺寸需要滿足的關(guān)系叛买,因?yàn)榫W(wǎng)絡(luò)為多標(biāo)簽而設(shè)計(jì)(一般的多標(biāo)簽采用直接連接多個(gè)分類器)砂代,卷積層的輸出 outputs 經(jīng)過了以下變換:

Reshape([label_num, int(outputs_shape[1] / label_num)])

為了保證運(yùn)算 int(outputs_shape[1] / label_num) 能夠取得正整數(shù),也意味著他們之間存在某種關(guān)系率挣,對(duì)于CNN5+Cross Entropy的網(wǎng)絡(luò)結(jié)構(gòu)泊藕,Conv2D層的步長皆為1,那么需要保證以下關(guān)系成立:

mod(\frac{輸入寬度\times輸入高度\times輸出層參數(shù)}{池化步長^{池化層數(shù)}\times標(biāo)簽數(shù)})= 0

所以有時(shí)候需要Resize網(wǎng)絡(luò)輸入的Shape

網(wǎng)絡(luò) 池化步長^池化層數(shù) 輸出層參數(shù)
CNN5 16 64
CNNX 8 64
ResNet50 16 1024
DenseNet 32 2048

例如使用CNN5+CrossEntropy組合难礼,則輸入寬度與輸入高度需要滿足:
mod(\frac{輸入寬度\times輸入高度\times64}{16\times標(biāo)簽數(shù)})= 0
同理如果CNN5+RNN+CTC娃圆,卷積層之后的輸出經(jīng)過以下變換:

Reshape([-1, outputs_shape[2] * outputs_shape[3]])

原輸出(batch_size, outputs_shape[1], outputs_shape[2], outputs_shape[3]),RNN層的輸入輸出要求為(batch, timesteps, num_classes)蛾茉,為了接入RNN經(jīng)過以上操作讼呢,那么又引出一個(gè)Time Step的概念,所以timesteps的值也是 outputs_shape[1]谦炬,而CTC Loss要求的輸入為 [batch_size, frames, num_labels]悦屏,若是 timesteps 小于標(biāo)簽數(shù)則無法計(jì)算損失节沦,也就無法找損失函數(shù)中找到極小值,梯度何以下降础爬。timesteps 最合理的值一般是標(biāo)簽數(shù)的2倍甫贯,為了達(dá)到目的,也可以通過Resize網(wǎng)絡(luò)輸入的Shape解決看蚜,一般情況timesteps直接關(guān)聯(lián)于圖片寬度叫搁,大多情況只要按比例放大寬度即可。

ExtractRegex 參數(shù):

注意:如果訓(xùn)練集的命名格式和我提供的新手訓(xùn)練集不一樣供炎,請(qǐng)根據(jù)實(shí)際情況修改ExtractRegex的正則表達(dá)式渴逻。目前只支持在yaml配置文件中直接修改,尚未提供GUI界面修改的支持音诫。 DatasetPath 和SourcePath參數(shù)允許多個(gè)路徑惨奕,這種操作適用于需要將多種樣本訓(xùn)練為一個(gè)模型,或者希望訓(xùn)練一套通用泛化模型的人竭钝。
字符集Category其實(shí)大多數(shù)情況下不需要修改梨撞,一般的圖形驗(yàn)證碼離不開數(shù)字和英文,而且一般來說是大小寫不敏感的香罐,不區(qū)分大小寫聋袋,因?yàn)榇虼a平臺(tái)收集的訓(xùn)練集質(zhì)量參差不齊,有些大寫有些小寫穴吹,不如全部統(tǒng)一為小寫幽勒,默認(rèn)ALPHANUMERIC_LOWER則會(huì)自動(dòng)將大寫的轉(zhuǎn)為小寫,字符集可定制化很靈活港令,除了配置備注上提供的幾種類型啥容,還可以訓(xùn)練中文,自定義字符集用list表示顷霹,示例如下:

Category: ['常', '世', '寧', '慢', '南', '制', '根', '難']

如果是單標(biāo)簽分類咪惠,可以配合LabelNum=1,例如:

Category: ["航母", "雨靴", "毛線", "安全帽", "調(diào)色板", "海鷗", "日歷", "網(wǎng)球拍", ......]

其文件名示例:航母_1231290424123.png

如果是多標(biāo)簽分類淋淀,可以配合LabelSplit=&遥昧,例如:

Category: ["航母", "雨靴", "毛線", "安全帽", "調(diào)色板", "海鷗", "日歷", "網(wǎng)球拍", ......]

其文件名示例:航母&雨靴&毛線_1231290424123.png

可以自己根據(jù)收集訓(xùn)練集的實(shí)際字符集使用率來定義,也可以無腦網(wǎng)上找3500常用字來訓(xùn)練朵纷,注意:中文字符集一般比數(shù)字英文大很多炭臭,剛開始收斂比較慢,需要更久的訓(xùn)練時(shí)間袍辞,也需要更多的樣本量鞋仍,請(qǐng)量力而行

QQ截圖20181204150924.png

形如上圖的圖片能輕松訓(xùn)練到95%以上的識(shí)別率。
ImageWidth搅吁、ImageHeight只要和當(dāng)前圖片尺寸匹配即可威创,其實(shí)這里的配置主要是為了方便后面的部署智能策略落午。

Pretreatment參數(shù):

該參數(shù)是用來做圖片預(yù)處理的,例如形如以下的GIF動(dòng)圖肚豺,


2pc5uv_8989.gif

可以使用ConcatFrames參數(shù)選取幀對(duì)兩幀進(jìn)行水平拼接溃斋,適用于處理滾動(dòng)型GIF,而閃爍型GIF可以使用BlendFrames參數(shù)進(jìn)行融合吸申。

3.2 開始訓(xùn)練

  1. 經(jīng)過 采集標(biāo)注樣本形如 xxx_隨機(jī)數(shù).png


    QQ截圖20200531182034.png
  2. 打包樣本
    通過GUI界面的 [Make Dataset] 或者 make_dataset.py 直接打包梗劫。
    注意:使用源碼運(yùn)行本項(xiàng)目的功能模塊需要具備一定的語言基礎(chǔ),參數(shù)修改的部分和示例已預(yù)留好呛谜,盡量不修改核心類或函數(shù)的代碼以免出現(xiàn)錯(cuò)誤。

按照上面的介紹枪萄,配置只要修改極少數(shù)的參數(shù)對(duì)應(yīng)的值隐岛,就可以開啟正式的訓(xùn)練之旅了,具體操作如下:
可以直接使用 PyCharm 的 Run瓷翻,執(zhí)行 trains.py聚凹,也可以在激活Virtualenv下使用終端亦或在安裝依賴的全局環(huán)境下執(zhí)行,但本文建議全程使用GUI界面進(jìn)行操作齐帚,使用GUI僅需啟動(dòng) app.py 即可妒牙。

python3 trains.py

剩下的就是等了,看過程对妄,等結(jié)果湘今。
正常開始訓(xùn)練的模樣應(yīng)該是這樣的:

訓(xùn)練結(jié)束會(huì)在項(xiàng)目的out路徑下生成一個(gè)包含pb文件的graph目錄和包含yaml文件的model目錄,下面該到部署環(huán)節(jié)了剪菱。

3.3 部署

真的很有必要認(rèn)真的介紹一下部署項(xiàng)目摩瞎,比起訓(xùn)練,這個(gè)部署項(xiàng)目傾注了筆者更多的心血孝常,為什么呢旗们?
項(xiàng)目地址:https://github.com/kerlomz/captcha_platform

如希望將本系統(tǒng)集成于自己的項(xiàng)目中的可以參考python-sdk的使用:
https://pypi.org/project/muggle-ocr/
該項(xiàng)目的核心基于 captcha_platform/sdk/pb/sdk.py 可以根據(jù)需要自行修改,抑或直接使用MuggleOCR 調(diào)用訓(xùn)練框架生產(chǎn)的模型构灸。(具體調(diào)用方法可點(diǎn)擊上面鏈接有對(duì)應(yīng)的文檔介紹)

編譯版:https://github.com/kerlomz/captcha_platform/releases上渴,使用編譯版無需安裝Python和TensorFlow環(huán)境。

真的值得了解的幾點(diǎn)

  1. 同時(shí)管理多個(gè)模型喜颁,支持模型熱拔插
  2. 靈活的版本控制
  3. 支持批量識(shí)別
  4. 服務(wù)智能路由策略

首先筆者重寫了TensorFlow的Graph會(huì)話管理稠氮,設(shè)計(jì)會(huì)話池,允許同時(shí)管理多模型半开,實(shí)現(xiàn)多模型動(dòng)態(tài)部署方案括袒。

1) 訓(xùn)練好的 pb模型只要放在部署項(xiàng)目的graph路徑下,yaml模型配置文件放在model稿茉, 即可被服務(wù)發(fā)現(xiàn)并加載锹锰。(用SDK調(diào)用時(shí)芥炭,兩者置于同一目錄下)

2) 如果需要卸載一個(gè)正在服務(wù)的模型,只需要在model中刪除該模型的yaml配置文件恃慧,在graph中刪除對(duì)應(yīng)的pb模型即可园蝠。

3) 如果需要更新一個(gè)已經(jīng)服務(wù)中的模型,只需修改新版的模型yaml配置文件的版本號(hào)高于原模型的版本號(hào)痢士,按先放pb后放yaml的順序彪薛,服務(wù)便會(huì)自動(dòng)發(fā)現(xiàn)新版的模型并加載使用,舊的模型將因版本低于新版模型不會(huì)被調(diào)用怠蹂,可以按照上述的卸載方法卸載已被棄用的模型釋放內(nèi)存善延。
上面的操作中無需重啟服務(wù),完全的無縫切換

其次城侧,一套服務(wù)想要服務(wù)于各式各樣的圖像識(shí)別需求易遣,可以定義一套策略,訓(xùn)練時(shí)將所有尺寸一樣的圖片訓(xùn)練成一個(gè)模型嫌佑,服務(wù)根據(jù)圖片尺寸自動(dòng)選擇使用哪個(gè)模型豆茫,這樣的設(shè)計(jì)使定制化和通用性共存,等積累到一定多樣的訓(xùn)練集時(shí)可以將所有的訓(xùn)練集合到一起訓(xùn)練一個(gè)通用模型屋摇,亦可以彼此獨(dú)立揩魂,每個(gè)模型的疊加僅僅增加了少量的內(nèi)存或顯存,網(wǎng)上的方案大多是不同的模型單獨(dú)部署一套服務(wù)炮温,每個(gè)進(jìn)程加載了一整套TensorFlow框架勢(shì)必是過于龐大和多余的火脉。

用到批量識(shí)別需求的人相對(duì)少很多這里就不展開介紹了。但是這里給出一個(gè)12306的例子:

FieldParam:
  CorpParams: [
    {
      "start_pos": [118, 0],
      "interval_size": [0, 0],
      "corp_num": [1, 1],
      "corp_size": [60, 30]
    },
    {
      "start_pos": [5, 40],
      "interval_size": [5, 5],
      "corp_num": [4, 2],
      "corp_size": [66, 66]
    }
  ]
  OutputCoord: True

該參數(shù)可以用于大圖的裁剪組成一批小圖作為一個(gè)批次的輸入柒啤,改用法可以避免多次調(diào)用忘分。

但是識(shí)別項(xiàng)目提供了多套可選的服務(wù)有:gRPC,F(xiàn)lask白修,Tornado妒峦,Sanic,其中Flask和Tornado提供了加密接口兵睛,類似于微信公眾號(hào)開發(fā)接口的SecretKey和AccessKey接口肯骇,感興趣的可以在demo.py中閱讀調(diào)用源碼了解。

部署的使用可以經(jīng)過package.py編譯為可執(zhí)行文件祖很,這樣可以免去更換機(jī)器環(huán)境安裝的煩惱吃媒,部署項(xiàng)目安裝流程同訓(xùn)練項(xiàng)目候醒,項(xiàng)目中提供的requirements.txt已經(jīng)將所需的依賴都列清楚了棵磷,強(qiáng)烈建議部署項(xiàng)目安裝cpu版TensorFlow风秤。

本項(xiàng)目部署推薦使用Tornado版,功能最齊全笨鸡,性能最為穩(wěn)定姜钳。

Linux:

  1. Tornado:
# 端口 19952
python3 tornado_server.py
  1. Flask
# 方案1坦冠,裸啟動(dòng), 端口 19951
python flask_server.py 
# 方案2哥桥,使用gunicorn辙浑,端口 5000
pip install gunicorn 
gunicorn -c deploy.conf.py flask_server:app
  1. Sanic:
# 端口 19953
python3 sanic_server.py
  1. gRPC:
# 端口 50054
python3 grpc_server.py
  1. 編譯版(基于Tornado)
# 前臺(tái)運(yùn)行
./captcha_platform_tornado
#后臺(tái)運(yùn)行
nohup ./captcha_platform_tornado &

Windows:
Windows平臺(tái)下都是通過python3 xxx_server.py啟動(dòng)對(duì)應(yīng)的服務(wù),注意拟糕,Tornado判呕、Flask、Sanic的性能在Windows平臺(tái)都大打折扣送滞,gRPC是Google開源的RPC服務(wù)侠草,有較為優(yōu)越的性能。
編譯版直接運(yùn)行編譯后的exe可執(zhí)行文件即可犁嗅。

3.4 調(diào)用/測(cè)試

1. Tornado服務(wù):

請(qǐng)求地址 Content-Type 參數(shù)形式 請(qǐng)求方法
http://localhost:19952/captcha/v1 application/json JSON POST

具體參數(shù):

參數(shù)名 必選 類型 說明
image Yes String Base64 編碼
model_name No String 模型名边涕,yaml配置中可綁定
need_color No String 顏色過濾,black/red/blue/yellow/green/white
output_split No String 多標(biāo)簽分割字符

請(qǐng)求為JSON格式愧哟,形如:{"image": "base64編碼后的圖像二進(jìn)制流"}

返回結(jié)果:

參數(shù)名 類型 說明
message String 識(shí)別結(jié)果或錯(cuò)誤消息
code String 狀態(tài)碼
success String 是否請(qǐng)求成功

該返回為JSON格式奥吩,形如:{"message": "xxxx", "code": 0, "success": true}

2. Flask服務(wù):

請(qǐng)求地址 Content-Type 參數(shù)形式 請(qǐng)求方法
http://localhost:19951/captcha/v1 application/json JSON POST

請(qǐng)求參數(shù)和返回格式同上

3. Sanic服務(wù):

請(qǐng)求地址 Content-Type 參數(shù)形式 請(qǐng)求方法
http://localhost:19953/captcha/v1 application/json JSON POST

請(qǐng)求參數(shù)和返回格式同上

4. gRPC服務(wù):
需要安裝依賴哼蛆,grpcio蕊梧、grpcio_tools和對(duì)應(yīng)的grpc.proto文件,可以直接從項(xiàng)目中的示例代碼demo.py中提取腮介。

python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. ./grpc.proto

grpcio肥矢、grpcio_tools 是根據(jù) grpc.proto 使用上述命令生成的。

class GoogleRPC(object):

    def __init__(self, host: str):
        self._url = '{}:50054'.format(host)
        self.true_count = 0
        self.total_count = 0

    def request(self, image, model_type=None, model_site=None):

        import grpc
        import grpc_pb2
        import grpc_pb2_grpc
        channel = grpc.insecure_channel(self._url)
        stub = grpc_pb2_grpc.PredictStub(channel)
        response = stub.predict(grpc_pb2.PredictRequest(
            image=image, split_char=',', model_type=model_type, model_site=model_site
        ))
        return {"message": response.result, "code": response.code, "success": response.success}

if __name__ == '__main__':
    result = GoogleRPC().request("base64編碼后的圖片二進(jìn)制流")
    print(result)

3.5 奇技淫巧

該項(xiàng)目還可以直接用于識(shí)別帶顏色的驗(yàn)證碼叠洗,部署項(xiàng)目middleware/impl/color_extractor.py基于k-means實(shí)現(xiàn)了顏色分離模塊甘改,可用于處理如下形式的驗(yàn)證碼:

紅色.png

還有一種方案是同時(shí)預(yù)測(cè)驗(yàn)證碼和每個(gè)字符對(duì)應(yīng)的顏色,不過這需要修改現(xiàn)有的神經(jīng)網(wǎng)絡(luò)進(jìn)行支持灭抑,在最后一層修改為雙輸出十艾,一個(gè)輸出顏色,一個(gè)輸出對(duì)應(yīng)字符腾节,這對(duì)于樣本標(biāo)注的要求較高忘嫉,也提高的成本,所以如果能用無限生成樣本案腺,那問題就迎刃而解了庆冕,比如上圖,筆者就寫了樣本生成代碼劈榨,感興趣的可以移步:
http://www.reibang.com/p/da1b972e24f2
其實(shí)還有很多很多技巧访递,例如,用生成的樣本代替訓(xùn)練集同辣,其實(shí)網(wǎng)上的圖片驗(yàn)證碼大多是采用開源的拷姿,稍作修改而已惭载,大多數(shù)情況都能被近似生成出來,上述展示的驗(yàn)證碼圖片不代表任何實(shí)際的網(wǎng)站跌前,如有雷同棕兼,純屬巧合,該項(xiàng)目只能用于學(xué)習(xí)和交流用途抵乓,不得用于非法用途伴挚。

后記

如果文章描述不夠詳盡或需要技術(shù)支持的,可以加群 857149419 咨詢灾炭,或在開源項(xiàng)目中提issue茎芋,很榮幸能為開源社區(qū)貢獻(xiàn)綿薄之力。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蜈出,一起剝皮案震驚了整個(gè)濱河市田弥,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌铡原,老刑警劉巖偷厦,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異燕刻,居然都是意外死亡只泼,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門卵洗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來请唱,“玉大人,你說我怎么就攤上這事过蹂∈螅” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵酷勺,是天一觀的道長本橙。 經(jīng)常有香客問我,道長脆诉,這世上最難降的妖魔是什么甚亭? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮库说,結(jié)果婚禮上狂鞋,老公的妹妹穿的比我還像新娘。我一直安慰自己潜的,他們只是感情好骚揍,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般信不。 火紅的嫁衣襯著肌膚如雪嘲叔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天抽活,我揣著相機(jī)與錄音硫戈,去河邊找鬼。 笑死下硕,一個(gè)胖子當(dāng)著我的面吹牛丁逝,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播梭姓,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼霜幼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了誉尖?” 一聲冷哼從身側(cè)響起罪既,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎铡恕,沒想到半個(gè)月后琢感,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡探熔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年驹针,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片祭刚。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡牌捷,死狀恐怖墙牌,靈堂內(nèi)的尸體忽然破棺而出涡驮,到底是詐尸還是另有隱情,我是刑警寧澤喜滨,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布捉捅,位于F島的核電站,受9級(jí)特大地震影響虽风,放射性物質(zhì)發(fā)生泄漏棒口。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一辜膝、第九天 我趴在偏房一處隱蔽的房頂上張望无牵。 院中可真熱鬧,春花似錦厂抖、人聲如沸茎毁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽七蜘。三九已至谭溉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間橡卤,已是汗流浹背扮念。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留碧库,地道東北人柜与。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像嵌灰,于是被迫代替她去往敵國和親旅挤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容