大家好,我是雪球。一、前言今天给大家分享的实战项目是常用的验证码标注&识别。前三篇讲解文章的创作灵感、需求分析与实现思路、数据采集/预处理/字符图切分等知识,高效数据标注等知识分别是以下几篇文章:Python项目实战篇——常用验证码标注与识别(需求分析与实现思路)Python项目实战篇-常用验证码标注与识别(数据采集/预处理/字符图切割)Python项目实战篇—常用验证码标注与识别(前-end+后端实现高效数据标注)本文介绍机器学习,讲解基于本项目的CNN神经网络模型训练/测试/部署。2.背景知识按照学习的好习惯,先搜索网上资源,然后想一想,首先想一想什么是神经网络,什么是卷积,为什么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模型的实际训练过程。一开始,确定模型训练的基本流程准备训练数据集,测试数据集,预测数据集CNN模型编码模型训练,测试模型预测,部署3.CNN神经网络模型训练,可以得到相关图片验证码字符数据。作者这里准备了500多个训练集(这里要感谢姐姐抽空帮我在标注系统上手动标注初始数据集~~),30多个测试集,预测5开。读者拉下python工程后,对应文件夹下就有所有数据,对应路径如下:src_img:训练数据集test_src_img:测试数据集usage_src_img:预测数据集图片验证码数据准备好后,本例需要先进行字符切割预处理(其他常用验证码需要读者自行调整),对应文件image_split,下面是主要方法代码。if__name__=='__main__':split_image_dir(SRC_IMG_DIR)split_test_image()进行字符分割后,对应的训练集字母分类在letter_template目录下,测试集字母分类在letter_test目录下。数据集类:net_data.py,以下是主要代码。labels=[]#2-9foriinrange(8):labels.append(50+i)#A-Zforiinrange(26):labels.append(65+i)classVerCodeDataset(数据集):def__init__(self,image_dir="./letter_template/"):l=os.listdir(image_dir)self.data=[]self.label=[]fordinl:fs=os.listdir("{}{}".format(image_dir,d))forfinfs:fup="{}{}/{}".format(image_dir,d,f)#图片numpy转tensort=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/)一个典型的神经网络训练过程包括以下几点:1.定义一个包含可训练参数的神经网络2.迭代整个输入3.通过神经网络处理输入4.计算损失(loss)5.将梯度反向传播到神经网络参数6.更新网络的参数,通常使用简单的更新方法:weight=weight-learning_rate*gradient定义神经网络(net_train.py):classNet(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)#SecondLayer,卷积核个数由10个改为25个self.conv2=nn.Conv2d(10,25,5)#Fully连接层1,40*40的字符图经过2层卷积+2层池化后变成7*7self.fc1=nn.Linear(1*25*7*7,120)#全连接层2self.fc2=nn。Linear(120,84)#最后的全连接层3为输出层,本例中有34个验证码Class,[2-9,A-Z],改为34。self.fc3=nn.Linear(84,34)defforward(self,x):#pooling的大小直接除以2x=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))#Neuronrelu激活函数x=F.relu(self.fc1(x))x=F.relu(self.fc2(x))x=self.fc3(x)returnxdefnum_flat_features(self,x):size=x.size()[1:]#alldimensionsexceptthebatchdimensionnum_features=1forsinsize:num_features*=sreturnnum_features下面代码中:self.fc1=nn.Linear(1*25*7*7,120)全连接该层第一个参数的大小:[40,40]after[5,5]convolutionkernel->[35,35][35,35]after[2,2]pooling->[18,18][18,18]经过[5,5]卷积核->[13,13][13,13]经过[2,2]池化->[7,7]上层卷积层,一共25个卷积核,所以这里的size是1(通道数)*25*7*7=1225,至于后面的全连接84可以随意改,保持它与较低的全连接层一致。以上是模型定义的代码。有兴趣的读者也可以使用其他模型进行训练。4.CNN神经网络模型测试net_train.py文件提供的训练代码支持GPU训练。如果没有NVDIA显卡,安装了pytorch版本对应的CUDA库,默认使用CPU训练。两种训练方法作者都试过了,如下是训练对比情况:数据量:2286张40*40单通道字符图像batch_size:50epoch:200设备时间GTX1070TI25sAMDR74750UPRO4min总结,数据量大,如果可以的话,使用显卡进行GTX显卡训练,训练效率比CPU高一个数量级【cuda安装文章链接】(https://www.cnblogs.com/yang520ming/p/10677110.html)下面是cuda安装注意事项:1.更新nvida显卡驱动,然后看cuda版本2.找到pytorch对应的cuda版本安装train方法代码如下:deftrain_gpu():use_cuda=torch.cuda.is_available()if(use_cuda):print("usegpucuda")else:print("usecpu")device=torch.device("cuda:0"ifuse_cudaelse"cpu")net=Net()net.to(device)#随机梯度descentopt=optim.SGD(net.parameters(),lr=0.01)#迭代数据200次epoch=200#单批数据为50batch_size=50trainloader=data.trainloader(batch_size)st=datetime.datetime.now()loss=0foreinrange(epoch):forstep,dinenumerate(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次迭代或第一个batchstep数据输出损失值if(e%50==0orstep==1):print("e:{},step:{},loss:{}".format(e,step,loss))print("loss:{}".format(loss))#输出训练时间print("costtime:",datetime.datetime.now()-st)#保存模型saveModel(net,opt)说明见上面代码注释。如果理解概念有问题,请再看up主的视频。作者我觉得很好:【神经网络学习与理解】(https://space.bilibili.com/504715181?spm_id_from=333.788.b_765f7570696e666f.1)下面是训练和测试过程的效果图:GPUmodel-trainingsetTraining:CPUmodel-trainingsetTraining:可以看出训练4分钟,迭代200次,模型趋于拟合效果,随着次数的增加梯度下降的更慢。事实上,经过100次迭代后,已经接近稳定振荡,loss值下降较慢,最终loss值为0.0016,拟合效果还不错。如果增加训练数据量,迭代次数,优化一些字符串的切割,可以提升模型的效果。读者可自行练习。CPU模型-测试集测试:看net_test.py中的代码,可以看到152个字符,准确率97%,部分字符切割问题会导致准确率下降,但问题不大,基本达到可用性个人项目水平,nice~~5.CNN神经网络模型预测与部署经过1、2、3步循环过程,可以使用相对稳定的模型对预测集进行预测。因为过拟合的问题,有些模型在测试集上可能表现比较好,在测试的时候效果不是很好。这里需要对训练数据和模型参数进行整理。CPU模型-预测集测试:代码如上图net_usage.py中所示。可以看到五个验证码的字符都预测正确了。CPU模型-部署:使用python的web框架FlaskAPI,编写图片验证码识别POST接口,传入文件路径,启动web应用。下面是通过本地文件路径识别接口的代码。详细代码见net_flask.py@app。路线('/recognize/path',methods=['POST'])defrecognize_path():filePathList=request.json['filePathList']code=CODE_SUCCESSmsg=MSG_SUCCESSdata=[]forfilePathinfilePathList:ifnotos.path.exists(filePath):#code=CODE_FAIL#msg="文件不存在"print("文件不存在:",filePath)data.append("")continueelse:labels=usage_model.usage(filePath)data.append(''.join(labels))result={'code':code,"msg":msg,"data":data}returnjsonify(result)模型-FlaskWebApp启动效果:Postman接口测试效果:网页批量请求-预测:OK,以上就是笔者图片验证码识别案例中卷积神经网络模型训练、测试和部署的全部内容。总的来说,从结果来看,模型的预测效果还是很不错的。首先,使用标签系统手动标记初始数据。收集下载数据集,然后准备数据集,然后进行模型的编码、训练和测试,然后用训练好的模型对数据进行预测,再通过人工判断加入训练集和校正,从而节省时间和成本。有效增加训练数据量。6.总结大家好,我是雪球。看完这些文章,读者就会熟悉CNN神经网络在图像特征提取方面的魅力。激活函数、随机梯度下降法、损失函数、反向传播等机制调整复杂非线性模型的参数,使得训练和处理的模型的概率分布尽可能接近人类标注数据的概率模型脑。当然,读者觉得这里还有很多疑问和问题。请不要气馁。机器学习和神经网络整个知识体系非常庞大。从数学理论到计算机算法再到工程框架,循序渐进。隐藏,请保持好奇和思考,不断的去了解和学习,以后可能等知识积累到一定程度,很多问题就会明白和明白了。说的有点多了,哈哈,总之,信息时代让网络资源得到合理利用。
