用vgg16做验证码识别(tensorflow版)

这篇文章主要是使用vgg16网络实现验证码的自动识别:
(1) captcha库
这个库可以自动生成验证码,生成验证码的代码如下:

from captcha.image import ImageCaptcha
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np


number = [str(i) for i in range(10)]
alphabet = [chr(i+ord('a')) for i in range(26)]
ALPHABET = [chr(i+ord('A')) for i in range(26)]
captcha_content = number+alphabet+ALPHABET
def gen_captcha(captcha_content,captcha_len=4):

    # captcha_content 构成验证码的字符list
    # captcha_len 验证码的长度
    captcha_str = np.random.choice(captcha_content,captcha_len)
    imageCaptcha = ImageCaptcha()
    captcha = imageCaptcha.generate(captcha_str)
    captcha = Image.open(captcha)
    captcha = np.array(captcha)
    return captcha,captcha_str
if __name__ == '__main__':
    captcha, captcha_str = gen_captcha(captcha_content, captcha_len=4)
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.set_title(captcha_str)
    ax.imshow(captcha)
    plt.show()

生成效果如下:
这里写图片描述

(2) 定义验证码识别的模型

import numpy as np
import tensorflow as tf

#image_size = [60,160,3]

def captcha_model(image_size,cap_size,input_data):

    with tf.name_scope('preprocess'):

        img_mean = tf.constant([123.68, 116.779, 103.939],tf.float32,shape=[1,1,1,3],name='img_mean')

        input_net = input_data - img_mean


    with tf.variable_scope('conv1') as scope:
        conv1_1 = tf.layers.conv2d(input_net,64,[3,3],[1,1],padding='same',activation=tf.nn.relu,kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),bias_initializer=tf.zeros_initializer(),name='conv1_1')
        conv1_2 = tf.layers.conv2d(conv1_1, 64, [3, 3], [1,1], padding='same', activation=tf.nn.relu,kernel_initializer=tf.truncated_normal_initializer(stddev=0.01), name='conv1_2')
        pool1_1 = tf.layers.max_pooling2d(conv1_2,[2,2],[2,2],'same',name='conv1_pool')

    with tf.variable_scope('conv2') as scope:

        conv2_1 = tf.layers.conv2d(pool1_1,128,[3,3],[1,1],padding='same',activation=tf.nn.relu,kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),bias_initializer=tf.zeros_initializer(),name='conv2_1')
        conv2_2 = tf.layers.conv2d(conv2_1, 128, [3, 3], [1, 1], padding='same', activation=tf.nn.relu,kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),bias_initializer=tf.zeros_initializer(), name='conv2_2')
        pool2_1 = tf.layers.max_pooling2d(conv2_2, [2, 2], [2, 2], 'same', name='conv2_pool')

    with tf.variable_scope('conv3') as scope:

        conv3_1 = tf.layers.conv2d(pool2_1,256,[3,3],[1,1],padding='same',activation=tf.nn.relu,kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),bias_initializer=tf.zeros_initializer(),name='conv3_1')
        conv3_2 = tf.layers.conv2d(conv3_1, 256, [3, 3], [1, 1], padding='same', activation=tf.nn.relu,kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),bias_initializer=tf.zeros_initializer(), name='conv3_2')
        conv3_3 = tf.layers.conv2d(conv3_2, 256, [3, 3], [1, 1], padding='same', activation=tf.nn.relu,kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),bias_initializer=tf.zeros_initializer(), name='conv3_3')
        pool3_1 = tf.layers.max_pooling2d(conv3_3, [2, 2], [2, 2], 'same', name='conv3_pool')

    with tf.variable_scope('conv4') as scope:

        conv4_1 = tf.layers.conv2d(pool3_1,512,[3,3],[1,1],padding='same',activation=tf.nn.relu,kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),bias_initializer=tf.zeros_initializer(),name='conv4_1')
        conv4_2 = tf.layers.conv2d(conv4_1, 512, [3, 3], [1, 1], padding='same', activation=tf.nn.relu,kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),bias_initializer=tf.zeros_initializer(), name='conv4_2')
        conv4_3 = tf.layers.conv2d(conv4_2, 512, [3, 3], [1, 1], padding='same', activation=tf.nn.relu,kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),bias_initializer=tf.zeros_initializer(), name='conv4_3')
        pool4_1 = tf.layers.max_pooling2d(conv4_3, [2, 2], [2, 2], 'same', name='conv4_pool')

    with tf.variable_scope('conv5') as scope:

        conv5_1 = tf.layers.conv2d(pool4_1,512,[3,3],[1,1],padding='same',activation=tf.nn.relu,kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),bias_initializer=tf.zeros_initializer(),name='conv5_1')
        conv5_2 = tf.layers.conv2d(conv5_1, 512, [3, 3], [1, 1], padding='same', activation=tf.nn.relu,kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),bias_initializer=tf.zeros_initializer(), name='conv5_2')
        conv5_3 = tf.layers.conv2d(conv5_2, 512, [3, 3], [1, 1], padding='same', activation=tf.nn.relu,kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),bias_initializer=tf.zeros_initializer(), name='conv5_3')
        pool5_1 = tf.layers.max_pooling2d(conv5_3, [2, 2], [2, 2], 'same', name='conv4_pool')

    with tf.variable_scope('fc') as scope:


        #flat = tf.layers.flatten(pool5_1)
        flat = tf.reshape(pool5_1,shape=[-1,5120])

        fc1 = tf.layers.dense(flat,1024,name='fc1',kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),bias_initializer=tf.zeros_initializer(),activation=tf.nn.relu)
        fc2 = tf.layers.dense(fc1, 512,kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),bias_initializer=tf.zeros_initializer(),name='fc2')
        logits = tf.layers.dense(fc2,cap_size,name='fc3',activation=None)

        return logits

