TensorFlow — 基于CNN數(shù)字識別

環(huán)境:Ubuntu 14.04.1 LTS (GNU/Linux 3.13.0-105-generic x86_64)

1 安裝captcha庫

sudo pip install captcha

2 生成驗證碼訓(xùn)練數(shù)據(jù)

2.1 驗證碼生成器

采用 python 中生成器方式來生成我們的訓(xùn)練數(shù)據(jù),這樣的好處是,不需要提前生成大量的數(shù)據(jù)失乾,訓(xùn)練過程中生成數(shù)據(jù)些阅,并且可以無限生成數(shù)據(jù)施禾。

2.1.1 示例代碼

現(xiàn)在在?/home/ubuntu?目錄下創(chuàng)建源文件 generate_captcha.py分歇,內(nèi)容可參考:

generate_captcha.py

#!/usr/bin/python

# -*- coding: utf-8 -*

from captcha.image import ImageCaptcha

from PIL import Image

import numpy as np

import random

import string

class generateCaptcha():

? ? def __init__(self,

? ? ? ? width = 160,#驗證碼圖片的寬

? ? ? ? height = 60,#驗證碼圖片的高

? ? ? ? char_num = 4,#驗證碼字符個數(shù)

characters = string.digits +string.ascii_uppercase + string.ascii_lowercase):

#驗證碼組成,數(shù)字+大寫字母+小寫字母

? ? ? ? self.width = width

? ? ? ? self.height = height

? ? ? ? self.char_num = char_num

? ? ? ? self.characters = characters

? ? ? ? self.classes = len(characters)

? ? def gen_captcha(self,batch_size = 50):

? ? ? ? X =np.zeros([batch_size,self.height,self.width,1])

? ? ? ? img =np.zeros((self.height,self.width),dtype=np.uint8)

? ? ? ? Y =np.zeros([batch_size,self.char_num,self.classes])

? ? ? ? image = ImageCaptcha(width =self.width,height = self.height)

? ? ? ? while True:

? ? ? ? ? ? for i in range(batch_size):

? ? ? ? ? ? captcha_str =''.join(random.sample(self.characters,self.char_num))

? ? ? ? ? ? img =image.generate_image(captcha_str).convert('L')

? ? ? ? ? ? img = np.array(img.getdata())

? ? ? ? ? ? X[i] =np.reshape(img,[self.height,self.width,1])/255.0

? ? ? ? ? ? for j,ch inenumerate(captcha_str):

? ? ? ? ? ? ? ? Y[i,j,self.characters.find(ch)] = 1

? ? ? ? Y =np.reshape(Y,(batch_size,self.char_num*self.classes))

yield X,Y

? ? def decode_captcha(self,y):

? ? ? ? y =np.reshape(y,(len(y),self.char_num,self.classes))

? ? ? ? return ''.join(self.characters[x] for xin np.argmax(y,axis = 2)[0,:])

? ? def get_parameter(self):

? ? ? ? return self.width, self.height, self.char_num, self.characters, self.classes

? ? def gen_test_captcha(self):

? ? ? ? image = ImageCaptcha(width =self.width,height = self.height)

? ? ? ? captcha_str =''.join(random.sample(self.characters,self.char_num))

? ? ? ? img = image.generate_image(captcha_str)

? ? ? ? img.save(captcha_str + '.jpg')

2.1.2 然后執(zhí)行

cd /home/ubuntu;

python

import generate_captcha

g = generate_captcha.generateCaptcha()

g.gen_test_captcha()

2.1.3 執(zhí)行結(jié)果

在?/home/ubuntu?目錄下查看生成的驗證碼赶么,jpg 格式的圖片可以點(diǎn)擊查看懦胞。

如:

Gxdl
KrO7

3 驗證碼識別模型

將驗證碼識別問題轉(zhuǎn)化為分類問題替久,總共62^4 種類型,采用 4 個 one-hot 編碼分別表示 4 個字符取值躏尉。

3.1 cnn 驗證碼識別模型

3 層隱藏層蚯根、2 層全連接層,對每層都進(jìn)行dropout胀糜。input——>conv——>pool——>dropout——>conv——>pool——>dropout——>conv——>pool——>dropout——>fullyconnected layer——>dropout——>fully connected layer——>output

3.1.1 示例代碼

現(xiàn)在在?/home/ubuntu?目錄下創(chuàng)建源文件?captcha_model.py颅拦,內(nèi)容可參考:

