前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python2.7搬运--->TensorFlow - 深度学习破解验证码

python2.7搬运--->TensorFlow - 深度学习破解验证码

作者头像
98k
发布2018-04-11 15:38:00
1.1K0
发布2018-04-11 15:38:00
举报
文章被收录于专栏:Django ScrapyDjango Scrapy

谷歌的开源深度学习工具 --py

简介

验证码主要用于防刷,传统的验证码识别算法一般需要把验证码分割为单个字符,然后逐个识别,如果字符之间相互重叠,传统的算法就然并卵了,本文采用cnn对验证码进行整体识别。通过本文的学习,大家可以学到几点:1.captcha库生成验证码;2.如何将验证码识别问题转化为分类问题;3.可以训练自己的验证码识别模型。

安装 captcha 库

sudo pip install captcha

生成验证码训练数据

所有的模型训练,数据是王道,本文采用 captcha 库生成验证码,captcha 可以生成语音和图片验证码,我们采用生成图片验证码功能,验证码是由数字、大写字母、小写字母组成(当然你也可以根据自己的需求调整,比如添加一些特殊字符),长度为 4,所以总共有 62^4 种组合验证码。

验证码生成器

采用 python 中生成器方式来生成我们的训练数据,这样的好处是,不需要提前生成大量的数据,训练过程中生成数据,并且可以无限生成数据。 |现在您可以在 /home/ubuntu 目录下创建源文件 generate_captcha.py,内容可参考:

代码语言:javascript
复制
#!/usr/bin/python
# -*- 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)

    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

    def gen_test_captcha(self):
        image = ImageCaptcha(width = self.width,height = self.height)
        captcha_str = ''.join(random.sample(self.characters,self.char_num))
        img = image.generate_image(captcha_str)
        img.save(captcha_str + '.jpg')

然后执行:

代码语言:javascript
复制
cd /home/ubuntu;
python
import generate_captcha
g = generate_captcha.generateCaptcha()
g.gen_test_captcha()

执行结果:

在 /home/ubuntu 目录下查看生成的验证码,jpg 格式的图片可以点击查看。

验证码识别模型

将验证码识别问题转化为分类问题,总共 62^4 种类型,采用 4 个 one-hot 编码分别表示 4 个字符取值。

cnn 验证码识别模型

3 层隐藏层、2 层全连接层,对每层都进行 dropout。input——>conv——>pool——>dropout——>conv——>pool——>dropout——>conv——>pool——>dropout——>fully connected layer——>dropout——>fully connected layer——>output 示例代码: 现在您可以在 /home/ubuntu 目录下创建源文件 captcha_model.py,内容可参考:

代码语言:javascript
复制
#!/usr/bin/python
# -*- coding: utf-8 -*

import tensorflow as tf
import math

