基于Keras框架的简易验证码识别网络的构建

Keras框架

Keras框架是一款操作十分简单,高度封装的深度学习框架。在学习完Coursera上AndrewNg的Machine learning课程后,打算用这款框架来实现个验证码识别的小项目。在这里其实更推荐先手动搭建一遍神经网络,比如双隐藏层的神经网络,之后再使用框架来实现自己项目。

当然,Keras框架的高度封装性有两面性啦。对于想要快速实现一个想法,Keras是不二之选。这里给出Keras的中文文档,方便大家学习。

生成训练集、测试集

神经网络的训练需要大量的数据,这里通过pillow库来自动生成一定数量的单验证码图片。

from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw
from PIL import ImageFilter
import string
import random
def gen_fake_code(miter,char):
    t_size=(18,27)
    #字体文件路径
    font_path="calibri.ttf"
    font=ImageFont.truetype(font_path,20)
    txt = Image.new('L', t_size, color='black')
    #(3,3)is to change the position of the char in the pic
    ImageDraw.Draw(txt).text((3,3), char, fill='white', font=font)
    # center不指定,默认为中心点
    w = txt.rotate(random.uniform(-20, 20), Image.BILINEAR)
    img_ = w.point(lambda i: i < 10, mode='1')
    #img_.show()
    img_.save('collection/'+str(miter)+'_'+char+'.png')
    #图片保存路径

def gen_set():
    #生成数
    iter_num=30000
    #生成26字母和10个数字
    char=[chr(i) for i in range(97,123)]
    for i in range(10):
        char.append(str(i))
    for i in range(iter_num):
        for k in char:
            gen_fake_code(i,k)

图片处理和数据载入

将rgb图片的三个像素值转为一个像素值。编写数据载入函数方便在训练前载入数据。

from PIL import Image
import numpy as np
def get_pix(k):
    a=(1,2,3)
    #转rgb三色为单色
    if type(k)==type(a):
        r=k[0]*0.333+k[1]*0.333+k[2]*0.333
    else:
        r=k
    return r
def get_image_array(filename):
    im=Image.open(filename)
    #获取图片宽,高
    width,height=im.getbbox()[2],im.getbbox()[3]
    #初始化图片像素值矩阵
    image_array=[[0 for col in range(width)] for row in range(height)]
    im=im.resize((width,height),Image.NEAREST)
    for i in range(height):
        for j in range(width):
            #填充像素矩阵
            image_array[i][j]=get_pix(im.getpixel((j,i)))
    image=[image_array[i][j] for i in range(height) for j in range(width)]
    return image
def load_image(num):
    char=[chr(i) for i in range(97,123)]
    for i in range(10):
        char.append(str(i))
    x_data,y_data,x_test,y_test=list(),list(),list(),list()
    #所有数据的90%为训练集
    for i in range(int(0.9*num)):
        for j in range(36):
            filename='collection/'+str(i)+'_'+char[j]+'.png'
            x_data.append(get_image_array(filename))
            y_data.append(j)
    #剩下10%为测试集
    for i in [k+90 for k in range(int(0.1*num))]:
            for j in range(36):
                filename='collection/'+str(i)+'_'+char[j]+'.png'
                x_test.append(get_image_array(filename))
                y_test.append(j)
    #返回训练集和测试集
    return [x_data,y_data,x_test,y_test]

搭建神经网络框架

这里的一些Keras的基本概念不再重复了。需要注意的是,单个验证码图片经过处理成18*27的矩阵了。在数据作为输入时需要除255来使矩阵内元素大小都处于0~1(标准化输入数据)。关于数据的读取和处理,单个图片数据需要从18*27的矩阵转为486*1的矩阵。而图片的读取则在image_handle.py文件中。

from image_handle import load_image
import numpy as np
from keras.models import Sequential
from keras.layers import Dense,Activation
def tran_y(y):
    y_ohe=np.zeros(36)
    y_ohe[y]=1
    return y_ohe
x_data,y_data,x_test,y_test=list(),list(),list(),list()
x_data,y_data,x_test,y_test=load_image(1000)
#读入数据
y_train=np.array([tran_y(y_data[i]) for i in range(len(y_data))])
y_test=np.array([tran_y(y_test[i]) for i in range(len(y_test))])
x_train=np.array(x_data)/255
x_test=np.array(x_test)/255
#标准化数据
model=Sequential()
model.add(Dense(units=300,kernel_initializer='random_uniform',bias_initializer='ones',input_dim=486))
#输入大小是18*27=486
model.add(Activation("relu"))
model.add(Dense(units=100,kernel_initializer='random_uniform',bias_initializer='ones'))
model.add(Activation("relu"))
model.add(Dense(36,kernel_initializer='random_uniform',bias_initializer='ones'))
model.add(Activation("softmax"))
model.compile(loss='binary_crossentropy',optimizer='adam',metrics=['accuracy'])
#模型构建完成
model.fit(x_train,y_train,epochs=1,batch_size=36)
predict=model.predict(x_test)
scores=model.evaluate(x_test,y_test,verbose=2)
print('Real labels:')
print([i.index(1) for i in y_test[0:10].tolist()])
print('Predict is :')
print([i.index(max(i)) for i in predict[0:10].tolist()])
#前十个真实标签与测试值的对比
print(str(scores[1]*100)+'%')
#正确率

在1000个样本的情况下,正确率可以达到100%

基于Keras框架的简易验证码识别网络的构建_第1张图片

你可能感兴趣的:(machine,learning)