captcha_model.py

#!/usr/bin/python

# -*- coding: utf-8 -*

import tensorflow as tf

import math

class captchaModel():

? ? def __init__(self,

? ? ? ? ? ? ? ? width = 160,

? ? ? ? ? ? ? ? height = 60,

? ? ? ? ? ? ? ? char_num = 4,

? ? ? ? ? ? ? ? classes = 62):

? ? ? ? self.width = width

? ? ? ? self.height = height

? ? ? ? self.char_num = char_num

? ? ? ? self.classes = classes

? ? def conv2d(self,x, W):

? ? ? ? return tf.nn.conv2d(x, W, strides=[1,1, 1, 1], padding='SAME')

? ? def max_pool_2x2(self,x):

? ? ? ? return tf.nn.max_pool(x, ksize=[1, 2,2, 1],

strides=[1, 2, 2,1], padding='SAME')

? ? def weight_variable(self,shape):

? ? ? ? initial = tf.truncated_normal(shape,stddev=0.1)

? ? ? ? return tf.Variable(initial)

? ? def bias_variable(self,shape):

? ? ? ? initial = tf.constant(0.1, shape=shape)

? ? ? ? return tf.Variable(initial)

? ? def create_model(self,x_images,keep_prob):

? ? ? ? #first layer

? ? ? ? w_conv1 = self.weight_variable([5, 5,1, 32])

? ? ? ? b_conv1 = self.bias_variable([32])

? ? ? ? h_conv1 = tf.nn.relu(tf.nn.bias_add(self.conv2d(x_images, w_conv1), b_conv1))

? ? ? ? h_pool1 = self.max_pool_2x2(h_conv1)

? ? ? ? h_dropout1 = tf.nn.dropout(h_pool1,keep_prob)

? ? ? ? conv_width = math.ceil(self.width/2)

? ? ? ? conv_height = math.ceil(self.height/2)

? ? ? ? #second layer

? ? ? ? w_conv2 = self.weight_variable([5, 5,32, 64])

? ? ? ? b_conv2 = self.bias_variable([64])

? ? ? ? h_conv2 = tf.nn.relu(tf.nn.bias_add(self.conv2d(h_dropout1, w_conv2), b_conv2))

? ? ? ? h_pool2 = self.max_pool_2x2(h_conv2)

? ? ? ? h_dropout2 = tf.nn.dropout(h_pool2,keep_prob)

? ? ? ? conv_width = math.ceil(conv_width/2)

? ? ? ? conv_height = math.ceil(conv_height/2)

? ? ? ? #third layer

? ? ? ? w_conv3 = self.weight_variable([5, 5,64, 64])

? ? ? ? b_conv3 = self.bias_variable([64])

? ? ? ? h_conv3 = tf.nn.relu(tf.nn.bias_add(self.conv2d(h_dropout2, w_conv3), b_conv3))

? ? ? ? h_pool3 = self.max_pool_2x2(h_conv3)

? ? ? ? h_dropout3 =tf.nn.dropout(h_pool3,keep_prob)

? ? ? ? conv_width = math.ceil(conv_width/2)

? ? ? ? conv_height = math.ceil(conv_height/2)

? ? ? ? #first fully layer

? ? ? ? conv_width = int(conv_width)

? ? ? ? conv_height = int(conv_height)

? ? ? ? w_fc1 = self.weight_variable([64*conv_width*conv_height,1024])

? ? ? ? b_fc1 = self.bias_variable([1024])

? ? ? ? h_dropout3_flat = tf.reshape(h_dropout3,[-1,64*conv_width*conv_height])

? ? ? ? h_fc1 = tf.nn.relu(tf.nn.bias_add(tf.matmul(h_dropout3_flat, w_fc1), b_fc1))

? ? ? ? h_fc1_drop = tf.nn.dropout(h_fc1,keep_prob)

? ? ? ? #second fully layer

? ? ? ? w_fc2 = self.weight_variable([1024,self.char_num*self.classes])

? ? ? ? b_fc2 = self.bias_variable([self.char_num*self.classes])

? ? ? ? y_conv = tf.add(tf.matmul(h_fc1_drop,w_fc2), b_fc2)

? ? ? ? return y_conv

3.2 訓(xùn)練cnn 驗證碼識別模型

