卷積神經網路(CNN)學習演算法之----基於LeNet網路的中文驗證碼識別
由於公司需要進行了中文驗證碼的圖片識別開發,最近一段時間剛忙完上線,好不容易閒下來就繼上篇《基於Windows10 x64+visual Studio2013+Python2.7.12環境下的Caffe配置學習 》文章,記錄下利用caffe進行中文驗證碼圖片識別的開發過程。由於這裡主要介紹開發和實現過程,CNN理論性的東西這裡不作為介紹的重點,遇到相關的概念和術語請自行研究。目前從我們訓練出來的模型來看,單字識別率接近96%,所以一個四字驗證碼的準確率大概80%,效果還不錯,完全能滿足使用,如果每張圖片的樣本繼續加大應該能取得更高的準確率,當然隨著樣本的加大,訓練時間也隨之增大,對硬體裝置要求也越高,還有就是優化LeNet網路結構,目前這裡只使用了三層卷積。
(一)開發準備
(1)開發環境
軟體環境:visual Studio2013+Python2.7.12+caffe
硬體環境:Intel Core i7-4790+GTX1080+RAM32G
(2)訓練圖片
可以用於驗證碼的中文常用字大概3666個,每個字的訓練大於等於50個,所以總共訓練樣本大概20萬,其中80%用於訓練集,20%用於測試集。樣本收集是一個非常麻煩和耗時的過程,需要手工標註結果,我這裡利用手工打碼平臺收集,最便宜一個驗證碼要4分錢,可以大概算一下,光為了收集這麼多樣本就將近花費1萬RMB,還有配置一個GTX1080的顯示卡大概6千RMB,這點成本對一個公司還好,如果是對於個人投入還是不少,所以對於實驗室的學生黨玩深度學習成本還是蠻高的!
訓練集:26萬樣本圖片
測試集:13萬樣本圖片
(二)圖片樣本處理
目前驗證碼種類無極繁多,有數字、字母、中文、圖片等等,不過本文主要介紹中文驗證碼的識別。中文驗證碼設計干擾的方式主要圍繞:
(1)背景色干擾
(2)文字傾斜扭曲
(3)干擾線
(4)中文拼音並存(百度九宮格)
(5)疊字
針對不同型別的驗證碼需要分別處理,這些處理過程統稱圖片預處理,目前並沒有統一的預處理方式,需要針對不同的驗證碼做特殊處理,但是大體過程無外乎:灰度化、二值化、去幹擾線、分割切圖、標準化,這些過程用python實現都非常的簡單,這裡就不詳細介紹了,直接上程式碼,需要import cv2:
1 class PreProcess(object): 2 """description of class""" 3 def ConvertToGray(self,Image,filename): 4 GrayImage=cv2.cvtColor(Image,cv2.COLOR_BGR2GRAY) 5 return GrayImage 6 7 def ConvertTo1Bpp(self,GrayImage,filename): 8 Bpp=cv2.threshold(GrayImage,127,255,cv2.THRESH_BINARY) 9 cv2.imwrite('D://'+'1.jpg',Bpp[1]) 10 return Bpp 11 12 def InterferLine(self,Bpp,filename): 13 for i in range(0,76): 14 for j in range(0,Bpp.shape[0]): 15 Bpp[j][i]=255 16 for i in range(161,Bpp.shape[1]): 17 for j in range(0,Bpp.shape[0]): 18 Bpp[j][i]=255 19 m=1 20 n=1 21 for i in range(76,161): 22 while(m<Bpp.shape[0]-1): 23 if Bpp[m][i]==0: 24 if Bpp[m+1][i]==0: 25 n=m+1 26 elif m>0 and Bpp[m-1][i]==0: 27 n=m 28 m=n-1 29 else: 30 n=m+1 31 break 32 elif m!=Bpp.shape[0]: 33 l=0 34 k=0 35 ll=m 36 kk=m 37 while(ll>0): 38 if Bpp[ll][i]==0: 39 ll=11-1 40 l=l+1 41 else: 42 break 43 while(kk>0): 44 if Bpp[kk][i]==0: 45 kk=kk-1 46 k=k+1 47 else: 48 break 49 if (l<=k and l!=0) or (k==0 and l!=0): 50 m=m-1 51 else: 52 m=m+1 53 else: 54 break 55 #endif 56 #endwhile 57 if m>0 and Bpp[m-1][i]==0 and Bpp[n-1][i]==0: 58 continue 59 else: 60 Bpp[m][i]=255 61 Bpp[n][i]=255 62 #endif 63 #endfor 64 return Bpp 65 66 def CutImage(self,Bpp,filename): 67 b1=np.zeros((Bpp.shape[0],20)) 68 for i in range(78,98): 69 for j in range(0,Bpp.shape[0]): 70 b1[j][i-78]=Bpp[j][i] 71 cv2.imwrite(outpath+filename.decode('gbk')[0].encode('gbk')+'_'+'%d' %(time.time()*1000)+str(random.randint(1000,9999))+'.png',b1) 72 73 b2=np.zeros((Bpp.shape[0],19)) 74 for i in range(99,118): 75 for j in range(0,Bpp.shape[0]): 76 b2[j][i-99]=Bpp[j][i] 77 cv2.imwrite(outpath+filename.decode('gbk')[1].encode('gbk')+'_'+'%d' %(time.time()*1000)+str(random.randint(1000,9999))+'.png',b2) 78 79 b3=np.zeros((Bpp.shape[0],19)) 80 for i in range(119,138): 81 for j in range(0,Bpp.shape[0]): 82 b3[j][i-119]=Bpp[j][i] 83 cv2.imwrite(outpath+filename.decode('gbk')[2].encode('gbk')+'_'+'%d' %(time.time()*1000)+str(random.randint(1000,9999))+'.png',b3) 84 85 b4=np.zeros((Bpp.shape[0],19)) 86 for i in range(139,158): 87 for j in range(0,Bpp.shape[0]): 88 b4[j][i-139]=Bpp[j][i] 89 cv2.imwrite(outpath+filename.decode('gbk')[3].encode('gbk')+'_'+'%d' %(time.time()*1000)+str(random.randint(1000,9999))+'.png',b4) 90 #return (b1,b2,b3,b4)預處理
呼叫預處理方法的程式碼:
1 import cv2 2 PP=PreProcess() 3 for root,dirs,files in os.walk(inpath): 4 for filename in files: 5 Img=cv2.imread(root+'/'+filename)#太坑,此處inpath不能包含中文路徑 6 GrayImage=PP.ConvertToGray(Img,filename) 7 Bpp=PP.ConvertTo1Bpp(GrayImage,filename) 8 Bpp_new=PP.InterferLine(Bpp,filename) 9 b=PP.CutImage(Bpp_new,filename)批量處理圖片
處理前的圖片:
預處理後的圖片:
(三)caffe模型配置
模型配置階段,需要進行caffe所需資料格式準備、訓練集和測試集準備、Lenet網路結構配置等三步
(1)訓練集和測試集準備
預處理階段將驗證碼切割成四個圖片後,需要將每個圖片進行標準化為32*32畫素大小的圖片,不然caffe模型無法訓練。標準化完成以後就需要把每個字的圖片分拆到訓練集和測試集中去,這裡程式碼就不貼了,根據個人喜好我設定一個字的訓練集佔80%,測試集佔20%,然後把所有字用一個字典進行對映為數字編號,方便模型給出結果時我們能找到對應的漢字。
(2)caffe格式資料
為了生成caffe所需資料格式需要用到convert_imageset專案,在第一篇配置中已經編譯好了這個專案,可以直接拿過來用,python呼叫程式碼如下:
path=os.getcwd()#儲存當前路徑 os.chdir("./caffe-master/caffe-master/Build/x64/Debug")#改變路徑到caffe.exe資料夾 os.system('SET GLOG_logtostderr=1') #生成訓練集 os.system('convert_imageset.exe --shuffle ./caffe-master/caffe-master/windows/CaptchaTest/dpsample/data/train ./caffe-master/caffe-master/windows/CaptchaTest/dpsample/data/train.txt ./caffe-master/caffe-master/windows/CaptchaTest/dpsample/data/trainldb 0') #生成測試集 os.system('convert_imageset.exe --shuffle ./caffe-master/caffe-master/windows/CaptchaTest/dpsample/data/val ./caffe-master/caffe-master/windows/CaptchaTest/dpsample/data/val.txt ./caffe-master/caffe-master/windows/CaptchaTest/dpsample/data/testldb 0')呼叫convert_imageset生成caffe資料格式
生成成功過後可以分別在訓練集和測試集資料夾看到如下兩個檔案:data.mdb和lock.mdb,都是caffe標準mdb格式的資料
(3)Lenet網路模型
目前Lenet模型已經非常成熟,最常用的是Lenet-5(5層),對於層數不需要太多的CNN網路用它完全足夠了,當然現在更強大的模型還有:Alexnet、googlenet,VGG,resnet。resnet是今年剛出的,據benchmark的測試,對於人臉識別它可以完爆其他網路,層數更是可以多達200,有興趣的可以看看:GitHub測評專案。對於Lenet有一個視覺化的配置網站:
模型總共包含三個卷積層,兩個池化層,模型中最重要的幾個設定引數:num_output、kernel_size、stride需要分別配置,模型的好壞除了層數結構的設計外,就看這幾個引數是否配置的合理,具體的配置這裡不詳細講解,相關講解文章非常的多,也有很多優秀的論文可以借鑑,模型的結構程式碼如下:
name: "LeNet" layer { name: "mnist" type: "Data" top: "data" top: "label" include { phase: TRAIN } transform_param { scale: 0.00390625 } data_param { source: "E:/work/meb/Deeplearning/caffe-master/caffe-master/windows/CaptchaTest/dpsample/data/trainldb" batch_size: 64 backend: LMDB } } layer { name: "mnist" type: "Data" top: "data" top: "label" include { phase: TEST } transform_param { scale: 0.00390625 } data_param { source: "E:/work/meb/Deeplearning/caffe-master/caffe-master/windows/CaptchaTest/dpsample/data/testldb" batch_size: 100 backend: LMDB } } layer { name: "conv1" type: "Convolution" bottom: "data" top: "conv1" param { lr_mult: 1 } param { lr_mult: 2 } convolution_param { num_output: 64 kernel_size: 7 stride: 1 weight_filler { type: "xavier" } bias_filler { type: "constant" } } } layer { name: "relu1" type: "ReLU" bottom: "conv1" top: "conv1" } layer { name: "pool1" type: "Pooling" bottom: "conv1" top: "pool1" pooling_param { pool: MAX kernel_size: 2 stride: 2 } } layer { name: "conv2" type: "Convolution" bottom: "pool1" top: "conv2" param { lr_mult: 1 } param { lr_mult: 2 } convolution_param { num_output: 256 pad:1 kernel_size: 6 stride: 1 weight_filler { type: "xavier" } bias_filler { type: "constant" } } } layer { name: "relu2" type: "ReLU" bottom: "conv2" top: "conv2" } layer { name: "conv3" type: "Convolution" bottom: "conv2" top: "conv3" param { lr_mult: 1 } param { lr_mult: 2 } convolution_param { num_output: 1024 pad:1 kernel_size: 5 stride: 1 weight_filler { type: "xavier" } bias_filler { type: "constant" } } } layer { name: "relu3" type: "ReLU" bottom: "conv3" top: "conv3" } layer { name: "pool2" type: "Pooling" bottom: "conv3" top: "pool2" pooling_param { pool: MAX kernel_size: 2 stride: 2 } } layer { name: "ip1" type: "InnerProduct" bottom: "pool2" top: "ip1" param { lr_mult: 1 } param { lr_mult: 2 } inner_product_param { num_output: 3666 weight_filler { type: "xavier" } bias_filler { type: "constant" } } } layer { name: "relu4" type: "ReLU" bottom: "ip1" top: "ip1" } layer { name: "ip2" type: "InnerProduct" bottom: "ip1" top: "ip2" param { lr_mult: 1 } param { lr_mult: 2 } inner_product_param { num_output: 3666 weight_filler { type: "xavier" } bias_filler { type: "constant" } } } layer { name: "accuracy" type: "Accuracy" bottom: "ip2" bottom: "label" top: "accuracy" include { phase: TEST } } layer { name: "loss" type: "SoftmaxWithLoss" bottom: "ip2" bottom: "label" top: "loss" }View Code
(四)訓練模型
到目前為止,準備工作都做完了,現在就可以利用python import caffe進行模型訓練了,模型訓練速度快慢主要看你GPU的配置如何,我開始用的GTX650,訓練5000輪下來,就得消耗半天時間,實在無法忍受這個速度,就向公司申請買了一個GTX1080,那速度簡直沒法比,訓練5000輪半個小時就能完成。呼叫模型的程式碼如下:
cmd='caffe.exe train -solver=./caffe-master/caffe-master/windows/CaptchaTest/dpsample/solver/lenet_solver.prototxt'#訓練語句 os.system(cmd) os.chdir(path)
模型訓練中主要的輸出引數有:loss,accuracy,如果你看到loss一直在收斂,每500輪輸出一次的準確率也在提高,那麼說明你的模型設計沒什麼問題,不然就得重新設計。訓練完成後就能得到如下模型:
(五)使用模型
模型訓練完成後,我們就可以簡單的用測試圖片進行測試,測試程式碼如下:
#呼叫模型 deploy='.\dpsample\solver\lenet_deploy.prototxt' #deploy檔案 caffe_model='.\dpsample\iterate_iter_5000.caffemodel' #訓練好的 caffemodel imgtest='./dpsample/data/val/685_363.png' #隨機找的一張待測圖片 net = caffe.Net(deploy, caffe_model, caffe.TEST) transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape}) #設定圖片的shape格式(1,3,32,32) transformer.set_transpose('data', (2,0,1)) #改變維度的順序,由原始圖片(28,28,3)變為(3,28,28) #transformer.set_mean('data', np.load(mean_file).mean(1).mean(1)) #減去均值,前面訓練模型時沒有減均值,這兒就不用 #transformer.set_raw_scale('data', 1) # 縮放到【0,1】之間 已經在網路裡設定scale,這裡可以不用 transformer.set_channel_swap('data', (2,1,0)) #交換通道,將圖片由RGB變為BGR im=caffe.io.load_image(imgtest) #載入圖片 net.blobs['data'].data[...] = transformer.preprocess('data',im) #執行上面設定的圖片預處理操作,並將圖片載入到blob中 out = net.forward() prob= net.blobs['prob'].data[0].flatten() #取出最後一層(Softmax)屬於某個類別的概率值,並列印 print prob order=prob.argsort()[-1] print(order)
最後輸出的order就是模型預測出最有可能文字的序號,再到文字和序號對應的字典中去檢視就知道這裡的識別對不對了!
#寫在最後# 我是一個忠實的VS使用者,所有程式碼都在VS編輯器實現的,它要能用python需要安裝一個PTVS外掛,在這裡編輯python程式碼需要非常注意中文編碼的處理,否則你會吃大苦頭,不過相信我,其他編輯器能搞定的VS也一定沒問題,只是你要有足夠的耐心,遇到問題的時候多思考多搜搜問題的本質所在。
原創性宣告:
作品及其衍生品不得未經許可而用於商業用途。個人使用無需許可,但必須在引用部分(程式碼,基本思想或實現方案等)標示出原作者資訊,釋出時需附帶本宣告。(對於GPLv3下發布的作品,引用本人作品不需要許可,也不需要標示出引用部分或附帶宣告。)
關於“原創”的說明:文章釋出前我會進行初步的相關搜尋,如未發現有別人發表過類似內容的作品我才會發表。但是因為可能有遺漏,所以不能保證我的部落格內容一定為“首創”,但一定可以保證“原創”。
歡迎轉載,並請註明以下內容:
轉載自部落格園marso的Blog, 部落格地址為http://%部落格URL%,採用 知識共享 署名-非商業性使用-相同方式共享 3.0 中國大陸 許可協議 進行許可。其中“%部落格URL%”替換為被轉載部落格的實際URL。
相關推薦
卷積神經網路(CNN)學習演算法之----基於LeNet網路的中文驗證碼識別
由於公司需要進行了中文驗證碼的圖片識別開發,最近一段時間剛忙完上線,好不容易閒下來就繼上篇《基於Windows10 x64+visual Studio2013+Python2.7.12環境下的Caffe配置學習 》文章,記錄下利用caffe進行中文驗證碼圖片識別的開發過程。由於這裡主要介紹開發和實現過程,
卷積神經網路(cnn)學習筆記1:入門
卷積神經網路 卷積神經網路(Convolutional Neural Network,CNN)是深度學習技術中極具代表的網路結構之一,在影象處理領域取得了很大的成功,在國際標準的ImageNet資料集上,許多成功的模型都是基於CNN 的。CNN相較於傳統的影象
卷積神經網絡(CNN)
進行 參數 一個 目的 下一步 方便 logs 很多 好的 最近可能會用到CNN,今天回顧一下,並找到了一些大神的精華帖,順便做個總結。 CNN是時下非常火的一種深度學習算法,它是一種前饋神經網絡,即神經元只與前後層有聯系,在同一層的神經元無聯系。筆者用下面這張圖用來說明卷
大話卷積神經網絡(CNN)
相關性 圖形 圖像識別 src 應用 data str one 便是 這幾年深度學習快速發展,在圖像識別、語音識別、物體識別等各種場景上取得了巨大的成功,例如AlphaGo擊敗世界圍棋冠軍,iPhone X內置了人臉識別解鎖功能等等,很多AI產品在
卷積神經網絡(CNN)的訓練過程
假設 特征向量 left 傳遞 方法 輸出 1.3 組成 初始化 卷積神經網絡的訓練過程 卷積神經網絡的訓練過程分為兩個階段。第一個階段是數據由低層次向高層次傳播的階段,即前向傳播階段。另外一個階段是,當前向傳播得出的結果與預期不相符時,將誤差從高層次向底層次進行傳播訓練的
卷積神經網絡(CNN)在語音識別中的應用
現狀 each htm 介紹 產品 都在 color pcnn tmp 卷積神經網絡(CNN)在語音識別中的應用作者:侯藝馨前言總結目前語音識別的發展現狀,dnn、rnn/lstm和cnn算是語音識別中幾個比較主流的方向。2012年,微軟鄧力和俞棟老師將前饋神經網絡FFDN
吳恩達深度學習筆記(deeplearning.ai)之卷積神經網路(CNN)(上)
1. Padding 在卷積操作中,過濾器(又稱核)的大小通常為奇數,如3x3,5x5。這樣的好處有兩點: 在特徵圖(二維卷積)中就會存在一箇中心畫素點。有一箇中心畫素點會十分方便,便於指出過濾器的位置。 在沒有padding的情況下,經過卷積操作,輸出的資
深入學習卷積神經網路(CNN)的原理知識
網上關於卷積神經網路的相關知識以及數不勝數,所以本文在學習了前人的部落格和知乎,在別人部落格的基礎上整理的知識點,便於自己理解,以後複習也可以常看看,但是如果侵犯到哪位大神的權利,請聯絡小編,謝謝。好了下面言歸正傳: 在深度學習領域中,已經經過驗證的成熟演算法,目前主要有深度卷積網路(DNN)和遞迴網
機器學習13:卷積神經網路(CNN)
一、Why CNN for Image? 1、對於一幅影象來說,用DNN全連線的話,引數會很多,而影象實際上是有很多冗餘的,有些地方的特徵可能不需要。而CNN其實是拿掉了DNN的一些引數。 2、識別工作中,有時候並不需要看整張圖,而只需要看部分位置如鳥嘴。不管鳥嘴出現在影象的哪個位置,
tensorflow 學習專欄(六):使用卷積神經網路(CNN)在mnist資料集上實現分類
卷積神經網路(Convolutional Neural Network, CNN)是一種前饋神經網路,它的人工神經元可以響應一部分覆蓋範圍內的周圍單元,對於大型影象處理有出色表現。卷積神經網路CNN的結構一般包含這幾個層:輸入層:用於資料的輸入卷積層:使用卷積核進行特徵提取和
深度學習基礎(二)—— 從多層感知機(MLP)到卷積神經網路(CNN)
經典的多層感知機(Multi-Layer Perceptron)形式上是全連線(fully-connected)的鄰接網路(adjacent network)。 That is, every neuron in the network is connec
乾貨 | 深度學習之卷積神經網路(CNN)的前向傳播演算法詳解
微信公眾號 關鍵字全網搜尋最新排名 【機器學習演算法】:排名第一 【機器學習】:排名第一 【Python】:排名第三 【演算法】:排名第四 前言 在(乾貨 | 深度學習之卷積神經網路(CNN)的模型結構)中,我們對CNN的模型結構做了總結,這裡我們就在CNN的模型基礎上,看看CNN的前向傳播演算法是什麼樣
【深度學習】卷積神經網路(CNN)
卷積神經網路(Convolutional Neural NetWork,CNN): 自然語言處理、醫藥發現、災難氣候發現、人工智慧程式。 輸入層: 整個神經網路的輸入 卷積層: 卷積神經網路中最重要的部分,卷積層中每一個節點的輸入只是上一層神經網路的一小塊,一般為3
卷積神經網路(CNN)在語音識別中的應用
卷積神經網路(CNN)在語音識別中的應用 作者:侯藝馨 前言 總結目前語音識別的發展現狀,dnn、rnn/lstm和cnn算是語音識別中幾個比較主流的方向。2012年,微軟鄧力和俞棟老師將前饋神經網路FFDNN(Feed Forward Deep Neural Network)引入到聲學模
卷積神經網路(CNN)_相關知識
斯坦福公開課 CS231n Convolutional Neural Networks for Visual Recognition : http://cs231n.stanford.edu/syllabus.html 網路引數初始化:https://www.cnblogs.com/yinheyi
卷積神經網路(CNN)一之概念原理
什麼是卷積神經網路呢?這個的確是比較難搞懂的概念,特別是一聽到神經網路,大家腦海中第一個就會想到複雜的生物學,讓人不寒而慄,那麼複雜啊.卷積神經網路是做什麼用的呢?它到底是一個什麼東東呢? 卷積神經網路的靈感源一種生物程序,其中神經元之間的聯結模式和動物視覺皮層組織非常相似。所以發明者把它叫做卷積神經網
【6年人工智慧開發】簡述卷積神經網路(CNN)
在百度做了6年人工智慧方面的程式設計開發,也有很多這方面的經驗吧,從古至今,機器人一直承載著人類巨大的夢想。隨著各類感測器、語音互動、機器識別、SLAM等技術的蓬勃發展,機器人開始從科幻作品中走出
卷積神經網路(CNN)基礎
CNN的基本結構 原文地址:https://www.jianshu.com/p/da0c4cc76a06 CNN分為幾層 CNN一共有卷積層(CONV)、ReLU層(ReLU)、池化層(Pooling)、全連線層(FC(Full Connection))下面是各個層的
卷積神經網路(CNN)之一維卷積、二維卷積、三維卷積詳解
由於計算機視覺的大紅大紫,二維卷積的用處範圍最廣。因此本文首先介紹二維卷積,之後再介紹一維卷積與三維卷積的具體流程,並描述其各自的具體應用。 1. 二維卷積 圖中的輸入的資料維度為14×1414×14,過濾器大小為5×55×5,二者做卷積,輸出的資料維度為10×1
簡單介紹卷積神經網路(CNN)
前言: 原創: Python開發者 內容取自公眾號——Python開發者,有興趣的可以關注一下 什麼是卷積神經網路,它為何重要? 卷積神經網路(也稱作 ConvNets 或 CNN)是神經網路的一種,它在影象識別和分類等領域已被證明非常有效。 卷積神經網路除了為機器人