tensorflow卷积神经网络实战----验证码识别

16 篇文章 0 订阅
8 篇文章 0 订阅

tensorflow2

  

交叉熵的计算

 

 

 

 

 读取图片数据:

def read_pic():
    """
    读取图片数据
    return filename_batch, image_b
    """
    # 1. 构造文件名队列
    # 获取文件名列表
    file_names = glob.glob("./data/GenPics/*.jpg")
    # print("file_names:\n", file_names)
    file_queue = tf.compat.v1.train.string_input_producer(file_names)
    # 2. 读取与解码
    # 读取阶段
    reader = tf.compat.v1.WholeFileReader()
    filename, image = reader.read(file_queue)
    # 解码阶段
    decoded = tf.compat.v1.image.decode_jpeg(image)
    print(decoded)
    # 更新形状, 将图片形状确定下来
    decoded.set_shape([20, 80, 3])
    print("decoded:\n", decoded)
    # 修改图片的类型
    image_cast = tf.compat.v1.cast(decoded, tf.compat.v1.float32)



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

 解析csv文件:

def parse_csv():

    """
    解析csv文件,建立文件名和标签值对应表格
    return csv_data
    """
    csv_data = pd.read_csv("./data/GenPics/labels.csv", names=["file_num", "chars"], index_col="file_num")

    # 根据字母生成对应数字
    # 如NZPP——>[13,25,15,15]
    # 创建空列表  遍历
    labels = []
    for label in csv_data["chars"]:
    # print(label)
        letter = []
        for word in label:
            # print(word)
            letter.append(ord(word) - ord("A"))  # 将转好的数字放入letter
        labels.append(letter)  # 将letter放入label
    csv_data["labels"] = labels
# print(csv_data)
    return csv_data

将标签中的字母转换成0~25的数字,并且一一对应

# 3)将filename和标签值联系起来
def filename2label(filenames, csv_data):
    """
    将filename和标签值联系起来
    :param filenames:
    :param csv_data:
    :return:
    """
    labels = []

    # 将b'文件名中的数字提取出来并索引相应的标签值

    for filename in filenames:
        digit_str = "".join(list(filter(str.isdigit, str(filename))))
        label = csv_data.loc[int(digit_str), "labels"]
        labels.append(label)

    # print("labels:\n", labels)

    return np.array(labels)

构建卷积神经网络 

# 4)构建卷积神经网络->y_predict
def create_weights(shape):
    return tf.Variable(initial_value=tf.compat.v1.random_normal(shape=shape, stddev=0.01))


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

        # 卷积层
        # 定义filter和偏置
        conv1_weights = create_weights(shape=[5, 5, 3, 32])
        conv1_bias = create_weights(shape=[32])
        conv1_x = tf.compat.v1.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.compat.v1.nn.max_pool(value=relu1_x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")

    # 2)第二个卷积大层
    with tf.compat.v1.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.compat.v1.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.compat.v1.nn.max_pool(value=relu2_x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")

    # 3)全连接层
    with tf.compat.v1.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

构造损失函数


    # 3、构造损失函数
    with tf.compat.v1.variable_scope("soft_cross"):

        loss_list = tf.nn.sigmoid_cross_entropy_with_logits(labels=y_true, logits=y_predict)
        loss = tf.reduce_mean(loss_list)

优化损失

    with tf.compat.v1.variable_scope("optimizer"):

        optimizer = tf.compat.v1.train.AdamOptimizer(learning_rate=0.001).minimize(loss)

计算准确率 

  with tf.compat.v1.variable_scope("acc"):

        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))

开启会话

 

 

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

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

        # 开启线程
        coord = tf.train.Coordinator()
        threads = tf.compat.v1.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)

完整代码如下:

import numpy as np
import tensorflow as tf
import glob
import pandas as pd
tf.compat.v1.disable_eager_execution()

def read_pic():
    """
    读取图片数据
    return filename_batch, image_b
    """
    # 1. 构造文件名队列
    # 获取文件名列表
    file_names = glob.glob("./data/GenPics/*.jpg")
    # print("file_names:\n", file_names)
    file_queue = tf.compat.v1.train.string_input_producer(file_names)
    # 2. 读取与解码
    # 读取阶段
    reader = tf.compat.v1.WholeFileReader()
    filename, image = reader.read(file_queue)
    # 解码阶段
    decoded = tf.compat.v1.image.decode_jpeg(image)
    print(decoded)
    # 更新形状, 将图片形状确定下来
    decoded.set_shape([20, 80, 3])
    print("decoded:\n", decoded)
    # 修改图片的类型
    image_cast = tf.compat.v1.cast(decoded, tf.compat.v1.float32)



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


def parse_csv():

    """
    解析csv文件,建立文件名和标签值对应表格
    return csv_data
    """
    csv_data = pd.read_csv("./data/GenPics/labels.csv", names=["file_num", "chars"], index_col="file_num")

    # 根据字母生成对应数字
    # 如NZPP——>[13,25,15,15]
    # 创建空列表  遍历
    labels = []
    for label in csv_data["chars"]:
    # print(label)
        letter = []
        for word in label:
            # print(word)
            letter.append(ord(word) - ord("A"))  # 将转好的数字放入letter
        labels.append(letter)  # 将letter放入label
    csv_data["labels"] = labels
# print(csv_data)
    return csv_data


# 3)将filename和标签值联系起来
def filename2label(filenames, csv_data):
    """
    将filename和标签值联系起来
    :param filenames:
    :param csv_data:
    :return:
    """
    labels = []

    # 将b'文件名中的数字提取出来并索引相应的标签值

    for filename in filenames:
        digit_str = "".join(list(filter(str.isdigit, str(filename))))
        label = csv_data.loc[int(digit_str), "labels"]
        labels.append(label)

    # print("labels:\n", labels)

    return np.array(labels)


# 4)构建卷积神经网络->y_predict
def create_weights(shape):
    return tf.Variable(initial_value=tf.compat.v1.random_normal(shape=shape, stddev=0.01))


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

        # 卷积层
        # 定义filter和偏置
        conv1_weights = create_weights(shape=[5, 5, 3, 32])
        conv1_bias = create_weights(shape=[32])
        conv1_x = tf.compat.v1.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.compat.v1.nn.max_pool(value=relu1_x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")

    # 2)第二个卷积大层
    with tf.compat.v1.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.compat.v1.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.compat.v1.nn.max_pool(value=relu2_x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")

    # 3)全连接层
    with tf.compat.v1.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

# 5)构造损失函数
# 6)优化损失
# 7)计算准确率
# 8)开启会话、开启线程


def conv_fc():
    filename, image = read_pic()
    csv_data = parse_csv()

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

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

    # 3、构造损失函数
    with tf.compat.v1.variable_scope("soft_cross"):

        loss_list = tf.nn.sigmoid_cross_entropy_with_logits(labels=y_true, logits=y_predict)
        loss = tf.reduce_mean(loss_list)

    # 4、优化损失
    with tf.compat.v1.variable_scope("optimizer"):

        optimizer = tf.compat.v1.train.AdamOptimizer(learning_rate=0.001).minimize(loss)

    # 5、计算准确率
    with tf.compat.v1.variable_scope("acc"):

        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_op = tf.compat.v1.global_variables_initializer()


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

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

        # 开启线程
        coord = tf.train.Coordinator()
        threads = tf.compat.v1.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)

if __name__ == "__main__":
    conv_fc()

 运行结果:

 

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值