每批次采用 64 個訓(xùn)練樣本,每 100 次循環(huán)采用 100 個測試樣本檢查識別準(zhǔn)確度教藻,當(dāng)準(zhǔn)確度大于 99% 時距帅,訓(xùn)練結(jié)束,采用 GPU 需要 5-6個小時左右括堤,CPU 大概需要 20 個小時左右碌秸。

注:作為實(shí)驗,你可以通過調(diào)整train_captcha.py文件中if acc > 0.99:代碼行的準(zhǔn)確度節(jié)省訓(xùn)練時間(比如將0.99 為 0.01)痊臭;同時哮肚,我們已經(jīng)通過長時間的訓(xùn)練得到了一個訓(xùn)練集,可以通過如下命令將訓(xùn)練集下載到本地广匙。

wget?http://tensorflow-1253902462.cosgz.myqcloud.com/captcha/capcha_model.zip

unzip capcha_model.zip

3.2.1 示例代碼

現(xiàn)在在?/home/ubuntu?目錄下創(chuàng)建源文件?train_captcha.py,內(nèi)容可參考:

train_captcha.py

#!/usr/bin/python

import tensorflow as tf

import numpy as np

import string

import generate_captcha

import captcha_model

if __name__ == '__main__':

? ? captcha =generate_captcha.generateCaptcha()

? ? width,height,char_num,characters,classes = captcha.get_parameter()

? ? x = tf.placeholder(tf.float32, [None,height,width,1])

? ? y_ = tf.placeholder(tf.float32, [None,char_num*classes])

? ? keep_prob = tf.placeholder(tf.float32)

? ? model = captcha_model.captchaModel(width,height,char_num,classes)

? ? y_conv = model.create_model(x,keep_prob)

? ? cross_entropy = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=y_,logits=y_conv))

? ? train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)

? ? predict = tf.reshape(y_conv, [-1,char_num,classes])

? ? real = tf.reshape(y_,[-1,char_num,classes])

? ? correct_prediction = tf.equal(tf.argmax(predict,2), tf.argmax(real,2))

? ? correct_prediction = tf.cast(correct_prediction, tf.float32)

? ? accuracy = tf.reduce_mean(correct_prediction)

? ? saver = tf.train.Saver()

? ? with tf.Session() as sess:

? ? ? ? sess.run(tf.global_variables_initializer())

? ? ? ? step = 0

? ? ? ? while True:

? ? ? ? ? ? batch_x,batch_y = next(captcha.gen_captcha(64))

? ? ? ? ? ? _,loss = sess.run([train_step,cross_entropy],feed_dict ={x: batch_x, y_: batch_y,keep_prob: 0.75})

? ? ? ? ? ? print ('step:%d,loss:%f' %(step,loss))

? ? ? ? ? ? if step % 100 == 0:

? ? ? ? ? ? ? ? batch_x_test,batch_y_test = next(captcha.gen_captcha(100))

? ? ? ? ? ? ? ? acc = sess.run(accuracy,feed_dict={x: batch_x_test, y_: batch_y_test, keep_prob: 1.})

? ? ? ? ? ? ? ? print('###############################################step:%d,accuracy:%f' %(step,acc))

if acc > 0.99:

saver.save(sess,"capcha_model.ckpt")

break

step += 1

3.2.2 然后執(zhí)行

cd /home/ubuntu;

python train_captcha.py

3.2.3執(zhí)行結(jié)果

step:75173,loss:0.010555

step:75174,loss:0.009410

step:75175,loss:0.009978

step:75176,loss:0.008089

step:75177,loss:0.009949

step:75178,loss:0.010126

step:75179,loss:0.009584

step:75180,loss:0.012272

step:75181,loss:0.010157

step:75182,loss:0.009529

step:75183,loss:0.007636

step:75184,loss:0.009058

step:75185,loss:0.010061

step:75186,loss:0.009941

step:75187,loss:0.009339

step:75188,loss:0.009685

step:75189,loss:0.009879

step:75190,loss:0.007799

step:75191,loss:0.010866

step:75192,loss:0.009838

step:75193,loss:0.010931

step:75194,loss:0.012859

step:75195,loss:0.008747

step:75196,loss:0.009147

step:75197,loss:0.009351

step:75198,loss:0.009746

step:75199,loss:0.010014

step:75200,loss:0.009024

###############################################step:75200,accuracy:0.992500

3.3 測試

cnn 驗證碼識別模型

