tensorflow验证码识别

验证码的识别原理类似于手写数字mnist数据集的识别,每张验证码上面存在四位字母A-Z, 在这里我可以用数字1-26表示,而1-26又可以转化为(比如3为[0, 0, 1, …, 0, 0])类似与手写数字识别一样的形式, 而验证码上面是由4位大写英文字母组成,在这里我们可以采用4 x 26的矩阵表示。

‘’'4.1 卷积神经网络
1)与传统的神经网络对比
输入层,隐藏层,(卷积层,激活层, 池化层, 全连接层) 输出层
4.2 卷积神经网络原理
卷积神经网络网络 - 结构
卷积层,
通过在原始图片上平移来提取图片
激活层,
增加非线性的分割能力
池化层(pooling layer, subsample),
降低网络的模型复杂度,减少学习参数
全连接层

卷积核四要素:

卷积网络API
tf.nn.conv2d(input, filter, strides=, padding=)
input:输入图像
    []为输入的图片,类型必须为float32,64
filter: 指定过滤器的权重:
    weights,
    变量 initial_value= random_normal(shape=[filter_height, filter_width, in_channels(输入图片的通道数), out_channels(输出图片的通道数)])
strides:
    步长 strides=[1, strides, stride, 1](上下左右的步长)
padding
    "SAME":越过边缘取样  ceil(H/S) (H为宽高, S为步长)
    "VALID":  不填充

4.2.3 激活函数
Relu优点
有效解决梯度消失问题
计算速度非常快

sigmoid缺点
    计算量大
    梯度消失
    取值范围在[-6, 6]
Tanh是由sigmoid改进而来

ReLU = max(0, x)(不会有梯度消失的情况)   (图片的像素点没有小于零的情况)
tf.nn.relu(features)
features:卷积后加上偏置的结果
return:结果

4.2.4池化层
减少学习参数, 降低网络的复杂度(最大池化,平均池化)
max_polling:取池化窗口的最大值 取filter中的最大值(比较常用)
avg_polling:取池化窗口的平均值 取filter中的平均值(比较常用)
tf.nn.max_pool(value, ksize=, strides=. padding=, name=None)
value: 4-D tensor形状[batch, height, width, channels]
channel: 并不是原始图片的通道数,而是多少fillter观察
ksize:池化窗口大小,[1, ksize, ksize, 1]
strides:步长大小,[1, strides, strides, 1]
padding:“SAME”, “VALID”, 使用填充算法的类型, 默认使用"SAME"

网络的优化和改进
使用改进版的SGD算法

调参——>提高学习率
调整网络结构 batch normallization 或者droupout层(降低模型的复杂度)
初始化的权重偏置的值 tf.varaible(initial_value=)
‘’’

‘’’
4.5 实战:验证码的识别
1)数据集
图片1 -> NZPP 一个样本对应4个目标值
手写数字的图片的识别 -> 0~9之间的某一个数
切割 -> 不具备通用性
[0, 0, 1, 0 …]
2)对数据集中
特征值 目标值 怎么用
3)如何分类?
如何衡量损失
手写数字识别案例 -> 交叉熵
softmax + 交叉熵
但是softmax只能计算一维
sigmoid交叉熵
正确性的计算
核心:比对真实值和目标值的位置
手写数字识别案例
y_predict[None, 10]

4)流程分析
    1)读取数据
        tf.WholeFileReader()
        filename -> 标签值
        key, value = read(file)
        key:文件名 - labels.csv - 目标值
        value:一个样本
    2)解析csv文件, 将标签值转化为数组
    3)将filename和标签值联系起来
    4)构建卷积神经网络 -> y_predict
    5)构造损失函数
    6)优化损失
    7)计算准确率
    8)开启会话, 开启线程

‘’’
import tensorflow as tf
import numpy as np
import tensorflow as tf
import os
import glob
import pandas as pd

