最近在研究 tensorflow框架下的深度学习,了解到深度学习对数据非常依赖,而标注好的数据集非常难得。今天发现 python 的captcha
库,可以生成验证码,因此,完全可以利用captcha
库生成一个验证码数据集,用于图片识别的实验。这其中会用到 yeild 和 next 关键字,生成数据 generator。
captcha 库的安装
captcha 库的安装非常简单,直接利用 pip
命令安装即可。
pip install captcha
看终端提示,它是先安装了 captcha
库,接着安装了 pillow
库。如果 pip
命令安装失败,可以自己下载安装包安装。
python实战,调用 captcha 生成简单图形验证码
安装好 captcha 库后,就可以使用 python 调用,生成验证码了。因为计划做图片识别,所以这里生成图形验证码。这里是一个例子。
#-*- coding:utf-8 -*-
from captcha.image import ImageCaptcha
import random
import string
image = ImageCaptcha(160,60) # 图片宽 160 高 60
characters = string.digits + string.ascii_uppercase + string.ascii_lowercase #验证码组成,数字+大写字母+小写字母
char_num = 4 #验证码字符个数
captcha_str = ''.join(random.sample(characters, char_num))
img = image.generate_image(captcha_str)
img.save(captcha_str + '.jpg')
上述代码生成了一个 160x60 的图形验证码,验证码由 4 位随机的数字、大小写字母组成,生成的验证码我们保存为 jpg 格式。
执行代码,得到如下图片:
因为验证码是由 10 个数字和 26 个字母组成,所以一共有 10 + 26x2(大小写) = 62 个类别,每次随机取 4 个字符组成验证码,如果标签用 one-hot 编码,那么标签的大小为 62x4 = 248。
python 的 yield 关键字
本节学习使用 python 的 captcha 库的目的就是为了做深度学习的数据集,深度学习网络需要很大的数据量,而存储和计算数据的内存是有限的,这两点其实是一对矛盾。我们需要大量数据,但是却没有无限大的内存存储它,有解决办法吗?当然是有的。
我们可以用多少,生成多少。比如训练深度学习网络时,需要一个 batch 的大小为 64 张验证码,那完全可以一次只生成 64 张图片。
似乎可以这样来:我们写一个函数,每次生成 64 张图片,需要数据时,调用一次该函数即可。这当然可行,只不过这样会有一个问题:每次生成图片都需要初始化程序,并且退出程序,而这样会导致产生数据的效率低下。为了解决这个问题,python有个叫数据生成器(generator)的功能,借助yield
和next
关键字,可以再程序不重启的情况下,产生一个 batch 的图片。看下面这段代码:
def gen_captcha(self,batch_size = 50):
...
while True:
for i in range(batch_size):
...
Y[i,j,self.characters.find(ch)] = 1
Y = np.reshape(Y,(batch_size,self.char_num*self.classes))
yield X,Y
咋一看它是一个死循环,不过 yield 关键字的使用,让它可以完成数据generator的功能。每次程序执行到yield
时,它会将 X 和 Y 返回,但是这个函数不会退出,在遇到 next 关键字后,它会接着运行
。例如我们在别处调用了
batch_x,batch_y = next(captcha.gen_captcha(64))
gen_captcha
函数会从上次停下的地方接着运行,这就源源不断的产生 batch size 的验证码图片了。
将生成验证码的动作封装为库
这一部分,我们基于前面的内容,利用 python 的 captcha 库,封装一个可以每次产生验证码 batch 的类,用于后续的深度学习网络的训练。代码如下:
#-*- 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,#验证码字符个数
characters = string.digits + string.ascii_uppercase + string.ascii_lowercase):#验证码组成,数字+大写字母+小写字母
self.width = width
self.height = height
self.char_num = char_num
self.characters = characters
self.classes = len(characters)
# print self.classes
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 in enumerate(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 x in np.argmax(y,axis = 2)[0,:])
def get_parameter(self):
return self.width,self.height,self.char_num,self.characters,self.classes
这里,我们详细分析一下 gen_captcha
函数,它是用来产生验证码 batch 的。
- X:一个 mini-batch 的训练数据,其 shape 为 [ batch_size, height, width, 1 ],batch_size 表示每批次多少个训练数据,height 表示验证码图片的高,width 表示验证码图片的宽,1 表示图片的通道。
- Y:X 中每个训练数据属于哪一类验证码,其形状为 [ batch_size, class ] ,对验证码中每个字符进行 One-Hot 编码,所以 class 大小为 4*62。
在每一个 batch 中,程序先将 RGB 彩色图片转成灰度图片,然后将数据全部变换到 [0,1] 范围内,存在 X 的第 i 个 batch。
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
标签值存在 Y 里,令 Y 中每个 batch 对应的字符的位置等于 1(即 one-hot 编码),最后将 Y 转成 [batch_size, 总类别] 的形状。
for j,ch in enumerate(captcha_str):
Y[i,j,self.characters.find(ch)] = 1
Y = np.reshape(Y,(batch_size,self.char_num*self.classes))
至此,利用 python 的 captcha 库生成验证码数据集的准备工作就做好了,今后研究深度学习图片识别时,这个可以作为一个不错的数据集。只需要将对象实例化,使用 next
关键字,就可以源源不断的获得训练的验证码 batch。
[…] 在python如何生成验证码小节,我们利用 captcha 库做了一个图形验证码产生器,可以产生带 one-hot 标签的图片数据集。本节将基于此数据集,建立一个卷积深度学习网络(CNN),并且训练之,希望可以识别破解此验证码数据集。 […]