Python项目实战篇——常用验证码标注&识别(CNN神经网络模型训练/测试/部署)

点击上方“Python爬虫与数据挖掘”,进行关注

回复“书籍”即可获赠Python从入门到进阶共10本电子书

愿得此身长报国,何须生入玉门关。

    大家好,我是Snowball。

一、前言

    今天给大家分享的实战项目是常用验证码标注&识别,前面三篇文章讲解了文章的创作灵感、需求分析和实现思路、数据采集/预处理/字符图切割等知识、高效率数据标注等知识,分别是以下文章:

Python项目实战篇——常用验证码标注和识别(需求分析和实现思路)

Python项目实战篇——常用验证码标注&识别(数据采集/预处理/字符图切割)

Python项目实战篇——常用验证码标注&识别(前端+后端实现高效率数据标注)

这篇文章引入机器学习,给大家讲解下基于该项目的CNN神经网络模型训练/测试/部署。

二、背景知识

    按照学习的好习惯,先搜索网上资源,再脑洞一下,先思考啥是神经网络,啥是卷积,CNN神经网络为啥能提取图片特征,这些问题笔者刚开始全部都遇到过,一脸蒙蔽有没有。不要急,有问题有时候是好事,说明你知道自己那些不知道,等到自己了解和懂得多了,有些问题就迎刃而解。

    笔者刚开始在上面的OpenCV知识学习过程中,就尝试用过传统的SIFT算法进行提取图片特征可以进行图片相似度匹配,但是效果都比较差,这里面用的是多维向量特征描述。而神经网络在机器学习的领域为啥这么牛皮,这里面是有数学方面的理论支撑,也有现在计算力和数据量的支持,而卷积神经网络专门用来处理图片特征提取。

    刚开始,笔者对这方面的理论知识了解甚少,于是充分利用搜索工具和网上资源,这里分享一下自己学习过程中的文章链接和视频链接,可以保证读者看完基本可以加深对神经网络训练的实战了解,可上手进行项目功能调整。好的,让我们开始学习(卷)起来,以下就是所有内容的链接,没有基础的朋友可以补一补,有基础的可以直接跳过:

