本博客开设了”深度学习计算机视觉实战“专栏,有兴趣的朋友欢迎访问并分享给您的朋友。
欢迎关注公众号”计算机视觉与OpenCV“,本号不定期会发出赠书活动。
欢迎加入QQ群**”187042448“**获取更多的软件编程、AI、机器学习、深度学习的资料。
欢迎加微信study428拉入微信群,暂时VI和VII群还可以扫码进群。
验证码在生活中随处可见,注册个网站你要被弯弯曲曲外加各种干扰的验证码折磨,买个票你要被12306的小图片验证码逼疯。搞个验证码主要是因为防止机器的恶意操作,简单说就是确认操作者是个人。
但是有的时候就想做成自动化的,咋办呢?这就要用到本文说的”验证码识别“了。
验证码识别是采用深度学习的方法,自动识别验证码的内容,本节的验证码识别是针对字母和数字组合的这种样式的,不是针对12306上那种让你选下面图中包含哪种物品的,那是属于图像识别或者图像分类的范畴,这个在后续文章有会做介绍。
本文分享的内容来源于图书《深度学习计算机视觉实战》,该书由刘东研究员和肖铃合作完成,由电子工业出版社出版。
该书从算法导读到模型训练,到模型部署一站式搞定,书中案例注释详细,均已通过运行验证。该书包括4个部分:
第一部分(1~2章)深度学习和计算机视觉的基础和算法讲解; 第二部分(3~6章)传统图像处理算法的案例讲解;
第三部分(7-11章)计算机视觉方向的案例讲解; 第四部分(12~13章)Tensorflow
Lite讲解(源码分析、模型优化、模型转换等)以及使用Tensorflow Lite在PC端和移动端的部署案例讲解。
本书可以为计算机视觉入门的读者和想要对模型进行工程部署的读者提供参考与帮助。京东自营正品链接:https://u.jd.com/rwk3HPT
下面就是验证码识别所在章节的目录:
要训练验证码识别的模型,包括以下四个步骤:
验证码的识别模型,主要步骤如下:
1、生成训练所需的验证码图片;
2、生成图片标签;
3、搭建识别网络并训练模型;
4、将模型部署应用。
现在分步骤介绍如下:
1、生成训练所需的验证码图片
有很多验证码图片生成的软件或者库,这里我用的是captcha库,需要先安装对应的Python包。使用captcha库的ImageCaptcha类生成验证码图片。
本案例使用的验证码是数字和大写字母的组合,可以自己修改对应的类别,生成不同的验证码。验证码生成代码如下:
from captcha.image import ImageCaptcha
import string
CHAR_SET = string.digits + string.ascii_uppercase #验证码中使用的字符集合
CHAR_LEN = len(CHAR_SET) #验证码字符集合中的字符数量
CAPTCHA_LEN = 3 #使用的验证码的长度为3
for i in range(CHAR_LEN):
for j in range(CHAR_LEN):
for k in range(CHAR_LEN):
captcha_text = CHAR_SET[i] + CHAR_SET[j] + CHAR_SET[k] #验证码内容
image = ImageCaptcha() #使用captcha生成验证码图片
try:
image.write(captcha_text, './data/'+ captcha_text + '.jpg') #将内容写入图片
except:
print(captcha_text) #图片写入失败时打印对应的内容
生成的验证码图片如下所示:
2、生成图片标签
标签就是图片的名称,可以直接读取图片的名称作为标签,三位验证码,数字和大写字母合起来有10+26=36种,三位验证码使用one-hot编码如“69A”,对于第一个字符“6”,在36个字符中的索引位置为第7位,所以创建一个全0序列,将第7位置为1,即“000000100000000000000000000000000000”,同理对于字符“9”和“A”,在对应的索引位置将该位置置1,最后将三个字符的编码结果拼接就是最终的label的结果。
3、搭建识别网络并训练模型
模型训练需分出训练集与测试集,可以使用sklearn的train_test_split函数来实现:
from sklearn.model_selection import train_test_split
#划分测试集,训练集
x_train, x_test, y_train, y_test = train_test_split(image_files, image_labels, test_size=0.1, random_state=33)
然后就可以使用tensorflow搭建模型训练网络:
def network():
x = tf.reshape(input, shape=[-1, IMAGE_HEIGHT, IMAGE_WIDTH, 1])
#第一层卷积
w1 = tf.Variable(0.01 * tf.random_normal([3,3,1,32])) #第一层权重
b1 = tf.Variable(0.1 * tf.random_normal([32])) #第一层偏置
#卷积
conv1 = tf.nn.Relu(tf.nn.bias_add(tf.nn.conv2d(x, w1, strides=[1,1,1,1], padding='SAME'), b1))
#池化
conv1 = tf.nn.max_pool(conv1, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')
#Dropout
conv1 = tf.nn.Dropout(conv1, keep_prob)
#归一化
norm1 = tf.nn.lrn(conv1, 4, bias=1.0, alpha=0.001 / 9.0, beta=0.75, name='norm1')
#第二层卷积
w2 = tf.Variable(0.01 * tf.random_normal([3,3,32,64]))
b2 = tf.Variable(0.1 * tf.random_normal([64]))
conv2 = tf.nn.Relu(tf.nn.bias_add(tf.nn.conv2d(norm1, w2, strides=[1,1,1,1], padding='SAME'), b2))
conv2 = tf.nn.max_pool(conv2, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')
conv2 = tf.nn.Dropout(conv2, keep_prob)
norm2 = tf.nn.lrn(conv2, 4, bias=1.0, alpha=0.001 / 9.0, beta=0.75, name='norm1')
#第三层卷积
w3 = tf.Variable(0.01 * tf.random_normal([3,3,64,128]))
b3 = tf.Variable(0.1 * tf.random_normal([128]))
conv3 = tf.nn.Relu(tf.nn.bias_add(tf.nn.conv2d(norm2, w3, strides=[1,1,1,1], padding='SAME'), b3))
conv3 = tf.nn.max_pool(conv3, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')
conv3 = tf.nn.Dropout(conv3, keep_prob)
norm3 = tf.nn.lrn(conv3, 4, bias=1.0, alpha=0.001 / 9.0, beta=0.75, name='norm1')
#第一层全连接
wd1 = tf.Variable(0.01 * tf.random_normal([8*20*128, 1024]))
bd1 = tf.Variable(0.1 * tf.random_normal([1024]))
dense = tf.reshape(norm3, [-1, wd1.get_shape().as_list()[0]])
dense = tf.nn.Relu(tf.add(tf.matmul(dense, wd1), bd1))
dense = tf.nn.Dropout(dense, keep_prob)
#第二层全连接
wout = tf.Variable(0.01 * tf.random_normal([1024, CAPTCHA_LEN * CHAR_LEN]))
bout = tf.Variable(0.1 * tf.random_normal([CAPTCHA_LEN * CHAR_LEN]))
out = tf.add(tf.matmul(dense, wout), bout)
return out
网络搭建后就是进行模型的训练工作了。
4、将模型部署应用
(csdn这个编辑到这里没找到方法将内容设置为正文的格式,下面不出现正文编辑行,不知道是我没找到还是本身就是个bug。最终我通过md的方式解决了,这做的也是奇葩的很)
模型部署在书中的第12和13两章有详细的说明,读者朋友可以参考这里将模型进行部署。