深度学习 -- TensorFlow(项目)验证码生成与识别(多任务学习)

# 验证码生成与识别
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
 
import tensorflow as tf
from tensorflow.keras.layers import Dense,GlobalAvgPool2D,Input
from tensorflow.keras.optimizers import SGD
from tensorflow.keras.models import Model
from tensorflow.keras.applications.resnet50 import ResNet50
from tensorflow.keras.callbacks import EarlyStopping,CSVLogger,ModelCheckpoint,ReduceLROnPlateau
import string
import numpy as np
import os
import random
from captcha.image import ImageCaptcha
from plot_model import plot_model
 
# 字符包含所有数字和所有小写英文字母,一共 62 个
characters = string.digits + string.ascii_letters
#            数字             字母
 
# 类别数(62)
classes_num = len(characters)
# 周期数
epochs = 100
 
# 图片宽度
width = 160
# 图片高度
height = 60
 
# 创建训练集(验证码)
def Create_train_data():
    # 1、创建字符集(字符包含所有数字和所有大小写英文字母,一共62(10+26+26)个)
    characters = string.digits + string.ascii_letters
    #            数字             英文字母(大小写)
 
    # 2、随机产生验证码(共1000个,每个长度为4)
    for i in range(1000):
        verification_list = []
 
        # 2-1、开始生产随机字符(4位)
        for j in range(4):
            c = random.choice(characters)   # 随机选择(从characters里面随机抽取)
            verification_list.append(c)
 
        # 2-2、实例化验证码生成器
        image = ImageCaptcha(width=160, height=60)  # 宽:160,高:60
 
        # 2-3、连接列表字符
        verification_list = ''.join(verification_list)
 
        # 2-4、生成验证码
        image.write(verification_list, 'captcha/train/' + verification_list + '.jpg')
 
 
# 创建测试集(验证码)
def Create_test_data():
    # 1、创建字符集(字符包含所有数字和所有大小写英文字母,一共62(10+26+26)个)
    characters = string.digits + string.ascii_letters
    #            数字             英文字母(大小写)
 
    # 2、随机产生验证码(共200个,每个长度为4)
    for i in range(200):
        verification_list = []
 
        # 2-1、开始生产随机字符(4位)
        for j in range(4):
            c = random.choice(characters)   # 随机选择(从characters里面随机抽取)
            verification_list.append(c)
 
        # 2-2、实例化验证码生成器
        image = ImageCaptcha(width=160, height=60)  # 宽:160,高:60
 
        # 2-3、连接列表字符
        verification_list = ''.join(verification_list)
 
        # 2-4、生成验证码
        image.write(verification_list, 'captcha/test/' + verification_list + '.jpg')
 
 
# 获取所有验证码图片路径和标签
def get_filenames_and_classes(dataset_dir):
    # 图片路径和标签
    paths ,targets = [], []
 
    # 获取每个图片的路径和标签
    for filename in os.listdir(dataset_dir):
        # 1、获取文件路径
        path = os.path.join(dataset_dir, filename)
#                           路径          文件名
        # 完成1:保存图片路径
        paths.append(path)
 
        # 2、获取验证码标签(取文件名的前 4 位,也就是验证码的标签)
        target = filename[0:4]
 
        # 定义一个空label(获取4*62的数组,用0填充)
        label = np.zeros((4, classes_num), dtype=np.uint8)
 
        # 3、标签转独热编码
        for i, ch in enumerate(target):
        # i:索引 ch:字符
            # 标记(设置标签):独热编码 one-hot 格式
            label[i, characters.find(ch)] = 1
            #    数组索引 字符下标(字符ch在characters中的下标)
 
        # 完成2:保存独热编码的标签
        targets.append(label)
 
    # 返回图片路径和标签
    return np.array(paths), np.array(targets)
 
 
# 图像处理函数
# 输入:图像路径、标签
# 输出:图像、标签
def image_function(filenames, label):
    # 1、根据图片路径读取图片内容
    image = tf.io.read_file(filenames)
    # 2、解码为jpeg格式、3通道(正规图像)
    image = tf.image.decode_jpeg(image, channels=3)
    # 3、归一化
    image = tf.cast(image, tf.float32) / 255.0
 
    # 返回图片数据和标签
    return image, label
 
 
# 标签处理函数
# 获得每一个批次的图片数据和标签
def label_function(image, label):
    # transpose 改变数据的维度,比如原来的数据 shape 是(64,4,62)
    # 这里的 64 是批次大小,验证码长度为 4 有 4 个标签,62 是 62 个不同的字符
    # tf.transpose(label,[1,0,2])计算后得到的 shape 为(4,64,62)
    # 原来的第 1 个维度变成了第 0 维度,原来的第 0 维度变成了 1 维度,第 2 维不变
    # (64,4,62)->(4,64,62)
    label = tf.transpose(label, [1, 0, 2])
    # 返回图片内容和标签,注意这里标签的返回,我们的模型会定义 4 个任务,所以这里返回 4 个标签
    # 每个标签的 shape 为(64,62),64 是批次大小,62 是独热编码格式的标签
    return image, (label[0], label[1], label[2], label[3])
 
 
