精华内容
下载资源
问答
  • 深度学习实战之CNN验证码识别

    千次阅读 2018-12-11 01:54:49
    我们要使用卷积神经网络实现验证码识别,具体流程大致为: 1、使用python的captcha模块生成验证码图片。 2、使用tensorflow搭建神经网络模型。 3、将数据喂入神经网络进行训练。 4、保存训练好的网络模型。 下面...

    我们要使用卷积神经网络实现验证码的识别,具体流程大致为:
    1、使用python的captcha模块生成验证码图片。
    2、使用tensorflow搭建神经网络模型。
    3、将数据喂入神经网络进行训练。
    4、保存训练好的网络模型。

    下面我们来看具体的细节。
    一、定义字符集,验证码一般为数字、字母。练习的时候可以先只考虑数字的情况,这样模型训练的会快些。代码如下:

    number = ['0','1','2','3','4','5','6','7','8','9']
    alphabet = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
    ALPHABET = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
    

    二、下面我们要从给定的字符集中选择4个字符,生成160*60的验证码图片,并将图片转化为numpy数组。然后将选择的四个字符生成为词向量形式。
    1、生成图片并转化为数组。

    # 传入数据集,从数据集中随机选择四个元素,然后返回这四个元素
    # def random_captcha_text(char_set=number+alphabet+ALPHABET, captcha_size=4):
    def random_captcha_text(char_set=number, captcha_size=4):
        captcha_text = []
        for i in range(captcha_size):
            c = random.choice(char_set)
            captcha_text.append(c)
        return captcha_text
    
    # 生成验证码图片,返回图片转化后的numpy数组,以及验证码字符文本
    def gen_captcha_text_and_image():  
        image = ImageCaptcha()  
        captcha_text = random_captcha_text()
        captcha_text = ''.join(captcha_text)  
        captcha = image.generate(captcha_text)
        # image.write(captcha_text, captcha_text + '.jpg')  # 将图片保存到硬盘
        captcha_image = Image.open(captcha)
        captcha_image = captcha_image.convert('L')
        captcha_image = captcha_image.point(lambda i: 255 - i) 
        # 将图片取反,黑色变为白色,白色变为黑色,这样模型收敛更块
        captcha_image = np.array(captcha_image)
        return captcha_text, captcha_image
    

    2、传入验证码文本,转化为词向量的形式,假设我们现在只使用数字集0-9。那么就是10分类,我们用一个长度为10的向量来表示一个数字,比如[1, 0, 0, 0, 0, 0, 0, 0, 0, 0]表示数字0,[0, 1, 0, 0, 0, 0, 0, 0, 0, 0]表示数字1。我们有四个字符,所以是一个4*10的矩阵,再将这个矩阵拉平为一维的,就是长度为40的向量。
    如果我们现在采用数字加大小写字母为字符集,那就是4*(10+26+26),再将矩阵拉平,就是长度为248的向量。代码如下:

    # 传入验证码字符文本,生成对应的词向量
    def text2vec(text):  
        text_len = len(text)  
        if text_len > MAX_CAPTCHA:  
            raise ValueError('验证码最长4个字符')  
        vector = np.zeros(MAX_CAPTCHA*CHAR_SET_LEN)  
        def char2pos(c):
            if c =='_':
                k = 62
                return k  
            k = ord(c)-48  
            if k > 9:  
                k = ord(c) - 55  
                if k > 35:  
                    k = ord(c) - 61  
                    if k > 61:  
                        raise ValueError('No Map')   
            return k
        for i, c in enumerate(text):
            idx = i * CHAR_SET_LEN + char2pos(c)  
            vector[idx] = 1
        return vector
    

    三、以上代码每次只生成一张验证码,当然每次传入网络一个样本也可以,但我们习惯一次喂入多个样本,所以我们还要一次性生成多张图片传入网络。代码如下。

    def get_next_batch(batch_size=64):
        batch_x = np.zeros([batch_size, IMAGE_HEIGHT*IMAGE_WIDTH])  
        batch_y = np.zeros([batch_size, MAX_CAPTCHA*CHAR_SET_LEN])  
       
        for i in range(batch_size):
            text, image = gen_captcha_text_and_image()  
            batch_x[i,:] = image.flatten()  # 将二维数组拉平为一维
            batch_y[i,:] = text2vec(text)
    
        return batch_x, batch_y
    

    四、现在图片生成好了,对应的词向量也生成好了,要开始搭建网络了,我们采用三层卷积,一层全连接层,最后输出成,具体细节卷积过程等,可以见我上一篇文章手写汉字识别。代码如下:

    def crack_captcha_cnn(w_alpha=0.01, b_alpha=0.1):  
        x = tf.reshape(X, shape=[-1, IMAGE_HEIGHT, IMAGE_WIDTH, 1])  
        
        w_c1 = tf.Variable(tf.random_normal([3, 3, 1, 32], stddev=w_alpha))
        b_c1 = tf.Variable(tf.random_normal([32], stddev=b_alpha))
        conv1 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(x, w_c1, strides=[1, 1, 1, 1], padding='SAME'), b_c1))  
        conv1 = tf.nn.max_pool(conv1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')  
        conv1 = tf.nn.dropout(conv1, keep_prob)
    
        w_c2 = tf.Variable(tf.random_normal([3, 3, 32, 64], stddev=w_alpha))
        b_c2 = tf.Variable(tf.random_normal([64], stddev=b_alpha))
        conv2 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(conv1, w_c2, strides=[1, 1, 1, 1], padding='SAME'), b_c2))  
        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)
       
        w_c3 = tf.Variable(tf.random_normal([3, 3, 64, 64], stddev=w_alpha))
        b_c3 = tf.Variable(tf.random_normal([64], stddev=b_alpha))
        conv3 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(conv2, w_c3, strides=[1, 1, 1, 1], padding='SAME'), b_c3))  
        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)
    
        
        w_d = tf.Variable(tf.random_normal([8*32*40, 1024], stddev=w_alpha))
        b_d = tf.Variable(tf.random_normal([1024], stddev=b_alpha))
        dense = tf.reshape(conv3, [-1, w_d.get_shape().as_list()[0]])  
        dense = tf.nn.relu(tf.add(tf.matmul(dense, w_d), b_d))  
        dense = tf.nn.dropout(dense, keep_prob)
       
        w_out = tf.Variable(tf.random_normal([1024, MAX_CAPTCHA*CHAR_SET_LEN], stddev=w_alpha))
        b_out = tf.Variable(tf.random_normal([MAX_CAPTCHA*CHAR_SET_LEN], stddev=b_alpha))
        out = tf.add(tf.matmul(dense, w_out), b_out)
        return out
    

    五、网络构建好了,现在需要构建损失函数,以及准确率等等,并开始训练了。具体代码如下:

    def train_crack_captcha_cnn():  
        output = crack_captcha_cnn()  
        # loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(output, Y))  
        loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=output, labels=Y))
        # 最后一层用来分类的softmax和sigmoid,可以自己选择
        # optimizer 为了加快训练 learning_rate应该开始大,然后慢慢衰
        optimizer = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)
    
        predict = tf.reshape(output, [-1, MAX_CAPTCHA, CHAR_SET_LEN])
        max_idx_p = tf.argmax(predict, 2)
        max_idx_l = tf.argmax(tf.reshape(Y, [-1, MAX_CAPTCHA, CHAR_SET_LEN]), 2)
        correct_pred = tf.equal(max_idx_p, max_idx_l)
        accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
    
        saver = tf.train.Saver()
        with tf.Session() as sess:
            sess.run(tf.global_variables_initializer())
    
            step = 0
            while True:
                batch_x, batch_y = get_next_batch(64)
                sess.run(optimizer, feed_dict={X: batch_x, Y: batch_y, keep_prob: 0.8})
                # 每10 step计算一次准确率
                if step % 10 == 0:
                    batch_x_test, batch_y_test = get_next_batch(100)
                    acc, loss_ = sess.run([accuracy, loss], feed_dict={X: batch_x_test, Y: batch_y_test, keep_prob: 0.8})
                    print(step, loss_, acc)
                    saver.save(sess, "./model/crack_capcha1.model", global_step=step)
                    # 如果准确率大于90%,保存模型,完成训练
                    if acc > 0.9:
                        saver.save(sess, "./model/crack_capcha.model", global_step=step)
                        break
                step += 1
    

    整个结构基本就是这样,如果只采用数字集的话,基本一千次迭代,半小时左右,准确率就能到90%以上。如果采用数字加大小写字母,时间会稍微久一点。下面是完整的代码:

    import tensorflow as tf
    from captcha.image import ImageCaptcha
    import numpy as np
    from PIL import Image
    import random
    
    number = ['0','1','2','3','4','5','6','7','8','9']
    alphabet = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
    ALPHABET = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
    
    # 传入数据集,从数据集中随机选择四个元素,然后返回这四个元素
    # def random_captcha_text(char_set=number+alphabet+ALPHABET, captcha_size=4):
    def random_captcha_text(char_set=number, captcha_size=4):
        captcha_text = []
        for i in range(captcha_size):
            c = random.choice(char_set)
            captcha_text.append(c)
        return captcha_text
    
    # 生成验证码图片,返回图片转化后的numpy数组,以及验证码字符文本
    def gen_captcha_text_and_image():
        image = ImageCaptcha()
        captcha_text = random_captcha_text()
        captcha_text = ''.join(captcha_text)
        captcha = image.generate(captcha_text)
        # image.write(captcha_text, captcha_text + '.jpg')  # 将图片保存到硬盘
        captcha_image = Image.open(captcha)
        captcha_image = captcha_image.convert('L')
        captcha_image = captcha_image.point(lambda i: 255 - i)
        # 将图片取反,黑色变为白色,白色变为黑色,这样模型收敛更块
        captcha_image = np.array(captcha_image)
        return captcha_text, captcha_image
    
    def text2vec(text):
        text_len = len(text)
        if text_len > MAX_CAPTCHA:
            raise ValueError('验证码最长4个字符')
        vector = np.zeros(MAX_CAPTCHA*CHAR_SET_LEN)
        def char2pos(c):
            if c =='_':
                k = 62
                return k
            k = ord(c)-48
            if k > 9:
                k = ord(c) - 55
                if k > 35:
                    k = ord(c) - 61
                    if k > 61:
                        raise ValueError('No Map')
            return k
        for i, c in enumerate(text):
            idx = i * CHAR_SET_LEN + char2pos(c)
            vector[idx] = 1
        return vector
    
    
    def get_next_batch(batch_size=64):
        batch_x = np.zeros([batch_size, IMAGE_HEIGHT * IMAGE_WIDTH])
        batch_y = np.zeros([batch_size, MAX_CAPTCHA * CHAR_SET_LEN])
    
        for i in range(batch_size):
            text, image = gen_captcha_text_and_image()
            batch_x[i, :] = image.flatten()  # 将二维数组拉平为一维
            batch_y[i, :] = text2vec(text)
    
        return batch_x, batch_y
    
    
    def crack_captcha_cnn(w_alpha=0.01, b_alpha=0.1):
        x = tf.reshape(X, shape=[-1, IMAGE_HEIGHT, IMAGE_WIDTH, 1])
    
        w_c1 = tf.Variable(tf.random_normal([3, 3, 1, 32], stddev=w_alpha))
        b_c1 = tf.Variable(tf.random_normal([32], stddev=b_alpha))
        conv1 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(x, w_c1, strides=[1, 1, 1, 1], padding='SAME'), b_c1))
        conv1 = tf.nn.max_pool(conv1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
        conv1 = tf.nn.dropout(conv1, keep_prob)
    
        w_c2 = tf.Variable(tf.random_normal([3, 3, 32, 64], stddev=w_alpha))
        b_c2 = tf.Variable(tf.random_normal([64], stddev=b_alpha))
        conv2 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(conv1, w_c2, strides=[1, 1, 1, 1], padding='SAME'), b_c2))
        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)
    
        w_c3 = tf.Variable(tf.random_normal([3, 3, 64, 64], stddev=w_alpha))
        b_c3 = tf.Variable(tf.random_normal([64], stddev=b_alpha))
        conv3 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(conv2, w_c3, strides=[1, 1, 1, 1], padding='SAME'), b_c3))
        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)
    
        w_d = tf.Variable(tf.random_normal([8 * 32 * 40, 1024], stddev=w_alpha))
        b_d = tf.Variable(tf.random_normal([1024], stddev=b_alpha))
        dense = tf.reshape(conv3, [-1, w_d.get_shape().as_list()[0]])
        dense = tf.nn.relu(tf.add(tf.matmul(dense, w_d), b_d))
        dense = tf.nn.dropout(dense, keep_prob)
    
        w_out = tf.Variable(tf.random_normal([1024, MAX_CAPTCHA * CHAR_SET_LEN], stddev=w_alpha))
        b_out = tf.Variable(tf.random_normal([MAX_CAPTCHA * CHAR_SET_LEN], stddev=b_alpha))
        out = tf.add(tf.matmul(dense, w_out), b_out)
        return out
    
    def train_crack_captcha_cnn():
        output = crack_captcha_cnn()
        # loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(output, Y))
        loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=output, labels=Y))
        # 最后一层用来分类的softmax和sigmoid,可以自己选择
        # optimizer 为了加快训练 learning_rate应该开始大,然后慢慢衰
        optimizer = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)
    
        predict = tf.reshape(output, [-1, MAX_CAPTCHA, CHAR_SET_LEN])
        max_idx_p = tf.argmax(predict, 2)
        max_idx_l = tf.argmax(tf.reshape(Y, [-1, MAX_CAPTCHA, CHAR_SET_LEN]), 2)
        correct_pred = tf.equal(max_idx_p, max_idx_l)
        accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
    
        saver = tf.train.Saver()
        with tf.Session() as sess:
            sess.run(tf.global_variables_initializer())
    
            step = 0
            while True:
                batch_x, batch_y = get_next_batch(64)
                sess.run(optimizer, feed_dict={X: batch_x, Y: batch_y, keep_prob: 0.8})
                # 每10 step计算一次准确率
                if step % 10 == 0:
                    batch_x_test, batch_y_test = get_next_batch(100)
                    acc, loss_ = sess.run([accuracy, loss], feed_dict={X: batch_x_test, Y: batch_y_test, keep_prob: 0.8})
                    print(step, loss_, acc)
                    saver.save(sess, "./model/crack_capcha1.model", global_step=step)
                    # 如果准确率大于90%,保存模型,完成训练
                    if acc > 0.9:
                        saver.save(sess, "./model/crack_capcha.model", global_step=step)
                        break
                step += 1
    
    
    if __name__ == '__main__':
    
        text, image = gen_captcha_text_and_image()
        print("验证码图像channel:", image.shape)  # (60, 160)
        # 图像大小
        IMAGE_HEIGHT = 60
        IMAGE_WIDTH = 160
        MAX_CAPTCHA = len(text)
        print("验证码文本字符数", MAX_CAPTCHA)
        # char_set = number + alphabet + ALPHABET
        char_set = number
        CHAR_SET_LEN = len(char_set)
    
        X = tf.placeholder(tf.float32, [None, IMAGE_HEIGHT * IMAGE_WIDTH])
        Y = tf.placeholder(tf.float32, [None, MAX_CAPTCHA * CHAR_SET_LEN])
        keep_prob = tf.placeholder(tf.float32)  # dropout
    
        train_crack_captcha_cnn()
    
    展开全文
  • lstm+ctc+cnn架构,进行不定长度验证码识别,达到不分割字符而识别验证码内容的效果。验证码内容包含了大小字母以及数字,并增加点、线、颜色、位置、字体等干扰项。本项目对gru +ctc+cnn
  • 我们使用卷积神经网络来实现验证码识别案列,具体流程如下: 1、使用python的captcha模块生成验证码图片。 2、使用tensorflow框架搭建神经网络模型。 3、将数据喂入搭建好的神经网络模型中。 4、保存训练好的网络...

    任务要求

    我们使用卷积神经网络来实现验证码识别案列,具体流程如下:

    1、使用python的captcha模块生成验证码图片。
    2、使用tensorflow框架搭建神经网络模型。
    3、将数据喂入搭建好的神经网络模型中。
    4、保存训练好的网络模型。

    下面我们来看具体的细节。
    一、定义字符集,验证码一般为数字、字母。练习的时候可以先只考虑数字的情况,这样模型训练的会快些。代码如下:

    number = ['0','1','2','3','4','5','6','7','8','9']  
    alphabet = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']  
    ALPHABET = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']  
    

    二、下面我们要从给定的字符集中选择4个字符,生成160*60的验证码图片,并将图片转化为numpy数组。然后将选择的四个字符生成为词向量形式。
    1、生成图片并转化为数组。

    def random_captcha_text(char_set=number+alphabet+ALPHABET, captcha_size=4):  
        captcha_text = []  
        for i in range(captcha_size):  
            c = random.choice(char_set)  
            captcha_text.append(c)  
        return captcha_text
    
    
    def gen_captcha_text_and_image():  
        image = ImageCaptcha()  
       
        captcha_text = random_captcha_text()  
        captcha_text = ''.join(captcha_text)  
       
        captcha = image.generate(captcha_text)  
        #image.write(captcha_text, captcha_text + '.jpg')   
       
        captcha_image = Image.open(captcha)
        captcha_image = captcha_image.convert('L')
        captcha_image = captcha_image.point(lambda i: 255 - i)
        #将图片取反,黑色变为白色,白色变为黑色,这样模型收敛更快
        captcha_image = np.array(captcha_image)
        return captcha_text, captcha_image
    

    2、传入验证码文本,转化为词向量的形式,假设我们现在只使用数字集0-9。那么就是10分类,我们用一个长度为10的向量来表示一个数字,比如[1, 0, 0, 0, 0, 0, 0, 0, 0, 0]表示数字0,[0, 1, 0, 0, 0, 0, 0, 0, 0, 0]表示数字1。我们有四个字符,所以是一个410的矩阵,再将这个矩阵拉平为一维的,就是长度为40的向量。
    如果我们现在采用数字加大小写字母为字符集,那就是4
    (10+26+26),再将矩阵拉平,就是长度为248的向量。代码如下:

    def text2vec(text):  
        text_len = len(text)  
        if text_len > MAX_CAPTCHA:  
            raise ValueError('验证码最长4个字符')  
       
        vector = np.zeros(MAX_CAPTCHA*CHAR_SET_LEN)  
        def char2pos(c):  
            if c =='_':  
                k = 62  
                return k  
            k = ord(c)-48  
            if k > 9:  
                k = ord(c) - 55  
                if k > 35:  
                    k = ord(c) - 61  
                    if k > 61:  
                        raise ValueError('No Map')   
            return k  
        for i, c in enumerate(text):  
            idx = i * CHAR_SET_LEN + char2pos(c)  
            vector[idx] = 1  
        return vector 
    

    三、以上代码每次只生成一张验证码,当然每次传入网络一个样本也可以,但我们习惯一次喂入多个样本,所以我们还要一次性生成多张图片传入网络。代码如下。

    # 生成一个训练batch  
    def get_next_batch(batch_size=128):  
        batch_x = np.zeros([batch_size, IMAGE_HEIGHT*IMAGE_WIDTH])  
        batch_y = np.zeros([batch_size, MAX_CAPTCHA*CHAR_SET_LEN])  
       
        # 有时生成图像大小不是(60, 160, 3)  
        def wrap_gen_captcha_text_and_image():  
            while True:  
                text, image = gen_captcha_text_and_image()  
                if image.shape == (60, 160, 3):  
                    return text, image  
       
        for i in range(batch_size):  
            text, image = wrap_gen_captcha_text_and_image()  
            image = convert2gray(image)  
       
            batch_x[i,:] = image.flatten() / 255 # (image.flatten()-128)/128  mean为0  
            batch_y[i,:] = text2vec(text)  
       
        return batch_x, batch_y  
    
    def convert2gray(img):  
        if len(img.shape) > 2:  
            gray = np.mean(img, -1)  
            # 上面的转法较快,正规转法如下  
            # r, g, b = img[:,:,0], img[:,:,1], img[:,:,2]  
            # gray = 0.2989 * r + 0.5870 * g + 0.1140 * b  
            return gray  
        else:  
            return img  
    

    四、现在图片生成好了,对应的词向量也生成好了,要开始搭建网络了,我们采用三层卷积,一层全连接层,最后输出成,代码如下:

    # 定义CNN
    def crack_captcha_cnn(w_alpha=0.01, b_alpha=0.1):  
        x = tf.reshape(X, shape=[-1, IMAGE_HEIGHT, IMAGE_WIDTH, 1])  
       
        #w_c1_alpha = np.sqrt(2.0/(IMAGE_HEIGHT*IMAGE_WIDTH)) #  
        #w_c2_alpha = np.sqrt(2.0/(3*3*32))   
        #w_c3_alpha = np.sqrt(2.0/(3*3*64))   
        #w_d1_alpha = np.sqrt(2.0/(8*32*64))  
        #out_alpha = np.sqrt(2.0/1024)  
       
        # 3 conv layer  
        w_c1 = tf.Variable(w_alpha*tf.random_normal([3, 3, 1, 32]))  
        b_c1 = tf.Variable(b_alpha*tf.random_normal([32]))  
        conv1 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(x, w_c1, strides=[1, 1, 1, 1], padding='SAME'), b_c1))  
        conv1 = tf.nn.max_pool(conv1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')  
        conv1 = tf.nn.dropout(conv1, keep_prob)  
       
        w_c2 = tf.Variable(w_alpha*tf.random_normal([3, 3, 32, 64]))  
        b_c2 = tf.Variable(b_alpha*tf.random_normal([64]))  
        conv2 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(conv1, w_c2, strides=[1, 1, 1, 1], padding='SAME'), b_c2))  
        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)  
       
        w_c3 = tf.Variable(w_alpha*tf.random_normal([3, 3, 64, 64]))  
        b_c3 = tf.Variable(b_alpha*tf.random_normal([64]))  
        conv3 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(conv2, w_c3, strides=[1, 1, 1, 1], padding='SAME'), b_c3))  
        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)
    
        # Fully connected layer  
        w_d = tf.Variable(w_alpha*tf.random_normal([8*32*40, 1024]))  
        b_d = tf.Variable(b_alpha*tf.random_normal([1024]))  
        dense = tf.reshape(conv3, [-1, w_d.get_shape().as_list()[0]])  
        dense = tf.nn.relu(tf.add(tf.matmul(dense, w_d), b_d))  
        dense = tf.nn.dropout(dense, keep_prob)  
       
        w_out = tf.Variable(w_alpha*tf.random_normal([1024, MAX_CAPTCHA*CHAR_SET_LEN]))  
        b_out = tf.Variable(b_alpha*tf.random_normal([MAX_CAPTCHA*CHAR_SET_LEN]))  
        out = tf.add(tf.matmul(dense, w_out), b_out)  
        #out = tf.nn.softmax(out)  
        return out  
    

    五、网络构建好了,现在需要构建损失函数,以及准确率等等,并开始训练了。具体代码如下:

    # 训练  
    def train_crack_captcha_cnn():  
        output = crack_captcha_cnn()  
        # loss  
        #loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(output, Y))  
        loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(output, Y))  
            # 最后一层用来分类的softmax和sigmoid有什么不同?  
        # optimizer 为了加快训练 learning_rate应该开始大,然后慢慢衰  
        optimizer = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)  
       
        predict = tf.reshape(output, [-1, MAX_CAPTCHA, CHAR_SET_LEN])  
        max_idx_p = tf.argmax(predict, 2)  
        max_idx_l = tf.argmax(tf.reshape(Y, [-1, MAX_CAPTCHA, CHAR_SET_LEN]), 2)  
        correct_pred = tf.equal(max_idx_p, max_idx_l)  
        accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))  
    
        saver = tf.train.Saver()  
        with tf.Session() as sess:  
            sess.run(tf.global_variables_initializer())  
       
            step = 0  
            while True:  
                batch_x, batch_y = get_next_batch(64)  
                _, loss_ = sess.run([optimizer, loss], feed_dict={X: batch_x, Y: batch_y, keep_prob: 0.75})  
                print(step, loss_)  
                  
                # 每100 step计算一次准确率  
                if step % 10 == 0:  
                    batch_x_test, batch_y_test = get_next_batch(100)
                    acc = sess.run(accuracy, feed_dict={X: batch_x_test, Y: batch_y_test, keep_prob: 1.})  
                    print(step, acc)  
                    # 如果准确率大于50%,保存模型,完成训练  
                    if acc > 0.50:  
                        saver.save(sess, "./model/crack_capcha.model", global_step=step)  
                        break
    
                step += 1
    

    整个结构基本就是这样,如果只采用数字集的话,基本一千次迭代,半小时左右,准确率就能到90%以上。如果采用数字加大小写字母,时间会稍微久一点。下面是完整的代码:

    import numpy as np  
    import tensorflow as tf
    from captcha.image import ImageCaptcha
    import numpy as np  
    import matplotlib.pyplot as plt  
    from PIL import Image  
    import random   
    
    number = ['0','1','2','3','4','5','6','7','8','9']  
    #alphabet = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']  
    #ALPHABET = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']  
    
    #def random_captcha_text(char_set=number+alphabet+ALPHABET, captcha_size=4):  
    def random_captcha_text(char_set=number, captcha_size=4):
        captcha_text = []
        for i in range(captcha_size):  
            c = random.choice(char_set)  
            captcha_text.append(c)  
        return captcha_text  
       
    
    def gen_captcha_text_and_image():  
        image = ImageCaptcha()  
       
        captcha_text = random_captcha_text()  
        captcha_text = ''.join(captcha_text)  
       
        captcha = image.generate(captcha_text)  
        #image.write(captcha_text, captcha_text + '.jpg')   
       
        captcha_image = Image.open(captcha)  
        captcha_image = np.array(captcha_image)  
        return captcha_text, captcha_image  
    
    def convert2gray(img):  
        if len(img.shape) > 2:  
            gray = np.mean(img, -1)  
            # 上面的转法较快,正规转法如下  
            # r, g, b = img[:,:,0], img[:,:,1], img[:,:,2]  
            # gray = 0.2989 * r + 0.5870 * g + 0.1140 * b  
            return gray  
        else:  
            return img  
    
       
      
    def text2vec(text):  
        text_len = len(text)  
        if text_len > MAX_CAPTCHA:  
            raise ValueError('验证码最长4个字符')  
       
        vector = np.zeros(MAX_CAPTCHA*CHAR_SET_LEN)  
    
        def char2pos(c):  
            if c =='_':  
                k = 62  
                return k  
            k = ord(c)-48  
            if k > 9:  
                k = ord(c) - 55  
                if k > 35:  
                    k = ord(c) - 61  
                    if k > 61:  
                        raise ValueError('No Map')   
            return k  
    
        for i, c in enumerate(text):  
            idx = i * CHAR_SET_LEN + int(c)  
            vector[idx] = 1  
        return vector
    
    
    # 传入验证码字符文本,生成对应的词向量
    # def text2vec(text):
    #     text_len = len(text)
    #     if text_len > MAX_CAPTCHA:
    #         raise ValueError('验证码最长4个字符')
    #     vector = np.zeros(MAX_CAPTCHA*CHAR_SET_LEN)
    #     def char2pos(c):
    #         if c =='_':
    #             k = 62
    #             return k
    #         k = ord(c)-48
    #         if k > 9:
    #             k = ord(c) - 55
    #             if k > 35:
    #                 k = ord(c) - 61
    #                 if k > 61:
    #                     raise ValueError('No Map')
    #         return k
    #     for i, c in enumerate(text):
    #         idx = i * CHAR_SET_LEN + char2pos(c)
    #         vector[idx] = 1
    #     return vector
    
    
    
    # 向量转回文本  
    def vec2text(vec):  
        """
        char_pos = vec.nonzero()[0]  
        text=[]  
        for i, c in enumerate(char_pos):  
            char_at_pos = i #c/63  
            char_idx = c % CHAR_SET_LEN  
            if char_idx < 10:  
                char_code = char_idx + ord('0')  
            elif char_idx <36:  
                char_code = char_idx - 10 + ord('A')  
            elif char_idx < 62:  
                char_code = char_idx-  36 + ord('a')  
            elif char_idx == 62:  
                char_code = ord('_')  
            else:  
                raise ValueError('error')  
            text.append(chr(char_code)) 
        """
        text=[]
        char_pos = vec.nonzero()[0]
        for i, c in enumerate(char_pos):  
            number = i % 10
            text.append(str(number)) 
                 
        return "".join(text)  
       
    """ 
    #向量(大小MAX_CAPTCHA*CHAR_SET_LEN)用0,1编码 每63个编码一个字符,这样顺利有,字符也有 
    vec = text2vec("F5Sd") 
    text = vec2text(vec) 
    print(text)  # F5Sd 
    vec = text2vec("SFd5") 
    text = vec2text(vec) 
    print(text)  # SFd5 
    """  
       
    # 生成一个训练batch  
    def get_next_batch(batch_size=128):  
        batch_x = np.zeros([batch_size, IMAGE_HEIGHT*IMAGE_WIDTH])  
        batch_y = np.zeros([batch_size, MAX_CAPTCHA*CHAR_SET_LEN])  
       
        # 有时生成图像大小不是(60, 160, 3)  
        def wrap_gen_captcha_text_and_image():  
            while True:  
                text, image = gen_captcha_text_and_image()  
                if image.shape == (60, 160, 3):  
                    return text, image  
       
        for i in range(batch_size):  
            text, image = wrap_gen_captcha_text_and_image()  
            image = convert2gray(image)  
    
            #将二维数组拉成一维数组
            batch_x[i,:] = image.flatten() / 255 # (image.flatten()-128)/128  mean为0  
            batch_y[i,:] = text2vec(text)  
       
        return batch_x, batch_y  
       
    
       
    # 定义CNN ,这里使用三层卷积和一层全连接操作,最后输出
    def crack_captcha_cnn(w_alpha=0.01, b_alpha=0.1):  
        x = tf.reshape(X, shape=[-1, IMAGE_HEIGHT, IMAGE_WIDTH, 1])  
       
        #w_c1_alpha = np.sqrt(2.0/(IMAGE_HEIGHT*IMAGE_WIDTH)) #  
        #w_c2_alpha = np.sqrt(2.0/(3*3*32))   
        #w_c3_alpha = np.sqrt(2.0/(3*3*64))   
        #w_d1_alpha = np.sqrt(2.0/(8*32*64))  
        #out_alpha = np.sqrt(2.0/1024)  
       
        # 3 conv layer  
        w_c1 = tf.Variable(w_alpha*tf.random_normal([3, 3, 1, 32]))  
        b_c1 = tf.Variable(b_alpha*tf.random_normal([32]))  
        conv1 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(x, w_c1, strides=[1, 1, 1, 1], padding='SAME'), b_c1))  
        conv1 = tf.nn.max_pool(conv1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')  
        conv1 = tf.nn.dropout(conv1, keep_prob)  
       
        w_c2 = tf.Variable(w_alpha*tf.random_normal([3, 3, 32, 64]))  
        b_c2 = tf.Variable(b_alpha*tf.random_normal([64]))  
        conv2 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(conv1, w_c2, strides=[1, 1, 1, 1], padding='SAME'), b_c2))  
        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)  
       
        w_c3 = tf.Variable(w_alpha*tf.random_normal([3, 3, 64, 64]))  
        b_c3 = tf.Variable(b_alpha*tf.random_normal([64]))  
        conv3 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(conv2, w_c3, strides=[1, 1, 1, 1], padding='SAME'), b_c3))  
        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)  
       
        # Fully connected layer  
        w_d = tf.Variable(w_alpha*tf.random_normal([8*20*64, 1024]))  
        b_d = tf.Variable(b_alpha*tf.random_normal([1024]))  
        dense = tf.reshape(conv3, [-1, w_d.get_shape().as_list()[0]])  
        dense = tf.nn.relu(tf.add(tf.matmul(dense, w_d), b_d))  
        dense = tf.nn.dropout(dense, keep_prob)  
       
        w_out = tf.Variable(w_alpha*tf.random_normal([1024, MAX_CAPTCHA*CHAR_SET_LEN]))  
        b_out = tf.Variable(b_alpha*tf.random_normal([MAX_CAPTCHA*CHAR_SET_LEN]))  
        out = tf.add(tf.matmul(dense, w_out), b_out)   
        return out  
       
    # 网络搭建好之后需要构建损失函数,以及准确率,并开始训练
    def train_crack_captcha_cnn():  
        output = crack_captcha_cnn()  
        loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(output, Y))  
        optimizer = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)  
        predict = tf.reshape(output, [-1, MAX_CAPTCHA, CHAR_SET_LEN])  
        max_idx_p = tf.argmax(predict, 2)  
        max_idx_l = tf.argmax(tf.reshape(Y, [-1, MAX_CAPTCHA, CHAR_SET_LEN]), 2)  
        correct_pred = tf.equal(max_idx_p, max_idx_l)  
        accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))  
       
        saver = tf.train.Saver()  
        with tf.Session() as sess:  
            sess.run(tf.global_variables_initializer())  
       
            step = 0  
            while True:  
                batch_x, batch_y = get_next_batch(64)  
                _, loss_ = sess.run([optimizer, loss], feed_dict={X: batch_x, Y: batch_y, keep_prob: 0.75})  
                print(step, loss_)  
                  
                # 每100 step计算一次准确率  
                if step % 10 == 0:  
                    batch_x_test, batch_y_test = get_next_batch(100)  
                    acc = sess.run(accuracy, feed_dict={X: batch_x_test, Y: batch_y_test, keep_prob: 1.})  
                    print(step, acc)  
                    # 如果准确率大于50%,保存模型,完成训练  
                    if acc > 0.50:  
                        saver.save(sess, "./model/crack_capcha.model", global_step=step)  
                        break  
       
                step += 1
    
    def crack_captcha(captcha_image):  
        output = crack_captcha_cnn()  
       
        saver = tf.train.Saver()  
        with tf.Session() as sess:  
            saver.restore(sess, "./model/crack_capcha.model-810") 
       
            predict = tf.argmax(tf.reshape(output, [-1, MAX_CAPTCHA, CHAR_SET_LEN]), 2)  
            text_list = sess.run(predict, feed_dict={X: [captcha_image], keep_prob: 1})  
            text = text_list[0].tolist()  
            return text
    
    
    if __name__ == '__main__':
        train = 1
        if train == 0:
            number = ['0','1','2','3','4','5','6','7','8','9']  
            #alphabet = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
            #ALPHABET = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
            
            text, image = gen_captcha_text_and_image()  
            print("验证码图像channel:", image.shape)  # (60, 160, 3)  
            # 图像大小  
            IMAGE_HEIGHT = 60  
            IMAGE_WIDTH = 160  
            MAX_CAPTCHA = len(text)  
            print("验证码文本最长字符数", MAX_CAPTCHA)
            # 文本转向量  
            #char_set = number + alphabet + ALPHABET + ['_']  # 如果验证码长度小于4, '_'用来补齐  
            char_set = number
            CHAR_SET_LEN = len(char_set)
            
            X = tf.placeholder(tf.float32, [None, IMAGE_HEIGHT*IMAGE_WIDTH])  
            Y = tf.placeholder(tf.float32, [None, MAX_CAPTCHA*CHAR_SET_LEN])  
            keep_prob = tf.placeholder(tf.float32) # dropout 
            
            train_crack_captcha_cnn()
        if train == 1:
            number = ['0','1','2','3','4','5','6','7','8','9']  
            IMAGE_HEIGHT = 60  
            IMAGE_WIDTH = 160  
            char_set = number
            CHAR_SET_LEN = len(char_set)
            
            
         
            text, image = gen_captcha_text_and_image()  
            
            
            f = plt.figure()  
            ax = f.add_subplot(111)  
            ax.text(0.1, 0.9,text, ha='center', va='center', transform=ax.transAxes)  
            plt.imshow(image)  
           
            plt.show()  
            
            MAX_CAPTCHA = len(text)
            image = convert2gray(image)  
            image = image.flatten() / 255  
            
            X = tf.placeholder(tf.float32, [None, IMAGE_HEIGHT*IMAGE_WIDTH])  
            Y = tf.placeholder(tf.float32, [None, MAX_CAPTCHA*CHAR_SET_LEN])  
            keep_prob = tf.placeholder(tf.float32) # dropout 
            
            predict_text = crack_captcha(image)  
            print("正确: {}  预测: {}".format(text, predict_text))  
           
    
    展开全文
  • 最近做一个小玩意需要识别验证码,之前从来没有接触过识别验证码这块,这可难倒了我。所以,在网上搜索如何识别验证码,许多前辈写的博文教会了我。怕以后又忘记了,故此写篇随笔记录。 我要识别验证码是一种非常...
  • CNN识别验证码的实用教程, tensorflow captcha ...本文举例的对象(为某银行的微信服务用的,下载训练集,本文代码): 为什么搞爬虫的时候要自己弄验证码识别?1,省钱,打码的市场价是1分一枚,1万个码就是100...

    用CNN识别验证码的实用教程, tensorflow captcha recognization practical tutorial

    本文重在实用,让你半天能搞定验证码的识别,包括从训练材料的获取、预处理和训练,以及predict服务器的搭建。

    本文举例的对象(为某银行的微信服务用的,下载训练集,本文代码):

    为什么搞爬虫的时候要自己弄验证码识别?

    1,省钱,打码的市场价是1分一枚,1万个码就是100块钱,如果一天10万码,那么一个月就要3W。

    2,更快更可靠,打码平台经常互相掐架时常DOS,而且一个码要3秒-10秒不等,如果是凌晨时间,就更慢了。如果自己识别了,基本0.1秒识别一枚,能够加快爬虫的速度。

    训练材料的获取

    到底需要多少标记好的材料?

    这和验证码的形态和预处理的方式有关,按本文举例的验证码、采用分割的预处理下,5000个能达到95+。我们实用8000枚的材料,最后能够得到97.5%的正确率。(注意,本事训练材料也是有错误的,包括测试数据,所以98%左右已经是极限了)下面给个基本的量级参考:

    4位数字+分割=800

    4位数字字母+分割=5000

    4位数字字母+整体=20000

    如何给训练材料打标记呢?

    方法1,自己标注

    3秒一个,5000枚,半天搞定。多分几个人的话,一小时搞定。

    方法2,打码平台(推荐)

    1分钱-2分钱一枚,5000枚只要50块钱,包括写脚本时间,估计一小时。推荐这种方法,花钱节约时间。

    方法3,找到对方的验证码的生成器

    很多平台生成验证码的时候一般都是找一个第三方的库来生成的,如果你也能找到对应的,那就OK了。

    方法4,模拟对方的验证码生成器

    如果模拟的不对,那就白忙活了。这其中包括正确的字体、干扰的线条、色彩等,对复杂点的验证码,基本是不可能1小时内能搞定的。有一个通用的思路是用类似prisma的样式迁移,但这就很费力了。

    我选择方法2,用打码平台花了50块钱,搞了1W个label的码(新用户从50送50),花了差不多1个小时。

    分割预处理

    分割预处理,就是把4位的验证码分割开来。像这样:

    那为什么要分割呢?

    分割的好处是,能够降低模型的复杂度,分割后,模型就只要能够识别当个字符就可以了。这就导致:

    1,那么需要的训练材料的量也相应变少了,同时一个sample也能产生4个训练材料,正反一下,需要标记的材料的量就降了很多。

    2,我们可以使用更简单的CNN网络了,训练时间也更快(不需要GPU也能在半小时内训练完)

    什么时候不分割呢?

    👆上图这种,都还是很简单的就可以分割的,但像下面这种(Google的)

    👇,变形拥挤在一起的就很难分割了。(也说明了什么样的验证码才是好的验证码)

    分不了就别分了,整体训练,也算是发挥CNN能力的时候。

    我做了分割,代码是pre.py,一小时差不多了。至此,我们训练材料准备就绪了,还剩下4小时。

    搭CNN网络

    选择一个合适的

    有很多现成的网络啊,有名的alexNet,googleNet,resNet都可以做图像分类,那我们用哪个呢,MnistNet!!就是那个分类lecun的手写数字的小网。

    直观的讲,原来是0-9十个类别的手写数字变形大、和我们数字+字母共35分类但因为是非手写的,所以容量上在一个等级。

    修改MnistNet

    我们啥都不用改,就只要改下最后一层的分类数量就行啦,从10改成10+26。(见deyzm.py)

    # Logits layer

    # Input Tensor Shape: [batch_size, 1024]

    # Output Tensor Shape: [batch_size, 10+26]

    logits = tf.layers.dense(inputs=dropout, units=10+26) #改成我们的分类数目

    改一行代码,用时30分钟够了吧。剩下3.5小时,得快点了。

    训练

    先要修改下数据加载部分

    这里我们要修改下数据输入部分,因为原来的Mnist的材料是一个二进制的文件,而我们要直接从图片中读训练数据和labels,加载后的数据格式和原MnistNet的输入一模一样,咱们的加载代码(详见deyzm.py中的load_data_set)

    def load_data_set(fn_labels):

    print('loading... ', fn_labels)

    with open(fn_labels, 'r') as fp_label:

    ll = fp_label.readlines()

    labels = [c2i(l.split(',')[1].strip()) for l in ll ]

    labels = np.array(labels)

    print(labels.shape, labels)

    data = []

    for i, line in enumerate(ll):

    if i%1000==0:

    print('{}/{}'.format(i, len(ll)))

    line = line.strip()

    ww = line.split(',')

    data.append(read_as_array(ww[0]))

    data = np.array(data)

    data = data.reshape((-1,28*28))

    return data, labels

    numpy没用过同学,快去看下numpy的数据处理5分钟就能理解。numpy快速教程

    开始训练

    改一个参数,节约时间

    mnist_classifier.train(

    input_fn=train_input_fn,

    steps=5000, #原20000,实际本例到4000,loss就到底了

    hooks=[])

    启动

    python deyzm.py

    启动的时候,loss在3.5,而且降的很慢。

    大概在2000+step的时候,loss开始打降了,最后5000step的时候完成训练。在测试集下面能够有95%的正确率。

    尝试跑到2W,虽然loss低了很多,但准确率没什么提高(因为训练和测试集合本身有2%的人工标注错误)

    训练结束,用时1小时(按5000step算,实际i7 4核在30分钟就跑完),没想到CPU训练这么快。剩下2.5小时。

    把predict做出http服务

    服务器上有10个进程都要用这个验证码识别,做个http服务来响应所有的请求吧。详见web_server.py。

    用时10分钟,最后我们提前完成了任务,可喜可贺可喜可贺,多出来的2.35小时玩点什么不好呢,要写这个文?

    感想

    用CNN做验证码识别大材小用了,但也不失为一个方法啦,而且实际表现确实非常好。其能力的上下限也很大,既可以识别简单的,也可以识别超级复杂的,必须是爬虫工程师的必备技能~

    同时感慨下现在的anti-spaming越来越难做了,验证码如此,文字的的机器人回复评论已经和正常人回复没差别了,危矣。顿时发现,机器只要具备一点点智能+人类的滥用,就能杀伤力爆炸。纵使机器可能永远无法具有意识,但这已经不是重点了,危险已经降临!

    参考

    验证码识别群625706505

    展开全文
  • Tensorflow是目前最流行的深度学习框架,我们可以用它来搭建自己的卷积神经网络并训练自己的分类器,本文介绍怎样使用Tensorflow构建自己的CNN,怎样训练用于简单的验证码识别的分类器。本文假设你已经安装好了...
  • ​整个项目代码分为三部分:Generrate_Captcha:生成验证码图片(训练集,验证集和测试集);读取图片数据和标签(标签即为图片文件名);cnn_model:卷积神经网络;driver:模型训练及评估。1、配置项class Config(object)...

    ​整个项目代码分为三部分:Generrate_Captcha:

    生成验证码图片(训练集,验证集和测试集);

    读取图片数据和标签(标签即为图片文件名);cnn_model:卷积神经网络;

    driver:模型训练及评估。

    1、配置项

    class Config(object):

    width = 160 # 验证码图片的宽

    height = 60 # 验证码图片的高

    char_num = 4 # 验证码字符个数

    characters = range(10) # 数字[0,9]

    test_folder = 'test' # 测试集文件夹,下同

    train_folder = 'train'

    validation_folder = 'validation'

    tensorboard_folder = 'tensorboard' # tensorboard的log路径

    generate_num = (5000, 500, 500) # 训练集,验证集和测试集数量

    alpha = 1e-3 # 学习率

    Epoch = 100 # 训练轮次

    batch_size = 64 # 批次数量

    keep_prob = 0.5 # dropout比例

    print_per_batch = 20 # 每多少次输出结果

    save_per_batch = 20 # 每多少次写入tensorboard

    2、生成验证码(class Generate)

    验证码图片示例:

    0478

    check_path():检查文件夹是否存在,如不存在则创建。

    gen_captcha():生成验证码方法,写入之前检查是否以存在,如存在重新生成。

    3、读取数据(classs ReadData)

    read_data():返回图片数组(numpy.array格式)和标签(即文件名); label2vec():将文件名转为向量; 例:

    label = '1327'

    label_vec = [0,1,0,0,0,0,0,0,0,0,

    0,0,0,1,0,0,0,0,0,0,

    0,0,1,0,0,0,0,0,0,0,

    0,0,0,0,0,0,0,1,0,0]

    load_data():加载文件夹下所有图片,返回图片数组,标签和图片数量。

    4、定义模型(cnn_model)

    采用三层卷积,filter_size均为5,为避免过拟合,每层卷积后面均接dropout操作,最终将的图像转为的矩阵。

    大致结构如下:模型结构

    5、训练&评估next_batch():迭代器,分批次返还数据;

    feed_data():给模型“喂”数据;x:图像数组;

    y:图像标签;

    keep_prob:dropout比例;evaluate():模型评估,用于验证集和测试集。

    run_model():训练&评估

    6、目前效果

    目前经过4000次迭代训练集准确率可达99%以上,测试集准确率93%,还是存在一点过拟合,不过现在模型是基于CPU训练的,完成一次训练耗费时间大约4个小时左右,后续调整了再进行更新。

    Images for train :10000, for validation : 1000, for test : 1000

    Epoch : 1

    Step 0, train_acc: 7.42%, train_loss: 1.43, val_acc: 9.85%, val_loss: 1.40, improved:*

    Step 20, train_acc: 12.50%, train_loss: 0.46, val_acc: 10.35%, val_loss: 0.46, improved:*

    Step 40, train_acc: 9.38%, train_loss: 0.37, val_acc: 10.10%, val_loss: 0.37, improved:

    Step 60, train_acc: 7.42%, train_loss: 0.34, val_acc: 10.25%, val_loss: 0.34, improved:

    Step 80, train_acc: 7.81%, train_loss: 0.33, val_acc: 9.82%, val_loss: 0.33, improved:

    Step 100, train_acc: 12.11%, train_loss: 0.33, val_acc: 10.00%, val_loss: 0.33, improved:

    Step 120, train_acc: 9.77%, train_loss: 0.33, val_acc: 10.07%, val_loss: 0.33, improved:

    Step 140, train_acc: 8.98%, train_loss: 0.33, val_acc: 10.40%, val_loss: 0.33, improved:*

    Epoch : 2

    Step 160, train_acc: 8.20%, train_loss: 0.33, val_acc: 10.52%, val_loss: 0.33, improved:*

    ...

    Epoch : 51

    Step 7860, train_acc: 100.00%, train_loss: 0.01, val_acc: 92.37%, val_loss: 0.08, improved:

    Step 7880, train_acc: 99.61%, train_loss: 0.01, val_acc: 92.28%, val_loss: 0.08, improved:

    Step 7900, train_acc: 100.00%, train_loss: 0.01, val_acc: 92.42%, val_loss: 0.08, improved:

    Step 7920, train_acc: 100.00%, train_loss: 0.00, val_acc: 92.83%, val_loss: 0.08, improved:

    Step 7940, train_acc: 100.00%, train_loss: 0.01, val_acc: 92.77%, val_loss: 0.08, improved:

    Step 7960, train_acc: 100.00%, train_loss: 0.01, val_acc: 92.68%, val_loss: 0.08, improved:

    Step 7980, train_acc: 100.00%, train_loss: 0.00, val_acc: 92.63%, val_loss: 0.09, improved:

    No improvement for over 1000 steps, auto-stopping....

    Test accuracy: 93.00%, loss: 0.08

    7、Tensorboard

    每次训练之前将Tensorboard路径下的文件删除,不然趋势图上会凌乱。

    Accurracy

    loss

    原文链接及完整代码:​文源网络,仅供学习之用,如有侵权,联系删除。

    我将优质的技术文章和经验总结都汇集在了我的公众号【Python圈子】里,为方便大家学习,还整理了一套学习资料,免费提供给热爱Python的同学! 更有学习交流群,多交流问题才能更快进步~

    展开全文
  • 基于pytorch和CNN的图片验证码识别

    千次阅读 2020-06-19 20:31:41
    是一种区分用户是计算机还是人的公共全自动程序,本文利用新兴的深度学习框架PyTorch,并结合卷积神经网络(CNN)搭建的模型进行训练,对于收集到的由数字和字母(区分大小写)组成的复杂的图片验证码识别取得了...
  • 基于CNN验证码识别神经网络实现

    万次阅读 2017-08-23 19:58:38
    1、什么是CNN? 2、TensorFlow进阶 二、实战 1、验证码生成 import random import numpy as np from PIL import Image from captcha.image import ImageCaptcha NUMBER = ['0', '1', '2', '3', '4', '5', '6', '7'...
  • 【Matlab验证码识别】CNN验证码识别【含源码 098期】 二、matlab版本及参考文献 1 matlab版本 2014a 2 参考文献 [1] 蔡利梅.MATLAB图像处理——理论、算法与实例分析[M].清华大学出版社,2020. [2]杨丹,赵海滨,龙哲....
  • CNN识别验证码

    千次阅读 2018-09-26 20:41:56
    我们这里生成的验证码是当前最常见的验证码即由26位大小写英文字母和0到9十个数字组成的字符型验证码。 2.生成方式 我们可以选择两种方式来生成我们的训练数据。一种是一次性生成几万张图(保存到本地),另一种是...
  • 人工神经网络 基于CNN卷积神经网络 基于Python 实现图片验证码识别
  • 最近在极客时间学习Tensorflow教程,想写一篇博文来总结一下CNN识别验证码这个小项目 生成验证码 我们会引入captcha这个库来生成我们的验证码 这个库安装也很简单 直接使用pip install 安装即可 我们生成一个验证码...
  • 基于CNN的四位数字验证码识别

    千次阅读 多人点赞 2019-06-15 17:10:47
    前言 验证码技术作为一种反自动化技术,使得很多程序的自动化工作止步。今天作者采用一些数字图像处理... 验证码识别 一.图像预处理 接下来,我将一张验证码0250为例,使用python语言和依赖opencv来开展预处理 ...
  • 卷积神经网络验证码识别 深度学习大行其道的一个重要原因,是算力的提升,技术的进步允许我们每个人都自由地使用个人PC训练强大的神经网络。神经网络的强大能力有效地辅助了我们开发各类新式软件,举个例子,原本的...
  • 本文介绍了python使用tensorflow深度学习识别验证码 ,分享给大家,具体如下: 除了传统的PIL包处理图片,然后用pytessert+OCR识别意外,还可以使用tessorflow训练来识别验证码。 此篇代码大部分是转载的,只改了很少...
  • 作为一只入门的DL小白,在此总结了自己学习CNN识别验证码图片的心得。
  • 验证码识别问题通常验证码识别需要如下几个步骤:(1)将整张图片切割为多个小图片,每个小图片包含一个字符(2)训练模型,识别每个小图片中的字符(3)将每个小图片的识别出的字符拼接为字符串作为整体识别结果复杂一点...
  • 深度神经网络实现验证码识别 前段时间接到了一个小项目,要做一个验证码的识别,验证码包含数字和英文字母,实现识别的过程用到了CNN网络,最后单个字符的准确率达到90%以上。 准备数据集 登录界面有一个验证码的...
  • Tensorflow是目前最流行的深度学习框架,我们可以用它来搭建自己的卷积神经网络并训练自己的分类器,本文介绍怎样使用Tensorflow构建自己的CNN,怎样训练用于简单的验证码识别的分类器。本文假设你已经安装好了...
  • 本资源是 https://github.com/nickliqian/cnn_captcha 这个github项目的代码的一个实现,修改了一些参数,并把模型一同放出,(github项目中没有模型)
  • 利用深度学习(CNN)进行验证码(字母+数字)识别

    万次阅读 多人点赞 2019-10-27 23:09:38
    本文方法针对的验证码为定长验证码,不包含中文。 本文的思路是:1. 使用keras中预训练好的模型,在python生成的验证码(5万条)上fine tune,得到python验证码模型;2. 使用python验证码模型,在实际验证码(500条...
  • CNN卷积神经网络实现验证码识别(准确率达99%)

    万次阅读 多人点赞 2017-12-11 23:17:30
    基于python生成验证码,并用CNN进行训练识别验证码四位,如果由数字,小写字母,大写字母组成,那么cpu要跑很久很久,所以这里的验证码只包含了四位数字,一共有10*10*10*10个可能的数据。通过卷积神经模型,准确...
  • 验证码识别,文本识别网络-CRNN(CNN+GRU/LSTM+CTC) ,含部分数据集 请配合博客 https://blog.csdn.net/okfu_DL/article/details/90379583 使用
  • 本文介绍了一个便捷的验证码识别项目,读者可以借助它快速训练模型与识别验证码。本项目使用卷积神经网络识别字符型图片验证码,其基于 TensorFlow 框架。它封装了非常通用的校验、训练、验证、识别和调用 API,极大...
  • 针对登录界面验证码图像中字符,提出了一种基于卷积 神经网络(CNN)的验证码识别方法.先对验证码图像进行预处理得到单个字符,再对单 字符图像数据建立 CNN模型进行迭代训练.该方法针对 验证码图像特征,图像字符分割...
  • 北京 上海巡回站 | NVIDIA DLI深度学习培训2018年1月26/1月12日NVIDIA 深度学习学院 带你快速进入火热的DL领域阅读全文 >正文共2929个字,17张图,预计阅读时间:8分钟。...目前,在图像识别和视觉
  • 之前我们做了一个验证码识别逻辑回归案例,我们将使用该案例中的‘cut_number/’文件夹下的数据作为卷积网络的训练数据。 在使用这些数据之前,我们要对数据进行处理,以对应卷积网络要求的数据格式! 数据处理分为...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,050
精华内容 420
关键字:

cnn验证码识别代码