class captchaModel():
    def __init__(self,
                 width = 160,
                 height = 60,
                 char_num = 4,
                 classes = 62):
        self.width = width
        self.height = height
        self.char_num = char_num
        self.classes = classes

    def conv2d(self,x, W):
        return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

    def max_pool_2x2(self,x):
        return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
                              strides=[1, 2, 2, 1], padding='SAME')

    def weight_variable(self,shape):
        initial = tf.truncated_normal(shape, stddev=0.1)
        return tf.Variable(initial)

    def bias_variable(self,shape):
        initial = tf.constant(0.1, shape=shape)
        return tf.Variable(initial)

    def create_model(self,x_images,keep_prob):
        #first layer
        w_conv1 = self.weight_variable([5, 5, 1, 32])
        b_conv1 = self.bias_variable([32])
        h_conv1 = tf.nn.relu(tf.nn.bias_add(self.conv2d(x_images, w_conv1), b_conv1))
        h_pool1 = self.max_pool_2x2(h_conv1)
        h_dropout1 = tf.nn.dropout(h_pool1,keep_prob)
        conv_width = math.ceil(self.width/2)
        conv_height = math.ceil(self.height/2)

        #second layer
        w_conv2 = self.weight_variable([5, 5, 32, 64])
        b_conv2 = self.bias_variable([64])
        h_conv2 = tf.nn.relu(tf.nn.bias_add(self.conv2d(h_dropout1, w_conv2), b_conv2))
        h_pool2 = self.max_pool_2x2(h_conv2)
        h_dropout2 = tf.nn.dropout(h_pool2,keep_prob)
        conv_width = math.ceil(conv_width/2)
        conv_height = math.ceil(conv_height/2)

        #third layer
        w_conv3 = self.weight_variable([5, 5, 64, 64])
        b_conv3 = self.bias_variable([64])
        h_conv3 = tf.nn.relu(tf.nn.bias_add(self.conv2d(h_dropout2, w_conv3), b_conv3))
        h_pool3 = self.max_pool_2x2(h_conv3)
        h_dropout3 = tf.nn.dropout(h_pool3,keep_prob)
        conv_width = math.ceil(conv_width/2)
        conv_height = math.ceil(conv_height/2)

        #first fully layer
        conv_width = int(conv_width)
        conv_height = int(conv_height)
        w_fc1 = self.weight_variable([64*conv_width*conv_height,1024])
        b_fc1 = self.bias_variable([1024])
        h_dropout3_flat = tf.reshape(h_dropout3,[-1,64*conv_width*conv_height])
        h_fc1 = tf.nn.relu(tf.nn.bias_add(tf.matmul(h_dropout3_flat, w_fc1), b_fc1))
        h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

        #second fully layer
        w_fc2 = self.weight_variable([1024,self.char_num*self.classes])
        b_fc2 = self.bias_variable([self.char_num*self.classes])
        y_conv = tf.add(tf.matmul(h_fc1_drop, w_fc2), b_fc2)

        return y_conv

训练 cnn 验证码识别模型

每批次采用 64 个训练样本,每 100 次循环采用 100 个测试样本检查识别准确度,当准确度大于 99% 时,训练结束,采用 GPU 需要 5-6 个小时左右,CPU 大概需要 20 个小时左右。 注:作为实验,你可以通过调整 train_captcha.py 文件中 if acc > 0.99: 代码行的准确度节省训练时间(比如将 0.99 为 0.01);同时,我们已经通过长时间的训练得到了一个训练集,可以通过如下命令将训练集下载到本地。

代码语言:javascript
复制
wget http://tensorflow-1253902462.cosgz.myqcloud.com/captcha/capcha_model.zip
unzip capcha_model.zip

现在您可以在 /home/ubuntu 目录下创建源文件 train_captcha.py,内容可参考:

代码语言:javascript
复制
#!/usr/bin/python

import tensorflow as tf
import numpy as np
import string
import generate_captcha
import captcha_model

if __name__ == '__main__':
    captcha = generate_captcha.generateCaptcha()
    width,height,char_num,characters,classes = captcha.get_parameter()

    x = tf.placeholder(tf.float32, [None, height,width,1])
    y_ = tf.placeholder(tf.float32, [None, char_num*classes])
    keep_prob = tf.placeholder(tf.float32)

    model = captcha_model.captchaModel(width,height,char_num,classes)
    y_conv = model.create_model(x,keep_prob)
    cross_entropy = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=y_,logits=y_conv))
    train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)

    predict = tf.reshape(y_conv, [-1,char_num, classes])
    real = tf.reshape(y_,[-1,char_num, classes])
    correct_prediction = tf.equal(tf.argmax(predict,2), tf.argmax(real,2))
    correct_prediction = tf.cast(correct_prediction, tf.float32)
    accuracy = tf.reduce_mean(correct_prediction)

    saver = tf.train.Saver()
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        step = 0
        while True:
            batch_x,batch_y = next(captcha.gen_captcha(64))
            _,loss = sess.run([train_step,cross_entropy],feed_dict={x: batch_x, y_: batch_y, keep_prob: 0.75})
            print ('step:%d,loss:%f' % (step,loss))
            if step % 100 == 0:
                batch_x_test,batch_y_test = next(captcha.gen_captcha(100))
                acc = sess.run(accuracy, feed_dict={x: batch_x_test, y_: batch_y_test, keep_prob: 1.})
                print ('###############################################step:%d,accuracy:%f' % (step,acc))
                if acc > 0.99:
                    saver.save(sess,"capcha_model.ckpt")
                    break
            step += 1