定义数据生成py文件:

from captcha.image import ImageCaptcha
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
def gen_captcha(captcha_content,captcha_len=4):

    # captcha_content 构成验证码的字符list
    # captcha_len 验证码的长度
    captcha_str = np.random.choice(captcha_content,captcha_len)
    imageCaptcha = ImageCaptcha()
    captcha = imageCaptcha.generate(captcha_str)
    captcha = Image.open(captcha)
    captcha = np.array(captcha)
    return captcha,captcha_str

def gen_batch(batch_size,image_size,captcha_content,str_to_int,captcha_len=4):


    x_train = np.zeros([batch_size,*image_size])
    y_ture = np.zeros([batch_size,captcha_len])

    while True:
        for i in range(batch_size):
            xs,ys = gen_captcha(captcha_content,captcha_len)
            x_train[i,:,:,:] = xs
            y_ture[i,:] = np.array([str_to_int[i] for i in ys])

        yield x_train,y_ture

定义训练py文件:

from model import captcha_model
from utils import gen_batch,build_dict_str_int
import tensorflow as tf
import numpy as np


number = [str(i) for i in range(10)]
alphabet = [chr(i+ord('a')) for i in range(26)]
ALPHABET = [chr(i+ord('A')) for i in range(26)]

image_size = [60,160,3]
lr = 0.001
epochs = 100
batch_size = 64
captcha_content = number
captcha_len = 4
captcha_size = len(captcha_content)
cap_size = captcha_size*captcha_len

str_to_int,int_to_str = build_dict_str_int(captcha_content)

input_data = tf.placeholder(dtype=tf.float32, shape=[None, *image_size], name='input_data')

label = tf.placeholder(dtype=tf.int32, shape=[None, captcha_len])

logits = captcha_model(image_size,cap_size,input_data)

y_true_one = tf.one_hot(indices=label,depth=captcha_size,axis=2,name='one_hot')
re_y_true = tf.reshape(y_true_one,shape=[batch_size,-1])

loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logits,labels=re_y_true))

optimizer = tf.train.AdamOptimizer(lr).minimize(loss)

y_pre = tf.argmax(tf.reshape(logits,[-1,captcha_len,captcha_size]),2)
y_true = tf.argmax(y_true_one,2)

accuracy = tf.reduce_mean(tf.cast(tf.equal(y_pre,y_true),tf.float32))


with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    writer = tf.summary.FileWriter('./graph/crack_capcha',sess.graph)

    saver = tf.train.Saver()
    gen_data = gen_batch(batch_size,image_size,captcha_content,str_to_int,captcha_len)
    epoch = 0
    while True:


        #for epoch in range(epochs):
        xs, ys = next(gen_data)
        _,train_loss,train_acc = sess.run([optimizer,loss,accuracy],feed_dict={input_data:xs,label:ys})

        if epoch % 10 == 0:
            print('Epochs {}/{} train_acc {},train_loss {}'.format(epoch,epochs,train_acc,train_loss))

            #saver.save(sess, "./model/crack_capcha.model", global_step=epoch)
        if train_acc > 0.9:
                saver.save(sess, "./model/crack_capcha.model", global_step=epoch)
                break
        epoch += 1
    writer.close()

训练时间可能比较长,耐心等待

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值