验证码破解之一:定长文本验证码

2018-01-02 16:19:20 浏览数 (1)

之前写过一篇验证码的破解,地址在这,其实效果不好,有很多朋友来问,其实我已经说了只是个demo;既然如此,就写下文本验证码的破解;本次的主题是定长的,就是验证码的长度是个定值,也是大家在上网过程中遇到的最多的验证码。

其实挺简单的,网上也有很多的总结性的文章,基本验证码破解就两个思路(deep learning):

  • 定长类:卷积 多个Softmax
  • 不定长类: LSTM CTC

这次的方法就是卷积 多个softmax

与传统的方法的区别

传统的方法是:

  1. 判定长度
  2. 分割单个字符
  3. 单个字符分类

现在我们的方法是:

构建一个网络让其一次性输出所有的字符(定长)

好处是显而易见的,简单啊!!!!同时借助大量的数据可以获得相当高的成功率

破解过程

数据的获取

由于需要大量的数据,所以无法通过网络down下来手写答案,所以只好代码生成;有一个python库可以帮我们搞定这个事情,地址戳这 贴下官方生成验证码的示例:

代码语言:javascript复制
from captcha.audio import AudioCaptcha
from captcha.image import ImageCaptcha

audio = AudioCaptcha(voicedir='/path/to/voices')
image = ImageCaptcha(fonts=['/path/A.ttf', '/path/B.ttf'])

data = audio.generate('1234')
audio.write('1234', 'out.wav')

data = image.generate('1234')
image.write('1234', 'out.png')

非常简单,同时还可以生成语音验证码

构建网络

大家看下生成的验证码图片就知道了其实很简单,所以网络不需要构建很复杂就可以很有效的搞定这件事,假设字符的固定长度是4,参考代码如下(keras):

代码语言:javascript复制
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)]
model = Model(input=input_tensor, output=x)

很简单对吧,其实这个网络就可以工作的很好

训练

代码语言:javascript复制
model.fit_generator(gen(), samples_per_epoch=51200, nb_epoch=5, nb_worker=2, pickle_safe=True, validation_data=gen(), nb_val_samples=1280)

gen是个生成器,生成训练数据

测试

代码语言:javascript复制
x, y = next(gen(1))
y_pred = model.predict(X)
plt.title('real: %snpred:%s'%(decode(y), decode(y_pred)))
plt.imshow(X[0], cmap='gray')

结果

训练了5个epoch,每个epoch大概5W张,acc可以到0.99

代码我是跑了别人使用Keras写的,准备使用Tensorflow复现下,写好后一并拿出来吧,暂时没有!

参考博客:

端到端的OCR

0 人点赞