然后执行:

代码语言:javascript
复制
cd /home/ubuntu;
python train_captcha.py

执行结果:

代码语言:javascript
复制
step:75173,loss:0.010555
step:75174,loss:0.009410
step:75175,loss:0.009978
step:75176,loss:0.008089
step:75177,loss:0.009949
step:75178,loss:0.010126
step:75179,loss:0.009584
step:75180,loss:0.012272
step:75181,loss:0.010157
step:75182,loss:0.009529
step:75183,loss:0.007636
step:75184,loss:0.009058
step:75185,loss:0.010061
step:75186,loss:0.009941
step:75187,loss:0.009339
step:75188,loss:0.009685
step:75189,loss:0.009879
step:75190,loss:0.007799
step:75191,loss:0.010866
step:75192,loss:0.009838
step:75193,loss:0.010931
step:75194,loss:0.012859
step:75195,loss:0.008747
step:75196,loss:0.009147
step:75197,loss:0.009351
step:75198,loss:0.009746
step:75199,loss:0.010014
step:75200,loss:0.009024
###############################################step:75200,accuracy:0.992500

测试 cnn 验证码识别模型

示例代码: 现在您可以在 /home/ubuntu 目录下创建源文件 predict_captcha.py,内容可参考:

代码语言:javascript
复制
#!/usr/bin/python

from PIL import Image, ImageFilter
import tensorflow as tf
import numpy as np
import string
import sys
import generate_captcha
import captcha_model

if __name__ == '__main__':
    captcha = generate_captcha.generateCaptcha()
    width,height,char_num,characters,classes = captcha.get_parameter()

    gray_image = Image.open(sys.argv[1]).convert('L')
    img = np.array(gray_image.getdata())
    test_x = np.reshape(img,[height,width,1])/255.0
    x = tf.placeholder(tf.float32, [None, height,width,1])
    keep_prob = tf.placeholder(tf.float32)

    model = captcha_model.captchaModel(width,height,char_num,classes)
    y_conv = model.create_model(x,keep_prob)
    predict = tf.argmax(tf.reshape(y_conv, [-1,char_num, classes]),2)
    init_op = tf.global_variables_initializer()
    saver = tf.train.Saver()
    gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.95)
    with tf.Session(config=tf.ConfigProto(log_device_placement=False,gpu_options=gpu_options)) as sess:
        sess.run(init_op)
        saver.restore(sess, "capcha_model.ckpt")
        pre_list =  sess.run(predict,feed_dict={x: [test_x], keep_prob: 1})
        for i in pre_list:
            s = ''
            for j in i:
                s += characters[j]
            print s

然后执行:

代码语言:javascript
复制
cd /home/ubuntu;
python predict_captcha.py Kz2J.jpg # 在你的机器上的验证码图片名称

执行结果: Kz2J 注:因为实验时间的限制,你可能调整了准确度导致执行结果不符合预期,属于正常情况。 在训练时间足够长的情况下,你可以采用验证码生成器生成测试数据,cnn 训练出来的验证码识别模型还是很强大的,大小写的 z 都可以区分,甚至有时候人都无法区分,该模型也可以正确的识别。

更多 TensorFlow 的系列教程:

TensorFlow - 相关 API TensorFlow - 线性回归

关于 TensorFlow 的更多资料可参考 TensorFlow 官网 。有墙,访问外国网站访问

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.09.28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 谷歌的开源深度学习工具 --py
  • 简介
    • 安装 captcha 库
    • 生成验证码训练数据
      • 验证码生成器
        • 然后执行:
          • 执行结果:
            • cnn 验证码识别模型
        • 验证码识别模型
          • 训练 cnn 验证码识别模型
          • 测试 cnn 验证码识别模型
          相关产品与服务
          验证码
          腾讯云新一代行为验证码(Captcha),基于十道安全栅栏, 为网页、App、小程序开发者打造立体、全面的人机验证。最大程度保护注册登录、活动秒杀、点赞发帖、数据保护等各大场景下业务安全的同时,提供更精细化的用户体验。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档