3.3.1示例代碼

現(xiàn)在在?/home/ubuntu?目錄下創(chuàng)建源文件?predict_captcha.py恼策,內(nèi)容可參考:

predict_captcha.py

#!/usr/bin/python

from PIL import Image, ImageFilter

import tensorflow as tf

import numpy as np

import string

import sys

import generate_captcha

import captcha_model

if __name__ == '__main__':

? ? captcha = generate_captcha.generateCaptcha()

? ? width, height, char_num, characters, classes = captcha.get_parameter()

? ? gray_image = Image.open(sys.argv[1]).convert('L')

? ? img = np.array(gray_image.getdata())

? ? test_x = np.reshape(img,[height,width,1])/255.0

? ? x = tf.placeholder(tf.float32, [None,height,width,1])

? ? keep_prob = tf.placeholder(tf.float32)

? ? model = captcha_model.captchaModel(width,height,char_num,classes)

? ? y_conv = model.create_model(x,keep_prob)

? ? predict = tf.argmax(tf.reshape(y_conv,[-1,char_num, classes]),2)

? ? init_op = tf.global_variables_initializer()

? ? saver = tf.train.Saver()

? ? gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.95)

? ? withtf.Session(config=tf.ConfigProto(log_device_placement=False,gpu_options=gpu_options))as sess:

? ? ? ? sess.run(init_op)

? ? ? ? saver.restore(sess,"capcha_model.ckpt")

? ? ? ? pre_list = sess.run(predict,feed_dict={x: [test_x],keep_prob: 1})

? ? ? ? for i in pre_list:

? ? ? ? ? ? s = ''

? ? ? ? ? ? for j in i:

? ? ? ? ? ? ? ? s += characters[j]

? ? ? ? ? ? ? ? print s

3.3.2 然后執(zhí)行

cd /home/ubuntu;

python predict_captcha.py Gxdl.jpg

3.3.3 執(zhí)行結(jié)果:

Gxdl

注:因時間的限制鸦致,我們可能調(diào)整了準(zhǔn)確度導(dǎo)致執(zhí)行結(jié)果不符合預(yù)期潮剪,這屬于正常情況。

在訓(xùn)練時間足夠長的情況下分唾,可以采用驗證碼生成器生成測試數(shù)據(jù)抗碰,cnn訓(xùn)練出來的驗證碼識別模型還是很強(qiáng)大的,大小寫的 z 都可以區(qū)分绽乔,甚至有時候人都無法區(qū)分弧蝇,該模型也可以正確的識別。

4 完成

以上折砸。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末看疗,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子睦授,更是在濱河造成了極大的恐慌两芳,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件去枷,死亡現(xiàn)場離奇詭異怖辆,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)删顶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門竖螃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人逗余,你說我怎么就攤上這事特咆。” “怎么了猎荠?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵坚弱,是天一觀的道長。 經(jīng)常有香客問我关摇,道長荒叶,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任输虱,我火速辦了婚禮些楣,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘宪睹。我一直安慰自己愁茁,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布亭病。 她就那樣靜靜地躺著鹅很,像睡著了一般。 火紅的嫁衣襯著肌膚如雪罪帖。 梳的紋絲不亂的頭發(fā)上促煮,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天邮屁,我揣著相機(jī)與錄音,去河邊找鬼菠齿。 笑死佑吝,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的绳匀。 我是一名探鬼主播芋忿,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼疾棵!你這毒婦竟也來了戈钢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤陋桂,失蹤者是張志新(化名)和其女友劉穎逆趣,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體嗜历,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宣渗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了梨州。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片痕囱。...
    茶點(diǎn)故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖暴匠,靈堂內(nèi)的尸體忽然破棺而出鞍恢,到底是詐尸還是另有隱情,我是刑警寧澤每窖,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布帮掉,位于F島的核電站,受9級特大地震影響窒典,放射性物質(zhì)發(fā)生泄漏蟆炊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一瀑志、第九天 我趴在偏房一處隱蔽的房頂上張望涩搓。 院中可真熱鬧,春花似錦劈猪、人聲如沸昧甘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽充边。三九已至,卻和暖如春常侦,著一層夾襖步出監(jiān)牢的瞬間痛黎,已是汗流浹背予弧。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工刮吧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留湖饱,地道東北人。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓杀捻,卻偏偏與公主長得像井厌,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子致讥,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評論 2 348

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