# 获取数据(训练集、测试集)
def GetData():
    global dataset_train, dataset_test
    # 1、获取数据和标签
    # 1-1、获取训练集数据和标签(路径和标签)
    train_data, train_target = get_filenames_and_classes("./captcha/train/")# 1000张图片,长度4
 
    # 1-2、获取测试集数据和标签(路径和标签)
    test_data, test_target = get_filenames_and_classes("./captcha/test/")   # 200张图片,长度4
 
    # 1-3、数据组合(图像路径和标签)     (创建 dataset 对象,传入图片路径和标签)
    dataset_train = tf.data.Dataset.from_tensor_slices((train_data, train_target))
    dataset_test = tf.data.Dataset.from_tensor_slices((test_data, test_target))
 
    # 2、打乱数据
    dataset_train = dataset_train.shuffle(buffer_size=100, reshuffle_each_iteration=True)  # map-可以自定义一个函数来处理每一条数据
    dataset_test = dataset_test.shuffle(buffer_size=20, reshuffle_each_iteration=True)
    #                                     数据缓冲器大小     随机打乱(是/否)
 
    # 3、对每条数据进行处理(图像地址->3通道图像->归一化)
    dataset_train = dataset_train.map(image_function)
    dataset_test = dataset_test.map(image_function)
    # map函数:可以自定义一个函数来处理每一条数据
 
    # 4、自定义重复周期和批次大小
    dataset_train = dataset_train.repeat(1)         # 数据重复生成 1 个周期
    dataset_test = dataset_test.repeat(1)           # 数据重复生成 1 个周期
    dataset_train = dataset_train.batch(64)         # 定义批次大小64
    dataset_test = dataset_test.batch(64)           # 定义批次大小64
 
    # 5、处理每批数据
    # 注意这个 map 和前面的 map 有所不同,第一个 map 在 batch 之前,所以是处理每一条数据
    # 这个 map 在 batch 之后,所以是处理每一个 batch 的数据
    dataset_train = dataset_train.map(label_function)
    dataset_test = dataset_test.map(label_function)
 
    # 获取一批次数据和标签
    trainx, trainy = next(iter(dataset_train))
    testx, testy = next(iter(dataset_test))
    # print(trainx)
    # print(trainy)
    # print(testx)
    # print(testy)
 
 
# 创建神经网络
def Create_Network():
    # 1、构造resnet50神经网络(50层残差网络)
    resnet50 = ResNet50(weights='imagenet', include_top=False, input_shape=(height, width, 3))  # 设置输入
    # weights:权重(imagenet:加载预训练权重)
    # include_top:是否保留顶层的全连接网络
    # input_shape:指明输入图片的shape,仅当include_top=False有效
 
    # 2、设置输入层
    inputs = Input((height, width, 3))  # 设置输入层大小
    x = resnet50(inputs)  # 使用 resnet50 进行特征提取
 
    # 3、平均池化(压缩数据)
    x = GlobalAvgPool2D()(x)
 
    # 4、配置输出层(多任务学习)
    # 把验证码识别的4个字符看成是4个不同的任务,每个任务负责识别1个字符
    x0 = Dense(classes_num, activation='softmax', name='out0')(x)
    x1 = Dense(classes_num, activation='softmax', name='out1')(x)
    x2 = Dense(classes_num, activation='softmax', name='out2')(x)
    x3 = Dense(classes_num, activation='softmax', name='out3')(x)
 
    # 5、配置模型(输入层、输出层)
    model = Model(inputs, [x0, x1, x2, x3])
 
    # 6、编译(多任务学习)(损失函数、权重、优化器、监视等等设置)
    # (4个任务我们可以定义4个loss)
    model.compile(loss={'out0': 'categorical_crossentropy',
                        'out1': 'categorical_crossentropy',
                        'out2': 'categorical_crossentropy',
                        'out3': 'categorical_crossentropy'},
                  loss_weights={'out0': 1, 'out1': 1, 'out2': 1, 'out3': 1},
                  optimizer=SGD(lr=0.01, momentum=0.9),
                  metrics=['acc'])
    # loss:损失函数    loss_weights:权重    optimizer:优化器(lr:学习率;momentum:带动量的梯度下降)
    # metrics:监视(acc)
 
    # 7、回调函数(停止训练、保存数据、保存模型、调整学习率)
    callbacks = [EarlyStopping(monitor='val_loss', patience=6, verbose=1),
                 CSVLogger('Captcha_tfdata.csv'),
                 ModelCheckpoint('Best_Captcha_tfdata.h5', monitor='val_loss', save_best_only=True),
                 ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=3, verbose=1)]
    # monitor='val_loss':监控指标'val_loss'
    # EarlyStopping:让模型停止(6个周期,val_loss没有下降则训练结束)
    # CSVLogger: 保存训练数据
    # ModelCheckpoint:保存模型(保存所有训练周期中val_loss最低的模型)
    # ReduceLROnPlateau 学习率调整,连续3个周期,val_loss没有下降,则当前学习率乘以0.1
 
    # 8、训练模型
    model.fit(x=dataset_train, epochs=epochs, validation_data=dataset_test, callbacks=callbacks)
 
 
if __name__ == '__main__':
    # 一、创建验证码数据集
    # 判断训练集文件夹是否为空
    if not os.listdir('D:\\Study\\AI\OpenCV\\draft.py\\captcha\\train'):
        Create_train_data()     # 生成验证码训练集
    # 判断测试集文件夹是否为空
    if not os.listdir('D:\\Study\\AI\OpenCV\\draft.py\\captcha\\test'):
        Create_test_data()      # 生成验证码测试集
 
    # 二、获取数据
    GetData()
 
    # 三、构造神经网络
    Create_Network()

(1743条消息) 深度学习 -- TensorFlow(项目)验证码生成与识别(多任务学习)__睿智_的博客-CSDN博客_tensorflow验证码识别

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值