**数学基础**
[微积分](https://www.bilibili.com/video/BV1Eb411u7Fw)


[线性代数](https://www.bilibili.com/video/BV1aW411Q7x1)


[概率论](https://www.bilibili.com/video/BV1ot411y7mU)


[计算机数学基础](https://www.bilibili.com/video/BV1AB4y1K7kM)




**OpenCV**
[OpenCV文章专栏](https://blog.csdn.net/yukinoai/category_9283880.html)


[OpenCV-Python视频](https://www.bilibili.com/video/BV1tb4y1C7j7)




**神经网络**
[理解卷积意义](https://www.bilibili.com/video/BV1VV411478E)


[前馈神经网络](https://www.bilibili.com/video/BV1Tt411s7fK)


[神经网络学习理解](https://space.bilibili.com/504715181?spm_id_from=333.788.b_765f7570696e666f.1)




**Python框架使用**
[Numpy中文教程](https://www.runoob.com/numpy/numpy-tutorial.html)


[PyTorch中文教程](https://pytorch.panchuang.net/SecondSection/neural_networks/)


[PyTorch视频](https://www.bilibili.com/video/BV1t64y1t7V8)

    以上就是笔者这次项目开发几个月来搜索的优质学习文章和视频资源了,有基础的朋友可以选择性相关知识学习,没有基础而时间充裕的可以恶补基础再动手实战,所谓磨刀不误砍柴工。想快速动手的小伙伴可以快速学习,把对应项目需要的知识点看明白即可。笔者建议的学习方式是确定自己的任务主线,然后边学边练边思考,在项目实战中学习总结是成长最快的方式。

    好的,在上面前置知识学习了解的差不多后,相信大家都已经知道CNN神经网络的理论知识了,接下来我们动手进行CNN模型的实战训练过程。

在开始,确定模型训练基本过程

  1. 准备训练数据集、测试数据集、预测数据集

  2. CNN模型编码

  3. 模型训练、测试

  4. 模型预测、部署

三、CNN神经网络模型训练

    1.准备数据

    通过实现思路第1-2步,可以得到相关图片验证码字符数据,笔者这里准备训练集500多张(这里得感谢我妹子花时间帮我在标注系统上手动标注的初始数据集~~),测试集30多张,预测5张。读者在python项目拉取下来后,对应的文件夹下面已有全部数据,对应路径如下:

src_img:训练数据集

test_src_img:测试数据集

usage_src_img:预测数据集

在准备好图片验证码数据后,本次案例需要先进行字符切割预处理(其他常用验证码需要读者自己调整),对应文件image_split,以下是main方法代码。

if __name__ == '__main__':
    split_image_dir(SRC_IMG_DIR)
    
    split_test_image()

执行字符切割后,对应的训练集字母分类在letter_template目录下,测试集字母分类在letter_test目录下。

数据集类:net_data.py,下面是主要代码。

labels = []
#2-9
for i in range(8):
    labels.append(50 + i)
#A-Z    
for i in range(26):
    labels.append(65 + i)


class VerCodeDataset(Dataset):
    def __init__(self, image_dir="./letter_template/"):
        l = os.listdir(image_dir)
        self.data = []
        self.label = []
        for d in l:
            fs = os.listdir("{}{}".format(image_dir, d))
            for f in fs:
                fup = "{}{}/{}".format(image_dir, d, f)
                #图片numpy转tensor
                t = torch.from_numpy(io.imread(fup)).float() / 255
                #将二维值标准化
                norl = transforms.Normalize(t.mean(), t.std())
                self.data.append(norl(t.reshape(1, 40, 40)))
                #添加字符对应标签序号
                self.label.append(labels.index(ord(d)))

数据集值制作描述可参考该文章链接:

[数据集制作参考文章](https://zhuanlan.zhihu.com/p/358671390)

2.CNN模型编码

    本文验证码的识别与MNIST的识别相当类似,模型这块采用简单的前馈神经网络,它接收输入,让输入一个接着一个的通过一些层,最后给出输出。下面是minst网络结构图:

[PyTorch 神经网络 - PyTorch官方教程中文版](https://link.zhihu.com/?target=http%3A//pytorch.panchuang.net/SecondSection/neural_networks/)

3a6631ba99e865d366d209a8ed0d6595.png

一个典型的神经网络训练过程包括以下几点:

1.定义一个包含可训练参数的神经网络

2.迭代整个输入

3.通过神经网络处理输入

4.计算损失(loss)

5.反向传播梯度到神经网络的参数

6.更新网络的参数,典型的用一个简单的更新方法:weight = weight - learning_rate *gradient

定义神经网络(net_train.py):

class Net(nn.Module):
    def __init__(self, dropout=0.1):
        super(Net, self).__init__()
        self.dropout = nn.Dropout(dropout)
         #第一层,卷积核个数从6改成10
        self.conv1 = nn.Conv2d(1, 10, 5)
        #第二层,卷积核个数从10改成25
        self.conv2 = nn.Conv2d(10, 25, 5)
        
        #全连接层1,40*40的字符图经过2层卷积+2层池化变成7*7
        self.fc1 = nn.Linear(1 * 25 * 7 * 7, 120)
        #全连接层2
        self.fc2 = nn.Linear(120, 84)
        #最后全连接3层为输出层,本案例验证码分类一共34类,[2-9,A-Z],改为34。
        self.fc3 = nn.Linear(84, 34)


    def forward(self, x):
        # 池化出来大小直接除2
        x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
        #防止过拟合
        x = self.dropout(x)
        x = F.max_pool2d(F.relu(self.conv2(x)), (2, 2))
        x = self.dropout(x)
        x = x.view(-1, self.num_flat_features(x))
        #神经元relu激活函数
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x


    def num_flat_features(self, x):
        size = x.size()[1:]  # all dimensions except the batch dimension
        num_features = 1
        for s in size:
            num_features *= s
        return num_features

下方代码中:

self.fc1 = nn.Linear(1 * 25 * 7 * 7, 120)

全连接层第一个参数的大小:

[40,40]经过[5,5]卷积核->[35,35]

[35,35]经过[2,2]池化->[18,18]

[18,18]经过[5,5]卷积核->[13,13]

[13,13]经过[2,2]池化->[7,7]

上层卷积层一共25个卷积核,因此这里的大小为1(通道数)*25*7*7= 1225,至于后面全连接的84可以随便改,和下层全连接层保持一致即可。

以上就是模型定义的代码了,读者有兴趣的也可以自行用其他模型训练。

四、CNN神经网络模型测试

    net_train.py文件提供的训练代码支持GPU训练,在没有NVDIA显卡和安装pytorch对应版本的CUDA库,默认是使用CPU训练,笔者对二种训练方式都进行了尝试,下面是训练对比情况:

数据量:2286张 40*40 单通道字符图片
batch_size: 50
epoch: 200


设备          时间
GTX 1070TI      25s
AMD R7 4750U PRO  4min

    总结,数据量大,有条件上GTX显卡就用显卡训练,训练效率高出CPU数量级

[cuda安装文章链接](https://www.cnblogs.com/yang520ming/p/10677110.html)

    这里是cuda安装注意事项:

1.更新nvida显卡驱动程序,然后看cuda版本
2.找pytorch对应cuda的版本安装

train方法代码如下:

def train_gpu():
    use_cuda = torch.cuda.is_available()
    if(use_cuda):
        print("use gpu cuda")
    else:
        print("use cpu")


    device = torch.device("cuda:0" if use_cuda else "cpu")
    net = Net()
    net.to(device)
  
  #随机梯度下降
    opt = optim.SGD(net.parameters(), lr=0.01)
    #迭代数据200次
    epoch = 200
    #单批次数据为50个
    batch_size = 50
    
    trainloader = data.trainloader(batch_size)
    st = datetime.datetime.now()
    loss = 0


    for e in range(epoch):
        for step, d in enumerate(trainloader):
            data_cuda =  d["data"].to(device)
            label_cuda = d["label"].to(device)
            #每次反向传播后,梯度清零
            opt.zero_grad()
            #前向传播
            out = net(data_cuda)
            #分类问题选用交叉熵损失函数
            lf = nn.CrossEntropyLoss()
            #计算损失
            loss = lf(out, label_cuda)
            #反向传播修改神经元参数
            loss.backward()
            opt.step()


      #每迭代50次或第一个批次步骤数据输出损失值
            if (e % 50 == 0 or step == 1):
                print("e : {} , step : {}, loss : {}".format(e, step, loss))


    print("loss : {}".format(loss))
    #输出训练时间
    print("cost time:",datetime.datetime.now() - st)
    #保存模型
    saveModel(net, opt)

描述见上面代码注释,对概念理解有问题建议可以再看下这个up主的视频,笔者觉得讲得非常不错:

[神经网络学习理解](https://space.bilibili.com/504715181?spm_id_from=333.788.b_765f7570696e666f.1)

下面给出训练、测试过程中的效果图:

GPU模型-训练集训练:

7c9b9a6ccd51a41c27ae6a5c46d1811c.png

CPU模型-训练集训练

c9350fd2d3324eface534544ac81977c.png

cf03ceabe77037dc823a22ded7a00121.png

    可以看到迭代200次,花费4分钟的训练,模型趋于拟合效果,次数越往后梯度下降越慢。其实在迭代100次之后就接近稳定来回振荡,损失值减少越慢,最后的损失值为0.0016,拟合效果还不错,如果增加训练数据量、迭代次数、优化部分字符串的切割,可以让模型效果更好,读者可自行实践。

CPU模型-测试集测试

代码见net_test.py

23ab2d95e7715a8892ffe772431fa6dd.png

    可以看到152个字符,97%的准确率,部分字符切割问题会导致准确率下降,不过问题不大,基本达到个人项目可用程度,Nice~~

五、CNN神经网络模型预测和部署

    经过1,2,3步循环过程后,可以用一个相对拟合稳定的模型进行预测集预测,因为过拟合的问题,可能有些模型在测试集表现较好,在测试时效果就不太好,这里需要对训练数据,模型参数进行排

CPU模型-预测集测试

代码见net_usage.py

acbf03dba5d47b48d78b946560d2d7eb.png

    上图可以看到,5张验证码的字符全部预测正确。

CPU模型-部署:

使用python的web框架Flask API,编写图片验证码识别POST接口,传入文件路径,启动web应用,以下是通过本机文件路径识别接口代码,详细代码见net_flask.py

@app.route('/recognize/path', methods=['POST'])
def recognize_path():
    filePathList = request.json['filePathList']
    code = CODE_SUCCESS
    msg = MSG_SUCCESS
    data = []
    for filePath in filePathList:
        if not os.path.exists(filePath):
            # code = CODE_FAIL
            # msg = "文件不存在"
            print("文件不存在:", filePath)
            data.append("")
            continue
        else:
            labels = usage_model.usage(filePath)
            data.append(''.join(labels))
    result = {'code': code, "msg": msg, "data": data}
    return jsonify(result)

模型-Flask Web App启动效果:

12bb02ffee56c1d139d0acb8acda0b37.png

Postman接口测试效果:

c0df8de052325f75ad2809becd8b21dd.png

Web页面批量请求-预测:

4c7df180c50033aa9e9b81ab3a2f30ca.png

    好的,以上就是笔者图片验证码识别案例中的卷积神经网络模型训练、测试、部署的全部内容了,总的来说,从结果看模型预测效果还是非常不错的,首先利用标注系统进行人工标注初始数据集、下载数据集,然后再进行数据集的准备,接着进行模型的编码、训练和测试,然后利用训练出来的模型进行数据预测,通过人工判断修正再把加入到训练集中,从而低时间成本、高效率增加训练数据量。

六、总结

    大家好,我是Snowball。这几篇文章,整个过程下来,读者就会熟悉到CNN神经网络在图片特征提取的魅力之处,其原理还是利用概率论、机器学习知识,在多层CNN模型下,通过多层感知机的激活函数、随机梯度下降法、损失函数、反向传播等机制进行复杂非线性模型参数的调节,使得训练处理的模型概率分布尽可能接近人脑中标注数据的概率模型。

    当然,读者看到这里觉得这里面还有很多疑问和问题,请不要气馁,整个机器学习、神经网络的知识体系是非常庞大的,从数学理论到计算机算法,再到工程框架,细节一步步被隐藏,请保持好奇心和思考,持续了解和学习,未来可能等知识积累到一定程度,那么很多问题就会明白和理解。说的东西有点多了,哈哈,总之还是,信息时代合理利用互联网上的资源。

    接下来讲述最后一部分,下一篇文章奉上。就是所有项目模块的部署部分,这部分内容不会太难,如果读者不感兴趣可以跳过,可以利用笔者部署到线上的系统进行体验,服务器带宽有限,有资源的读者可以自己部署一套:线上效果体验地址

    小伙伴们,快快用实践一下吧!如果在学习过程中,有遇到任何问题,欢迎加我好友,我拉你进Python学习交流群共同探讨学习。

fe114fb4293dd94a858e1f1320db95ce.png

------------------- End -------------------

往期精彩文章推荐:

026d7cf2f54fd66c9ac6ad8651ab9801.png

欢迎大家点赞,留言,转发,转载,感谢大家的相伴与支持

想加入Python学习群请在后台回复【入群

万水千山总是情,点个【在看】行不行

/今日留言主题/

随便说一两句吧~~

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
【课程介绍】      Pytorch项目实战 垃圾分类课程从实战的角度出发,基于真实数据集与实际业务需求,结合当下最新话题-垃圾分类问题为实际业务出发点,介绍最前沿的深度学习解决方案。    从0到1讲解如何场景业务分析、进行数据处理,模型训练与调优,最后进行测试与结果展示分析。全程实战操作,以最接地气的方式详解每一步流程与解决方案。    课程结合当下深度学习热门领域,尤其是基于facebook 开源分类神器ResNext101网络架构,对网络架构进行调整,以计算机视觉为核心讲解各大网络的应用于实战方法,适合快速入门与进阶提升。【课程要求】 (1)开发环境:python版本:Python3.7+; torch版本:1.2.0+; torchvision版本:0.4.0+ (2)开发工具:Pycharm;(3)学员基础:需要一定的Python基础,及深度学习基础;(4)学员收货:掌握最新科技图像分类关键技术;(5)学员资料:内含完整程序源码和数据集;(6)课程亮点:专题技术,完整案例,全程实战操作,徒手撸代码【课程特色】 阵容强大讲师一直从事与一线项目开发,高级算法专家,一直从事于图像、NLP、个性化推荐系统热门技术领域。仅跟前沿基于当前热门讨论话题:垃圾分类,课程采用学术届和工业届最新前沿技术知识要点。实战为先根据实际深度学习工业场景-垃圾分类,从产品需求、产品设计和方案设计、产品技术功能实现、模型上线部署。精心设计工业实战项目保障效果项目实战方向包含了学术届和工业届最前沿技术要点项目包装简历优化课程内垃圾分类图像实战项目完成后可以直接优化到简历中【课程思维导图】 【课程实战案例】

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值