前言:
本文章將記錄我利用深度學(xué)習(xí)方法實(shí)現(xiàn)身份證圖像的信息識(shí)別系統(tǒng)的實(shí)現(xiàn)過程,及學(xué)習(xí)到的心得與體會(huì)。本次實(shí)踐是我投身AI的初次系統(tǒng)化的付諸實(shí)踐,意義重大,讓自己成長(zhǎng)許多。終于有空閑的時(shí)間,將其記錄,只為更好的分享與學(xué)習(xí)。
目錄:
1、本人的主要工作
2、關(guān)鍵技術(shù)
3、模型訓(xùn)練
4、系統(tǒng)設(shè)計(jì)及實(shí)現(xiàn)
5、總結(jié)
正文:
一、本人的主要工作
深度學(xué)習(xí)技術(shù)與傳統(tǒng)模式識(shí)別技術(shù)相比,免去人工提取特征,識(shí)別率更高。我基于深度學(xué)習(xí)的技術(shù)背景,主要的研究?jī)?nèi)容如下:
1)身份證圖像涉及個(gè)人隱私,很難獲取其數(shù)據(jù)訓(xùn)練集。針對(duì)此問題,我采用獲取身份證上印刷體漢字和數(shù)字的數(shù)據(jù)訓(xùn)練集的方法,利用Python圖像庫(PIL)將13類漢字印刷體字體轉(zhuǎn)換成6492個(gè)類別,建立了較大的字符訓(xùn)練集;
2)如何獲取身份證圖片上的字符是在設(shè)計(jì)中一個(gè)重要問題。我采用水平和垂直投影技術(shù),首先對(duì)身份證圖像進(jìn)行預(yù)處理,然后對(duì)圖片在水平和垂直方向上像素求和,區(qū)分字符與空白區(qū)域,完成了身份證圖像中字符定位與分割工作,有很好的切分效果;
3)在模型訓(xùn)練中模型的選擇與設(shè)計(jì)是一個(gè)重要的環(huán)節(jié),本文選擇Lenet模型,發(fā)現(xiàn)模型層次太淺,然后增加卷積層和池化層,設(shè)計(jì)出了改進(jìn)的深層Lenet模型,然后采用Caffe深度學(xué)習(xí)工具對(duì)模型進(jìn)行訓(xùn)練,并在訓(xùn)練好的模型上進(jìn)行測(cè)試,實(shí)驗(yàn)表明,模型的測(cè)試精度達(dá)到96.2%。
基于上述研究,本文設(shè)計(jì)并實(shí)現(xiàn)了身份證圖像自動(dòng)識(shí)別系統(tǒng),該系統(tǒng)先從移動(dòng)端拍照獲取身份證圖片,然后在Flask輕量級(jí)web服務(wù)器上將身份證圖像輸入到模型中進(jìn)行識(shí)別,并返回識(shí)別結(jié)果。設(shè)計(jì)的系統(tǒng)能準(zhǔn)確識(shí)別出身份證上文字信息,具有較高的準(zhǔn)確率,有一定的實(shí)用價(jià)值。
二、關(guān)鍵技術(shù)
2.1 深度學(xué)習(xí)介紹
深度學(xué)習(xí)技術(shù)被提出后,發(fā)展迅速,在人工智能領(lǐng)域取得了很好的成績(jī),越來越多優(yōu)秀的神經(jīng)網(wǎng)絡(luò)也應(yīng)運(yùn)而生。深度學(xué)習(xí)通過建立多個(gè)隱層的深層次網(wǎng)絡(luò)結(jié)構(gòu),比如卷積神經(jīng)網(wǎng)絡(luò),可以用來研究并處理目前計(jì)算機(jī)視覺領(lǐng)域的一些熱門的問題,如圖像識(shí)別和圖像檢索。
深度學(xué)習(xí)建立從輸入數(shù)據(jù)層到高層輸出層語義的映射關(guān)系,免去了人工提取特征的步驟,建立了類似人腦神經(jīng)網(wǎng)的分層模型結(jié)構(gòu)。深度學(xué)習(xí)的示意圖如圖所示
圖 有多個(gè)隱層的深度學(xué)習(xí)示意圖
深度學(xué)習(xí)的學(xué)習(xí)過程會(huì)分層進(jìn)行,深度學(xué)習(xí)經(jīng)過多層的學(xué)習(xí),最終可以很好的表示數(shù)據(jù)特征。
2.2 卷積神經(jīng)網(wǎng)絡(luò)(CNN)
卷積神經(jīng)網(wǎng)絡(luò)有了很多年的發(fā)展,CNN在對(duì)圖像的識(shí)別上有很好的表現(xiàn),利用權(quán)值共享的方式,降低了網(wǎng)絡(luò)的維度,也加快了訓(xùn)練網(wǎng)絡(luò)的效率。
CNN具有多層的神經(jīng)網(wǎng)絡(luò),有卷積層、池化層和線性整流層等,具體CNN網(wǎng)絡(luò)結(jié)構(gòu)示意圖如圖所示:
圖 卷積神經(jīng)網(wǎng)絡(luò)示意圖
如上圖所示,輸入數(shù)據(jù)圖像Input分別與三個(gè)濾波器做卷積運(yùn)算。卷積完成后, 函數(shù)得到的特征映射圖,然后再將特征映射圖輸入到 層。S2層處理完后到達(dá)C3層,和 C1 的處理步驟一樣,以此類推,最終輸出結(jié)果。
卷積神經(jīng)網(wǎng)絡(luò)的網(wǎng)絡(luò)結(jié)構(gòu)如下:
1)卷積層(Convolutional layer)
卷積層由卷積單元組成,卷積單元進(jìn)行著卷積運(yùn)算,目的是提取出不同的形色各異的特征。
2)線性整流層(ReLU layer)
線性整流層使用線性整流(Rectified Linear Units, ReLU)作為這一層神經(jīng)的激活函數(shù)(Activation function)。它可以增強(qiáng)判定函數(shù)和整個(gè)神經(jīng)網(wǎng)絡(luò)的非線性特性,而本身并不會(huì)改變卷積層。ReLU可以將神經(jīng)網(wǎng)絡(luò)的訓(xùn)練速度提升數(shù)倍,而并不會(huì)對(duì)模型的泛化準(zhǔn)確度造成產(chǎn)生顯著影響。
3)池化層(Pooling Layer)
池化(Pooling)是卷積神經(jīng)網(wǎng)絡(luò)中另一個(gè)重要的概念。Pooling是一種向下采樣過程,它將劃定的區(qū)域輸出最大值。Pooling層的作用是通過減小數(shù)據(jù)參數(shù)數(shù)量有效的控制過擬合。在平時(shí)的使用中,Convolutional層之間都會(huì)按照一定的周期來插入Pooling層。
圖 池化層下采樣過程圖
池化層通常會(huì)分別作用于每個(gè)輸入的特征并減小其大小。目前最常用形式的池化層是每隔2個(gè)元素從圖像劃分出2x2的區(qū)塊,然后對(duì)每個(gè)區(qū)塊中的4個(gè)數(shù)取最大值。這將會(huì)減少75%的數(shù)據(jù)量。過去,平均池化的使用曾經(jīng)較為廣泛,但是最近由于最大池化在實(shí)踐中的表現(xiàn)更好,平均池化已經(jīng)不太常用。
因?yàn)槌鼗瘜犹斓販p小了數(shù)據(jù)量的大小,對(duì)與數(shù)據(jù)特征的學(xué)習(xí)不利,目前的趨勢(shì)是使用較小的池化濾鏡,甚至不再使用池化層。
4)損失函數(shù)層(loss layer)
損失函數(shù)層通常是網(wǎng)絡(luò)的最后一層,用于表示預(yù)測(cè)與測(cè)試結(jié)果之間的差別。在網(wǎng)絡(luò)中有不同類型的損失函數(shù)。
2.1.3 Lenet模型和Alexnet模型
1)Lenet模型
Lenet由Yan Le Cun等人于1998年提出,在手寫數(shù)字的識(shí)別上有極高的準(zhǔn)確率。 輸入層大小為128×128,第一個(gè)卷積層窗口大小為 5×5,有 20 個(gè)過濾器共生成 20 張?zhí)卣鲌D,第二個(gè)卷積層窗口大小為 5×5,50 個(gè)過濾器共生成 50 張?zhí)卣鲌D,兩個(gè)池化層窗口大小均為 2,第一個(gè)全連接層共有 500 個(gè)神經(jīng)元,如圖所示。
圖 Lennet模型示意圖
2)Alexnet模型
Alexnet比Lenet的網(wǎng)絡(luò)結(jié)構(gòu)更深,如圖 Alexnet示意圖所示。
圖 Alexnet網(wǎng)絡(luò)模型示意圖
在Alexnet網(wǎng)絡(luò)模型中輸入的圖像規(guī)格是224*224三通道的RGB顏色圖像,特征的提取采用5*5的卷積核。在使用中Alexnet會(huì)輸入227*227三通道圖片,而不是它規(guī)格中的大小。在提取特征圖時(shí)采用公式,如下所示:
[img_size - filter_size]/stride +1 = new_feture_size
其中[ ]表示向下取整,圖片并且是RGB通道的。
2.2 深度學(xué)習(xí)框架Caffe介紹
Caffe是目前深度學(xué)習(xí)領(lǐng)域主流的一個(gè)開源庫,采用C++和CUDA實(shí)現(xiàn),支持MATLAB和Python接口,優(yōu)點(diǎn)是速度快、開放性好、易于模塊化拓展。Caffe可以廣泛應(yīng)用在多個(gè)領(lǐng)域,典型的如圖像分類、語音識(shí)別等。
Caffe框架可以從三方面來理解:1)數(shù)據(jù)存儲(chǔ):Caffe通過四維數(shù)組(blobs)來保存模型計(jì)算上的數(shù)據(jù),大型數(shù)據(jù)存儲(chǔ)在LevelDB數(shù)據(jù)庫中。2)層結(jié)構(gòu): Caffe支持完整的層類型,按照分層模型,可以在分層模型中保證了數(shù)據(jù)參數(shù)傳遞的準(zhǔn)確性; 3)網(wǎng)絡(luò)和運(yùn)行方式:一個(gè)深度神經(jīng)網(wǎng)絡(luò)起始于數(shù)據(jù)層,數(shù)據(jù)層加載數(shù)據(jù),中間每一層計(jì)算出梯度,最后一層完成分類重建,這樣一整套運(yùn)行流程使得Caffe有很好的健壯性。
2.3 字符定位與切割
在對(duì)輸入的身份證圖片進(jìn)行識(shí)別前,要進(jìn)行必要的圖片預(yù)處理。在本文的系統(tǒng)中是基于單個(gè)字符的數(shù)據(jù)集訓(xùn)練得到的模型,系統(tǒng)中輸入身份證圖片后要對(duì)文字區(qū)域進(jìn)行定位與切割,以此來獲取身份證 圖片上的每一個(gè)字符。
本文的字符定位與切割采用水平和垂直投影分割法,具體流程如下:1)首先對(duì)圖像進(jìn)行二值化處理,將圖像轉(zhuǎn)變成黑白的灰度圖;2)在字符區(qū)域圖像中呈現(xiàn)出白色,空隙區(qū)域?yàn)楹谏?,通過水平投影的方式將字符區(qū)域與空隙區(qū)域分割開,以此來確定字符所在行。3)使用垂直投影分割法,將字符從二值化圖像的每一行中分割出來,如此經(jīng)過垂直與水平的切割,可以將每個(gè)字都分割出來。
三、模型訓(xùn)練
3.1 獲取數(shù)據(jù)樣本庫
本系統(tǒng)中,要獲取的身份證上的字體為印刷體,目前有很多開源的手寫漢字?jǐn)?shù)據(jù)庫,比如中科院的CASIA手寫中文字庫]中的 HWDB1.1 脫機(jī)字庫子集。如果利用手寫漢字庫進(jìn)行本系統(tǒng)的模型訓(xùn)練,會(huì)導(dǎo)致模型精度不高,而且適用情景也有偏差。所以在本系統(tǒng)中我將用Python生成印刷體漢字圖片字庫。
在日常使用中,共有3755個(gè)常用漢字,如何獲取這些數(shù)據(jù)訓(xùn)練集成為一個(gè)要解決的問題。在Python圖像庫(PIL)是很好的工具,有很優(yōu)秀的圖像處理功能,本文利用PIL對(duì)數(shù)據(jù)訓(xùn)練集進(jìn)行處理。PIL實(shí)現(xiàn)文字轉(zhuǎn)換成圖片的過程核心代碼如下所示:
find_image_bbox = FindImageBBox() img = Image.new("RGB", (self.width, self.height), "black") draw = ImageDraw.Draw(img)
PIL將文字繪制到img上,之后把圖片保存成jpg格式。
從項(xiàng)目的font_path目錄下選擇字體格式文件,有ttf、ttc、otf等格式的文件,都通過ImageFont的truetype()方法設(shè)置選擇哪種字體文件
然后將文字繪制到圖片中,輸出文字圖片的列表:
draw.text((0, 0), char, (255, 255, 255),font=font) data = list(img.getdata())
經(jīng)過實(shí)驗(yàn),本文收集到一級(jí)常用和次常用的漢字共有6492個(gè),將每個(gè)漢字寫入腳本的數(shù)據(jù)文件中,然后使用上述PIL方法依次讀取數(shù)據(jù)文件中的漢字并生成字體圖片輸出,并將字體圖片按順序分類存放,漢字的腳本見下面的鏈接:腳本鏈接GitHub
字體文件下載地址:鏈接
這里生成的字體圖片如圖所示,最后會(huì)組合類別:
這里附上執(zhí)行獲取數(shù)據(jù)集的腳本代碼:
3.2 處理數(shù)據(jù)集圖片
本文采用Caffe框架在分割好的字符集上進(jìn)行訓(xùn)練。在訓(xùn)練網(wǎng)絡(luò)前首先要準(zhǔn)備好數(shù)據(jù)訓(xùn)練集。在Caffe中直接使用的是lmdb或者leveldb文件,所以我們需要將圖片文件轉(zhuǎn)化成db文件,讓Caffe可識(shí)別。在Caffe的工程目錄下的tools里很多工具類文件,其中的convert_imageset.cpp的作用就是將圖片數(shù)據(jù)訓(xùn)練集轉(zhuǎn)換成db文件,讓Caffe能夠識(shí)別,在對(duì)Caffe編譯之后產(chǎn)生可執(zhí)行文件,這里convert_imageset的使用格式如下:
convert_imageset [FLAGS] ROOTFOLDER/ LISTFILE DB_NAME
如上所示,convert_imageset方法需要帶四個(gè)參數(shù),分別指定圖片參數(shù)、圖片存放的路徑、圖片清單和生成的db文件存放目錄。
之后創(chuàng)建一個(gè)sh腳本文件將各個(gè)函數(shù)與輸出進(jìn)行整合,最終的目的是在相應(yīng)目錄下生成train_lmdb和test_lmdb文件,如下為在腳本文件中生成train_lmdb的示例代碼:
GLOG_logtostderr=1 $TOOLS/convert_imageset \ --resize_height=$RESIZE_HEIGHT \ --resize_width=$RESIZE_WIDTH --shuffle --gray \ $TRAIN_DATA_ROOT $DATA/train.txt $EXAMPLE/train_lmdb
最后在終端下運(yùn)行這個(gè)腳本文件,生成了訓(xùn)練用和測(cè)試用的lmdb文件,如圖所示:
圖 lmdb文件目錄
同時(shí)會(huì)生成圖片清單文件列表,本文截取部分內(nèi)容,如圖3.5所示:
這里附上數(shù)據(jù)集轉(zhuǎn)換的完整代碼:
#!/usr/bin/env sh# Create the imagenet lmdb inputs # N.B. set the path to the imagenet train + val data dirs EXAMPLE=/workspace/caffe_dataset_lower_engmkdir -p $EXAMPLErm -rf $EXAMPLE/train_lmdbrm -rf $EXAMPLE/val_lmdb DATA=/workspace/caffe_dataset_lower_eng TOOLS=$CAFFE_ROOT/build/tools TRAIN_DATA_ROOT=${DATA}/VAL_DATA_ROOT=${DATA}/# Set RESIZE=true to resize the images to 256x256. Leave as false if images have # already been resized using another tool. RESIZE=trueif $RESIZE; then RESIZE_HEIGHT=28 RESIZE_WIDTH=28else RESIZE_HEIGHT=0 RESIZE_WIDTH=0fiif [ ! -d "$TRAIN_DATA_ROOT" ]; then echo "Error: TRAIN_DATA_ROOT is not a path to a directory: $TRAIN_DATA_ROOT" echo "Set the TRAIN_DATA_ROOT variable in create_imagenet.sh to the path" \ "where the ImageNet training data is stored." exit 1fiif [ ! -d "$VAL_DATA_ROOT" ]; then echo "Error: VAL_DATA_ROOT is not a path to a directory: $VAL_DATA_ROOT" echo "Set the VAL_DATA_ROOT variable in create_imagenet.sh to the path" \ "where the ImageNet validation data is stored." exit 1fiecho "Creating train lmdb..."GLOG_logtostderr=1 $TOOLS/convert_imageset \ --resize_height=$RESIZE_HEIGHT \ --resize_width=$RESIZE_WIDTH \ --shuffle \ --gray \ $TRAIN_DATA_ROOT \ $DATA/train.txt \ $EXAMPLE/train_lmdb GLOG_logtostderr=1 $TOOLS/convert_imageset \ --resize_height=$RESIZE_HEIGHT \ --resize_width=$RESIZE_WIDTH \ --shuffle \ --gray \ $VAL_DATA_ROOT \ $DATA/test.txt \ $EXAMPLE/val_lmdbecho "Done."
3.3 模型的選擇
在進(jìn)行網(wǎng)絡(luò)訓(xùn)練前另一項(xiàng)關(guān)鍵的任務(wù)是模型的選擇與配置,因?yàn)橐WC模型的精度,要選一個(gè)適合本文身份證信息識(shí)別的網(wǎng)絡(luò)模型。
首先因?yàn)闈h字識(shí)別相當(dāng)于一個(gè)類別很多的圖片分類系統(tǒng),所以先考慮深層的網(wǎng)絡(luò)模型,優(yōu)先采用Alexnet網(wǎng)絡(luò)模型,對(duì)于漢字識(shí)別這種千分類的問題很合適,但是在具體實(shí)施時(shí)發(fā)現(xiàn)本文獲取到的數(shù)據(jù)訓(xùn)練集每張圖片都是64*64大小的一通道的灰度圖,而Alexnet的輸入規(guī)格是224*224三通道的RGB圖像,在輸入上不匹配,并且Alexnet在處理像素較高的圖片時(shí)效果好,用在本文的訓(xùn)練中顯然不合適。
其次是Lenet模型,沒有改進(jìn)的Lenet是一個(gè)淺層網(wǎng)絡(luò)模型,如今利用這個(gè)模型對(duì)手寫數(shù)字識(shí)別精度達(dá)到99%以上,效果很好,在實(shí)驗(yàn)時(shí)我利用在Caffe下的draw_net.py腳本并且用到pydot庫來繪制Lenet的網(wǎng)絡(luò)模型圖,實(shí)驗(yàn)中繪制的原始Lenet網(wǎng)絡(luò)模型圖如圖所示,圖中有兩個(gè)卷積層和兩個(gè)池化層,網(wǎng)絡(luò)層次比較淺。
圖 原始的Lenet網(wǎng)絡(luò)模型結(jié)構(gòu)圖
前期實(shí)驗(yàn)中將數(shù)據(jù)訓(xùn)練集放入未改進(jìn)的Lenet模型中進(jìn)行訓(xùn)練,訓(xùn)練效果不理想,accurary值不是穩(wěn)定上升,而是時(shí)常波動(dòng),并且出現(xiàn)了過擬合的現(xiàn)象,這里截取了一張網(wǎng)絡(luò)迭代四千次的ROC曲線圖如圖所示:
圖 迭代四千次的ROC曲線圖
圖中出現(xiàn)明顯的波動(dòng),并且出現(xiàn)accuracy=1的時(shí)候的過擬合現(xiàn)象,因?yàn)榫W(wǎng)絡(luò)層次比較淺,訓(xùn)練效果不理想。這是因?yàn)樵跐h字識(shí)別系統(tǒng)上,漢字分類數(shù)量巨大,有幾千個(gè)分類,簡(jiǎn)單的Lenet不足夠支持這么多的分類。本文嘗試使用改進(jìn)的Lenet網(wǎng)絡(luò)模型用在本文的訓(xùn)練上,所以本文在訓(xùn)練網(wǎng)絡(luò)前期實(shí)驗(yàn)的基礎(chǔ)上,在Lenet-5的基礎(chǔ)上增加隱含層,包括卷積層和池化層,最后網(wǎng)絡(luò)結(jié)構(gòu)達(dá)到了11層,修改完成后,為了查看網(wǎng)絡(luò)的結(jié)構(gòu)組成,同樣使用draw_net.py腳本對(duì)改進(jìn)的網(wǎng)絡(luò)模型進(jìn)行繪制,具體結(jié)構(gòu)如圖所示:
圖 改進(jìn)的Lenet網(wǎng)絡(luò)模型結(jié)構(gòu)圖
在圖中可以明顯看出和原始的Lenet模型相比,改進(jìn)后的模型層次明顯加深,多了一倍的卷積層和池化層。經(jīng)過前期訓(xùn)練實(shí)驗(yàn)得出:深層網(wǎng)絡(luò)能更好的支持漢字的分類。
3.4 訓(xùn)練模型
首先編輯solver.prototxt文件:
# The train/test net protocol buffer definition net: "data/lenet_train_test.prototxt"# test_iter specifies how many forward passes the test should carry out. # In the case of MNIST, we have test batch size 100 and 100 test iterations, # covering the full 10,000 testing images. test_iter: 100# Carry out testing every 500 training iterations. test_interval: 500# The base learning rate, momentum and the weight decay of the network. base_lr: 0.01momentum: 0.9weight_decay: 0.0005# The learning rate policy lr_policy: "inv"gamma: 0.0001power: 0.75# Display every 100 iterations display: 100# The maximum number of iterations max_iter: 50000# snapshot intermediate results snapshot: 5000snapshot_prefix: "data/lenet"# solver mode: CPU or GPU solver_mode: GPU
在Caffe的build文件夾下有tools文件夾,這個(gè)里面有個(gè)可執(zhí)行文件caffe,根據(jù)上文生成的Solver文件,可以在終端直接輸入命令開始訓(xùn)練網(wǎng)絡(luò):
build/tools/caffe train -solver data/deepocr/solver.prototxt --gpu=1
這里在命令行的后面添加--gpu=1,表示選擇Tesla K40上GPU進(jìn)行模型的訓(xùn)練。因?yàn)閿?shù)據(jù)量和迭代次數(shù)較大,盡管在GPU環(huán)境下訓(xùn)練并利用cuDNN加速,但訓(xùn)練模型還是花費(fèi)了大約8個(gè)小時(shí)的時(shí)間。最后的訓(xùn)練精度達(dá)到0.962,loss值較小,如圖所示,圖中達(dá)到預(yù)期的效果,訓(xùn)練成功。
圖 訓(xùn)練并測(cè)試的結(jié)果圖
為了更加詳細(xì)的了解訓(xùn)練的過程,本文使用Python的接口對(duì)訓(xùn)練過程進(jìn)行可視化,方便得出實(shí)驗(yàn)的結(jié)論,所以本文使用jupyter notebook來繪制loss值和accuracy值變化的ROC曲線圖,在網(wǎng)頁的輸入框中配置相關(guān)信息即可繪制曲線圖,本文使用SGDSolver,即隨機(jī)梯度下降算法對(duì)曲線進(jìn)行繪制:
solver = caffe.SGDSolver('data/deepocr/solver.prototxt')
然后設(shè)置迭代次數(shù)和手機(jī)數(shù)據(jù)的間隔等信息:
niter = 20000 display= 100
這里迭代次數(shù)設(shè)置為20000次是因?yàn)橛?xùn)練時(shí)發(fā)現(xiàn)迭代次數(shù)超過兩萬次后accuracy的值會(huì)趨于穩(wěn)定,浮動(dòng)很小,為了使用對(duì)訓(xùn)練過程進(jìn)行可視化,無法利用服務(wù)器GPU進(jìn)行繪制,只能在本地CPU環(huán)境下繪制,所以耗時(shí)會(huì)非常長(zhǎng)。
迭代并獲取loss和accuracy值后,初始化曲線圖,將值傳入,便可繪制出ROC曲線圖:
ax1.set_xlabel('iteration') ax1.set_ylabel('train loss') ax2.set_ylabel('test accuracy')
loss和accuracy曲線圖如圖所示:
圖 loss和accuracy曲線圖
在圖中可以看出,在迭代兩萬次后,loss值逐漸減小并 趨于穩(wěn)定,accuracy精度值逐漸穩(wěn)定達(dá)到0.96左右,
最后訓(xùn)練完模型后配置生成deploy.prototxt文件,這個(gè)文件會(huì)在模型的使用時(shí)用到。和訓(xùn)練時(shí)的網(wǎng)絡(luò)模型文件不同,它沒有數(shù)據(jù)層,并且將最后的層替換成為概率層。deploy文件通過手動(dòng)配置完成。
最后附上修改后的Lenet網(wǎng)絡(luò):鏈接
其余代碼見GitHub:https://github.com/still-wait/deepLearning_OCR
由于篇幅原因,本文其余內(nèi)容詳見 :
深度學(xué)習(xí)實(shí)踐系列之--身份證上漢字及數(shù)字識(shí)別系統(tǒng)的實(shí)現(xiàn)(下)
本人原創(chuàng),轉(zhuǎn)載請(qǐng)注明:http://www.cnblogs.com/ygh1229/p/7224940.html
http://www.cnblogs.com/ygh1229/p/7224940.html