popyone
发布于 2023-08-27 / 31 阅读
0
0

从接触深度学习开始

#AI

从接触深度学习开始

开始

    最开始接触到深度学习的时候,自己对Python这门语言的使用还是停留在爬虫的应用上。2021年底,公司提出要自己开发证件识别接口,java研发们较劲脑子的去找能落地到私有化部署的方案,但实际上互联网的很多方案是使用大厂的API来实现的,我们比较了很多方案,最终选取了OpenCV的java方案,文字识别采用我提供的paddle飞浆paddlehub中的文字识别接口。方案开始到结束很顺利,因为缺少大量样本人工检查,在使用了少量验证后,项目上线了。

    在这里,是我第一次接触百度的paddle框架中的paddlehub,在此使用期间,还是对深度学习的概念比较模糊,停留在文字识别、人脸识别基础的使用,对模型和预训练模型的概念理解不清晰,先对深度学习的相关术语做个记录:

  • 模型 架构与一组特定参数的组合
  • 架构 要传递输入数据和参数的实际数学函数,也是尝试去拟合模型的模板
  • 标签 目标或者因变量(身份证上的姓名、住址、身份证号等)
  • 参数 模型中的值,根据执行任务进行改变,并通过模型训练更新
  • 拟合 更新模型的参数,让使用输入数据的模型的预测与目标标签匹配
  • 训练 和拟合表现的是一个意思
  • 预训练模型 已经使用大型数据集训练过的模型,并且之后可以对其进行微调
  • 微调 针对不同任务优化预训练模型
  • 周期 对所有输入数据进行一轮完整训练
  • 权重 可以被称为参数
  • 自变量 计算得出预测,预测包含数据,不包含标签
  • 预测 模型的输出结果
  • 模型的性能 性能评估结果可以称为损失(loss)
  • 损失 对模型的质量进行评估的指标,不仅取决于预测,也和正确的标签高度相关
  • 指标 用验证集对模型进行评价
  • 验证集 一组不包含在训练集中的数据,仅用于衡量模型的效果
  • 训练集 用于拟合(训练)模型的数据,不包含验证集中的任何数据
  • 过拟合 以一种可以记住输入数据特定特征的方式来训练模型,其不能很好的泛化到训练期间未见到过的数据
  • CNN 卷积神经网络,一种对计算机视觉任务特别有效的神经网络

出现问题

    看到这里,仔细看了相关术语的人,应该知道我们身份证识别系统出现的问题在哪里了,验证集数量不够,采用的很多是网络上的虚拟身份证图片,其中的细节和真实的身份证还有一定的区别。当用户开始使用后发现,大量身份证无法识别,返回的错误有两种,接口不可用、无法识别;

  • 第一个问题是java版使用OpenCV出现无限循环,引起内存超过阈值(3G),被kubernetes直接杀掉重启了,通过询问研发,得知程序采取了旋转的方式,将身份证的角度旋转到水平位置,如果无法旋转确认是否到水平,就会无限制旋转下去,造成内存激增,引发kubernetes的内存限制;
  • 第二个问题,识别结果是一组文字,如何从文字中获取姓名、身份证号,程序采用的是人工筛选,按照演练测试的文字顺序去解析这一组文字,但实际情况是这组文字的顺序可能有很多种的,返回的结果就不是想要得到的;

解决

    出现这个问题,公司研发部需要马上解决,不然会影响到项目上线。经过一个多星期的研究,使用java无法解决这个问题,决定用我上次写的Python来处理身份证旋转水平的问题,通过测试,这个Python的实现方法能正常识别姓名和证件号(从自己心里上讲,这个程序我并没有吃透,对模型的加载和使用停留在浅层,识别时间比较长,每张身份证识别需要3秒以上)。新的程序很快部署上线了,通过了验收。

深入学习

    我们这个项目,使用身份证识别的人并不多,一直没有人反馈问题,但是,通过日志监控发现,程序paddlehub的接口一直在重启(内存用量超过3G),在缺乏时间和处理方法的情况下,采用了daemon分配,一个node启动一个paddlehub,启动了3个paddlehub接口,这样的话,识别程序充气的项目使用身份证识别的时候就不会受到程序重启的影响。
    时间来到了2023年,年初的大模型ChatGPT3.5向人们展示了强大的自然语言处理能力,这激起了国内一股AIGC的热潮,公司允许我们在做完了手里工作的情况去学习研究这些知识。这个时候,我可以将工作任务完成后时间,用于学习paddle以及其他开源模型,通过一次一次的预训练模型使用、数据标注、预训练模型微调,搞明白了模型的原理;
    我们的模型使用cpu预测(云服务器支持avx),需要加载到内存,每增加一个线程,就多加载一次模型,自然内存使用量就会非常大,当内存使用量超过pod(kubernetes)限制的时候,就被kill掉重启了;
    明白了这个问题后,我重构了整套身份证识别系统,将旋转到水平和paddlehub两个接口合二为一,添加了住址识别(因为是通过人工处理,只处理了两行住址),程序运行架构改为:

  • 程序启动的时候将paddlehub模型加载到内存
  • 每个程序单线程运行
  • 程序运行在3个node上

    这样程序运行起来了,每个程序加载了三个mobile模型:“头像识别、文字位置识别、文字识别”,启动后内存使用2.5G,多次识别不会再增加内存使用量,每次识别时间0.9xx秒以内,识别成功率增加(增加了通过头像识别旋转身份证,减少了拍照角度的影响)。

总结

    到此,我完成了一个手动的身份证识别的程序,学习到了很多AI的基础术语和概念。但其实呢,我们从开始就绕了弯路,最直接的方式,是微调UIE(通用信息抽取)模型,通过真实有效的身份证数据,来微调模型,让模型转成一个专门针对身份证识别的任务模型。这是我的第二步学习的方向;目前通过标注和微调实现了聊天数据的关键信息抽取,语义方向的定义。
    这是我的博客第一次录入这么多纯文字的文章,下来我会不定期总结自己AI的学习之路,记录下来方便自己查阅。


评论