更多:TensorFlow…
第06课:TensorFlow 实战二:验证码识别
一、前期回顾:
通过前面几篇文章,大家应该已经初步掌握了:如何使用 TensorFlow,如何搭建一个 CNN 模型,如何对模型进行优化,如何对模型进行可视化。
本篇文章,将和大家一起解决一个实际问题:“破解验证码”。
二、需要准备的:
- 一台有 NVIDIA 显卡的电脑,因为这次的模型比较大,如果是用 CPU 训练起来会很慢,甚至直接死机。如果没有好显卡,也可以在 AWS(亚马逊云)上申请一个竞价的 GPU 服务器,一个小时也就几块钱,租几个小时即可,比国内要便宜的多。后面我可以写一篇如何在 AWS 上租服务器的文章。
- 先安装好 Keras、captcha、tqdm 这几个包
三、代码实现:
1,生成随机验证码图片
我们自己做一个生成验证码的程序,这样可以生成无数的验证码进行学习
from captcha.image import ImageCaptcha import matplotlib.pyplot as plt import numpy as np import random //%matplotlib inline //%config InlineBackend.figure_format = 'retina' import string ###--------------- ###一、生成随机验证码 ### -------------- #设置字符集 characters = string.digits + string.ascii_uppercase print(characters) #设置图片长宽、字符个数和字符集类别数量 width, height, n_len, n_class = 170, 80, 4, len(characters) #定义生成器 generator = ImageCaptcha(width=width, height=height) #随机生成4个字符 random_str = ''.join([random.choice(characters) for j in range(n_len)]) #把字符转变成图片 img = generator.generate_image(random_str) #显示图片 plt.imshow(img) plt.title(random_str) #定义数据生成器 def gen(batch_size=32): X = np.zeros((batch_size, height, width, 3), dtype=np.uint8) y = [np.zeros((batch_size, n_class), dtype=np.uint8) for i in range(n_len)] generator = ImageCaptcha(width=width, height=height) while True: for i in range(batch_size): # 生产随机字符 random_str = ''.join([random.choice(characters) for j in range(4)]) # 生产图片 X[i] = generator.generate_image(random_str) # 把Y设置成4个列表 for j, ch in enumerate(random_str): y[j][i, :] = 0 y[j][i, characters.find(ch)] = 1 yield X, y #把数组y转换成字符 def decode(y): y = np.argmax(np.array(y), axis=2)[:,0] return ''.join([characters[x] for x in y])

图片生成的实例
2,构造模型
这里构造了一个比较深的模型,所以训练的速度会比较慢。
###--------------- ###二、构造模型 ai8py.com ### -------------- from keras.models import * from keras.layers import * from keras.optimizers import * input_tensor = Input((height, width, 3)) x = input_tensor x = Lambda(lambda x:(x-127.5)/127.5)(x) #搭建一个CNN,使用两个卷积、一个池化作为单元,循环4次; #然后Flatten和Dropout,全连接 input_tensor = Input((height, width, 3)) x = input_tensor for i in range(4): x = Convolution2D(32*2**i, 3, 3, activation='relu')(x) x = Convolution2D(32*2**i, 3, 3, activation='relu')(x) x = MaxPooling2D((2, 2))(x) x = Flatten()(x) x = Dropout(0.25)(x) x = [Dense(n_class, activation='softmax', name='c%d'%(i+1))(x) for i in range(4)] # 这里和之前不同的是,input和output指定方式不一样 model = Model(input=input_tensor, output=x) model.compile(loss='categorical_crossentropy', optimizer='adadelta', metrics=['accuracy']) # 查看模型 model.summary()

模型参数展示
3、训练模型
如果没有显卡,真心是慢。这……是不是给了大家升级机器配置的理由?O(∩_∩)O哈哈~
# 训练模型 model.fit_generator(gen(), samples_per_epoch=51200, nb_epoch=5, nb_worker=2, pickle_safe=True, validation_data=gen(), nb_val_samples=1280)

训练模型
4、测试结果
测试单次的结果:
测试结果 X, y = next(gen(1)) y_pred = model.predict(X) plt.title('real: %s\npred:%s'%(decode(y), decode(y_pred))) plt.imshow(X[0], cmap='gray') plt.axis('off')

单个样本测试
测试大批量样本的平均准确率:
from tqdm import tqdm def evaluate(model, batch_num=100): batch_acc = 0 generator = gen() for i in tqdm(range(batch_num)): X, y = generator.next() y_pred = model.predict(X) batch_acc += np.mean(map(np.array_equal, np.argmax(y, axis=2).T, np.argmax(y_pred, axis=2).T)) return batch_acc / batch_num evaluate(model)

平均准确率
小结
卷积神经网络很强大,我们这里只是识别4位的字母+数字的验证码,如果我们有大量中文的验证码作为学习材料,识别中文也是可以的。也就是说:我们喂给模型什么东西,它就学到什么。
到这里,TensorFlow 可以说已经入门了,如果希望能再深入学习。建议如下:
- 目前机器学习中大部分应用都基于深度学习,这一次人工智能浪潮的到来,也是因为深度学习的发展,所以深度学习是目前推荐的方向。
- 掌握了 TensorFlow,只是学会了一个工具,最多是“手中有剑”。我们还要对机器学习和深度学习的理论进行系统学习。
- 在掌握了理论知识后,可以开始看各种学术论文,然后尝试自己实现。如果觉得实现有难度,可以到 GitHub 上去查找前人实现的代码。我们做过的事,肯定别人已经做过无数次了。
- 看过若干论文和实现了若干论文上的模型后,相信你已经做到“手中有剑,心中也有剑”。可以到 Kaggle 上尝试参加比赛,加入我的深度学习爱好者社群,在群里大家思维一起碰撞,说不定就会找到 Magic Feature。