cnn卷积神经网络---验证码识别

验证码数据集下载 https://download.csdn.net/download/qq_42363032/12746911

在这里插入图片描述

类别处理—one-hot

验证码字符数是4个
转成one-hot编码是(1, 40)
为方便计算 转成(4, 10) 计算准确率方便找最大值索引

'''
验证码图片如1327,需要对类别标签进行one-hot编码转换
[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]
验证码4个数,对应40个onehot(1, 40), 转成(4, 10)方便计算
'''
def label2oneHot(lable):
    vec = numpy.zeros(40)
    for i, num in enumerate(lable):
        index = i * 10 + int(num)
        vec[index] = 1
    return vec

'''

灰度处理

对于验证码识别,彩色对于我们是没有用的,转成灰度图

def convert2gray(img):
    if img.shape[2] > 2:
        r, g, b = img[:, :, 0], img[:, :, 1], img[:, :, 2]
        gray = 0.2989 * r + 0.5872 * g + 0.1140 * b     # 这些小数加起来的和要小于1(等于1也不行)
        return gray
    else:
        return img

读取图片

  • 读取图片
  • 灰度处理
  • 归一化
  • 维度转换 同一尺寸
  • 返回ndarray
def get_datasets(file_path, num):
    img_list, label_list = [], []
    temp = 0
    for i in os.listdir(file_path):  # 1327.jpg
        img = Image.open(file_path + '\\' + i)  # 读取图片
        img = convert2gray(numpy.array(img))    # 灰度处理  np.array(image) 3维  image 2维
        img = img / 255.
        img_list.append(img.reshape(IMG_HEIGHT, IMG_WIDTH, 1))
        label_list.append(label2oneHot(i[:4]))
        temp += 1
        if temp >= num:
            break
    return numpy.array(img_list), numpy.array(label_list)

完整代码

import tensorflow as tf
import tensorflow.contrib as con
import random, os, matplotlib.pyplot as plt, numpy
from PIL import Image

'''
验证码字符数是4个
转成one-hot编码是(1, 40)
为方便计算 转成(4, 10)  计算准确率方便找最大值索引
'''

# 训练集和测试集数量
train_num = 1000
test_num = 100

IMG_HEIGHT = 60  # 图片高度
IMG_WIDTH = 160  # 图片宽度

'''
验证码图片如1327,需要对类别标签进行one-hot编码转换
[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]
验证码4个数,对应40个onehot(1, 40), 转成(4, 10)方便计算
'''
def label2oneHot(lable):
    vec = numpy.zeros(40)
    for i, num in enumerate(lable):
        index = i * 10 + int(num)
        vec[index] = 1
    return vec

'''
对于验证码识别,彩色对于我们是没有用的,转成灰度图
'''
def convert2gray(img):
    if img.shape[2] > 2:
        r, g, b = img[:, :, 0], img[:, :, 1], img[:, :, 2]
        gray = 0.2989 * r + 0.5872 * g + 0.1140 * b     # 这些小数加起来的和要小于1(等于1也不行)
        return gray
    else:
        return img

'''
读取图片
+ 读取图片
+ 灰度处理
+ 归一化
+ 维度转换 同一尺寸
+ 返回ndarray
'''
def get_datasets(file_path, num):
    img_list, label_list = [], []
    temp = 0
    for i in os.listdir(file_path):  # 1327.jpg
        img = Image.open(file_path + '\\' + i)  # 读取图片
        img = convert2gray(numpy.array(img))    # 灰度处理  np.array(image) 3维  image 2维
        img = img / 255.
        img_list.append(img.reshape(IMG_HEIGHT, IMG_WIDTH, 1))
        label_list.append(label2oneHot(i[:4]))
        temp += 1
        if temp >= num:
            break
    return numpy.array(img_list), numpy.array(label_list)

train_x, train_y = get_datasets(r'G:\A_深度学习1\tensorflow\train', train_num)
test_x, test_y = get_datasets(r'G:\A_深度学习1\tensorflow\test', test_num)

print(train_x.shape, len(train_y))

g_b = 0
def next_batch(X, Y, size):
    global g_b
    X = X[g_b:g_b + size]
    Y = Y[g_b:g_b + size]
    g_b = g_b + size
    return X, Y

print('==================================')

training_epochs = 100  # 训练总周期
batch_size = 100  # 训练每批样本数

# 占位符  Y: 4个数字的独热编码
X, Y = tf.placeholder('float', shape=[None, IMG_HEIGHT, IMG_WIDTH, 1]), tf.placeholder('float', shape=[None, 40])

# 第一层卷积
with tf.variable_scope('conv1'):
    W1 = tf.Variable(tf.random_normal([3, 3, 1, 32]))
    L1 = tf.nn.conv2d(X, W1, strides=[1, 1, 1, 1], padding='SAME')
    L1 = tf.nn.relu(L1)
    L1 = tf.nn.max_pool(L1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')

# 第二层卷积
with tf.variable_scope('conv2'):
    W2 = tf.Variable(tf.random_normal([3, 3, 32, 64]))
    L2 = tf.nn.conv2d(L1, W2, strides=[1, 1, 1, 1], padding='SAME')
    L2 = tf.nn.relu(L2)
    L2 = tf.nn.max_pool(L2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')

    dim = L2.get_shape()[1].value * L2.get_shape()[2].value * L2.get_shape()[3].value
    L2 = tf.reshape(L2, [-1, dim])

# 全连接层
with tf.variable_scope('fc'):
    W3 = tf.get_variable(name='w3', shape=[dim, 128], initializer=con.layers.xavier_initializer())
    b3 = tf.Variable(tf.random_normal([128]))
    L3 = tf.nn.relu(tf.matmul(L2, W3) + b3)

W4 = tf.get_variable(name='W4', shape=[128, 40], initializer=con.layers.xavier_initializer(), dtype=tf.float32)
b4 = tf.Variable(tf.random_normal([40]))
logits = tf.matmul(L3, W4) + b4

# 代价函数和优化器
# sigmod_cross适用于每个类别相互独立但不互斥,如图中可以有字母和数字
# softmax_cross适用于每个类别独立且排斥的情况,如数字和字母不可以同时出现
cost = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=logits, labels=Y))
optimizer = tf.train.AdamOptimizer(0.001).minimize(cost)

# 准确率计算
predict = tf.argmax(tf.reshape(logits, [-1, 4, 10]), 2)     # 在第2轴找最大索引
pre_y = tf.argmax(tf.reshape(Y, [-1, 4, 10]), 2)
acc = tf.reduce_mean(tf.cast(tf.equal(predict, pre_y), 'float'))

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for e in range(training_epochs):
        avg_cost = 0
        total_batch = int(train_num / batch_size)
        g_b = 0
        for i in range(total_batch):
            x, y = next_batch(train_x, train_y, batch_size)
            c, _ = sess.run([cost, optimizer], feed_dict={X: x, Y: y})
            avg_cost += c / total_batch

        if e % 10 == 0:
            print('Epoch:', (e + 1), 'cost =', avg_cost, 'acc=',
                  sess.run(acc, feed_dict={X: train_x, Y: train_y}))

    # 测试模型检查准确率
    print('正确率:', sess.run(acc, feed_dict={X: test_x, Y: test_y}))

    # 在测试集中随机抽一个样本进行测试
    r = random.randint(0, test_num - 1)
    print("标签: ", sess.run(tf.argmax(test_y[r:r + 1].reshape(4, 10), 1)))
    pre = sess.run([tf.argmax(tf.reshape(logits, [4, 10]), 1)], feed_dict={X: test_x[r:r + 1]})
    print("预测: ", pre)

    plt.imshow(test_x[r].reshape(60, 160))
    plt.show()
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WGS.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值