def read_pic():
‘’’
读取图片数据
:return:
‘’’
# 1、构造文件名队列
filenames = glob.glob(r’D:/QQPCmgr/Desktop/GenPics/*.jpg’)
# print(filenames)
file_queue = tf.train.string_input_producer(filenames)

# 2、读取与解码
reader = tf.WholeFileReader()
filename, image = reader.read(file_queue)
#解码阶段
decoded = tf.image.decode_jpeg(image)
# print(decoded)
decoded.set_shape([20, 80, 3])
# 修改图片的类型
image_cast = tf.cast(decoded, tf.float32)

# 3、批处理阶段
filename_batch, image_batch = tf.train.batch([filename, image_cast], batch_size=100, num_threads=1, capacity=200)
return filename_batch, image_batch

def parse_csv():
‘’’
#解析csv文件,建立关系
:return:
‘’’
data = pd.read_csv(r’D:\QQPCmgr\Desktop\GenPics\labels.csv’, names=[‘file_num’, ‘chars’], index_col=‘file_num’)

# 根据字母生成对应的数字
labels = []
for label in data["chars"]:
    letter = []
    for word in label:
        letter.append(ord(word) - ord('A'))
    labels.append(letter)
data['labels'] = labels

return data

def filename2label(filename, csv_data):
‘’’

:param filename:
:param csv_data:
:return:
'''
# print(filename)
labels = []
for file in filename:
    file_num = "".join(list(filter(str.isdigit, str(file))))
    target = csv_data.loc[int(file_num), 'labels']
    labels.append(target)
return np.array(labels)

def create_weights(shape):
return tf.Variable(initial_value=tf.random_normal(shape=shape, stddev=0.01))

def create_model(x):
“”"
构建卷积神经网络
:param x:[None, 20, 80, 3]
:return:
“”"
# 1)第一个卷积大层
with tf.variable_scope(“conv1”):

    # 卷积层
    # 定义filter和偏置
    conv1_weights = create_weights(shape=[5, 5, 3, 32])
    conv1_bias = create_weights(shape=[32])
    conv1_x = tf.nn.conv2d(input=x, filter=conv1_weights, strides=[1, 1, 1, 1], padding="SAME") + conv1_bias

    # 激活层
    relu1_x = tf.nn.relu(conv1_x)

    # 池化层
    pool1_x = tf.nn.max_pool(value=relu1_x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")

# 2)第二个卷积大层
with tf.variable_scope("conv2"):
    # [None, 20, 80, 3] --> [None, 10, 40, 32]
    # 卷积层
    # 定义filter和偏置
    conv2_weights = create_weights(shape=[5, 5, 32, 64])
    conv2_bias = create_weights(shape=[64])
    conv2_x = tf.nn.conv2d(input=pool1_x, filter=conv2_weights, strides=[1, 1, 1, 1], padding="SAME") + conv2_bias

    # 激活层
    relu2_x = tf.nn.relu(conv2_x)

    # 池化层
    pool2_x = tf.nn.max_pool(value=relu2_x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")

# 3)全连接层
with tf.variable_scope("full_connection"):
    # [None, 10, 40, 32] -> [None, 5, 20, 64]
    # [None, 5, 20, 64] -> [None, 5 * 20 * 64]
    # [None, 5 * 20 * 64] * [5 * 20 * 64, 4 * 26] = [None, 4 * 26]
    x_fc = tf.reshape(pool2_x, shape=[-1, 5 * 20 * 64])
    weights_fc = create_weights(shape=[5 * 20 * 64, 4 * 26])
    bias_fc = create_weights(shape=[104])
    y_predict = tf.matmul(x_fc, weights_fc) + bias_fc

return y_predict

if name == “main”:
filename, image = read_pic()
csv_data = parse_csv()

# 1、准备数据
x = tf.placeholder(tf.float32, shape=[None, 20, 80, 3])
y_true = tf.placeholder(tf.float32, shape=[None, 4*26])

# 2、构建模型
y_predict = create_model(x)

# 3、构造损失函数
loss_list = tf.nn.sigmoid_cross_entropy_with_logits(labels=y_true, logits=y_predict)
loss = tf.reduce_mean(loss_list)

# 4、优化损失
optimizer = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)

# 5、计算准确率
equal_list = tf.reduce_all(
tf.equal(tf.argmax(tf.reshape(y_predict, shape=[-1, 4, 26]), axis=2),
         tf.argmax(tf.reshape(y_true, shape=[-1, 4, 26]), axis=2)), axis=1)
accuracy = tf.reduce_mean(tf.cast(equal_list, tf.float32))

# 初始化变量
init = tf.global_variables_initializer()


# 开启会话
with tf.Session() as sess:

    # 初始化变量
    sess.run(init)

    # 开启线程
    coord = tf.train.Coordinator()
    threads = tf.train.start_queue_runners(sess=sess, coord=coord)

    for i in range(1000):
        filename_value, image_value = sess.run([filename, image])
        # print("filename_value:\n", filename_value)
        # print("image_value:\n", image_value)

        labels = filename2label(filename_value, csv_data)
        # 将标签值转换成one-hot
        labels_value = tf.reshape(tf.one_hot(labels, depth=26), [-1, 4*26]).eval()

        _, error, accuracy_value = sess.run([optimizer, loss, accuracy], feed_dict={x: image_value, y_true: labels_value})

        print("第%d次训练后损失为%f,准确率为%f" % (i+1, error, accuracy_value))

    # 回收线程
    coord.request_stop()
    coord.join(threads)

在这里插入图片描述
在173次训练之后识别的准确率已经就收敛于1

数据链接:链接:https://pan.baidu.com/s/1QmwuMQMI6Ihf0XcbFty3xw
提取码:etl7
复制这段内容后打开百度网盘手机App,操作更方便哦

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值