目标识别项目实战:基于Yolov7-LPRNet的动态车牌目标识别算法模型(二)


前言

目标识别如今以及迭代了这么多年,普遍受大家认可和欢迎的目标识别框架就是YOLO了。按照官方描述,YOLOv8 是一个 SOTA 模型,它建立在以前 YOLO 版本的成功基础上,并引入了新的功能和改进,以进一步提升性能和灵活性。从基本的YOLOv1版本到如今v8版本,完成了多次蜕变,现在已经相当成熟并且十分的亲民。我见过很多初学目标识别的同学基本上只花一周时间就可以参照案例实现一个目标检测的项目,这全靠YOLO强大的解耦性和部署简易性。初学者甚至只需要修改部分超参数接口,调整数据集就可以实现目标检测了。但是我想表达的并不是YOLO的原理有多么难理解,原理有多难推理。一般工作中要求我们能够运行并且能够完成目标检测出来就可以了,更重要的是数据集的标注。我们不需要完成几乎难以单人完成的造目标检测算法轮子的过程,我们需要理解YOLO算法中每个超参数的作用以及影响。就算我们能够训练出一定准确度的目标检测模型,我们还需要根据实际情况对生成结果进行一定的改写:例如对于图片来说一共出现了几种目标;对于一个视频来说,定位到具体时间出现了识别的目标。这都是需要我们反复学习再练习的本领。

完成目标检测后,我们应该输出定位出来的信息,YOLO是提供输出设定的超参数的,我们需要根据输出的信息对目标进行裁剪得到我们想要的目标之后再做上层处理。如果是车牌目标识别的项目,我们裁剪出来的车牌就可以进行OCR技术识别出车牌字符了,如果是安全帽识别项目,那么我们可以统计一张图片或者一帧中出现检测目标的个数做出判断,一切都需要根据实际业务需求为主。本篇文章主要是OCR模型对车牌进行字符识别,结合YOLO算法直接定位目标进行裁剪,裁剪后生成OCR训练数据集即可。开源项目地址,如果有帮助希望不吝点亮star~

基于Yolov7-LPRNet的动态车牌目标识别算法模型icon-default.png?t=N7T8https://github.com/Fanstuck/Yolov7-LPRNet

其中数据集的质量是尤为重要的,决定了模型的上限,因此想要搭建一个效果较好的目标识别算法模型,就需要处理流程较为完善的开源数据集。本篇文章采用的是CCPD数据集,上篇文章已经详细描述了整个项目的初步搭建过程,包括数据集准备和数据预处理,大体系统框架和数据标签聚合。现在开始正式YOLOv7搭建。


一、YOLOv7

YOLO算法作为one-stage目标检测算法最典型的代表,其基于深度神经网络进行对象的识别和定位,运行速度很快,可以用于实时系统。从近几年来看,模型结构重参化和动态标签分配已经成为了目标检测领域中的主要优化方向。针对于结构重参化,YOLOv7的作者是通过分析梯度的传播路径来为网络中的不同层进行结构重参化优化,作者还提出了扩展和复合缩放的方式,通过这种方式可以更高效利用参数量和计算量。这样不仅可以减少大量参数,还可以提高推理速度以及检测精度。

我们这里不作展开Yolov7详解,开源项目里面自带大家可直接克隆就好,省去了一些冗余功能。但是github上面的版本删去了训练模块,提供了已经训练完成的模型和推理模型,这样克隆方便展示直接效果,训练的权重并不是最优的,本身并没有迭代多次,想要精度更高的模型我将会在后续硬件支持下再训练,或者大家也可以去下载别人已经训练好的模型。大家如有需要可以通过网盘下载:

链接:https://pan.baidu.com/s/1rjkwqC0p5kp43WP8EnMwqw
提取码:40yu
我会在本篇文章详细介绍模型权重的具体训练过程。

二、训练步骤

1.安装环境

利用Yolo训练模型十分简单并没有涉及到很复杂的步骤,如果是新手的话注意下载的torch版本是否符合本身NVDIA GPU的版本,需要根据NVIDIA支持最高的cuda版本去下载兼容的Torch版本,查看cuda版本可以通过终端输入:nvidia-smi

确定requirements.txt没问题之后,直接通过pip下载环境即可:

pip install -r requirements.txt

 2.修改Yolo配置文件

首先增加cfg/training/yolov7-e6e-ccpd.yaml文件,此配置文件可以参数动态调整网络规模,这里也不展开细讲,以后会有Yolov7源码详解系列,敬请期待,我们需要根据我们用到的官方yolo模型选择对于的yaml文件配置,我这里用的的yolov7-e6e模型训练,所以直接拿yolov7-e6e.yaml改写:

# parameters
nc: 1  # number of classes
depth_multiple: 1.0  # model depth multiple
width_multiple: 1.0  # layer channel multiple

其中nc是检测个数,depth_multiple是模型深度,width_multiple表示卷积通道的缩放因子,就是将配置里面的backbone和head部分有关Conv通道的设置,全部乘以该系数。通过这两个参数就可以实现不同复杂度的模型设计。然后是添加数据索引文件data/license.yaml:

train: ./split_dataset/images/train  
val: ./split_dataset/images/val 
test: ./split_dataset/images/test # number of classes
nc : 1#class names
names : ['license']

3.训练模型

前面train,val,test都对应着目录存放的训练数据集。之后修改train.py中的参数或者是直接在终端输入对应的参数自动目录,我一般是习惯直接在defalut下面修改,parser的各类参数功能为:

#weight:指定预训练权重路径;如果这里设置为空的话,就是自己从头开始进行训练;官方有提供预训练权重
#cfg:指定模型配置文件路径的;源码里面提供了几个配置文件,配置文件里面指定了一些参数信息和backbone的结构信息。
#data:数据集对应的参数文件;里面主要存放数据集的类别和路径信息。
#hyp:指定超参数文件的路径;超参数里面包含了大量的参数信息。
#epochs:训练的轮数;默认为300轮,显示效果是0-299
#batch-size:每批次的输入数据量;default=-1将时自动调节batchsize大小
#img-size:训练集和测试集图片的像素大小;输入默认640*640,可以进行适当的调整,这样才能达到好的效果。
#rect:是否采用矩阵推理的方式去训练模型。
#resume:断点续训:即是否在之前训练的一个模型基础上继续训练,default 值默认是 false;
#nosave:是否只保存最后一轮的pt文件;我们默认是保存best.pt和last.pt两个的;
#notest:只在最后一轮测试;正常情况下每个epoch都会计算mAP,但如果开启了这个参数,那么就只在最后一轮上进行测试,不建议开启。
#noautoanchor:是否禁用自动锚框;默认是开启的,自动锚点的好处是可以简化训练过程。
#evolve:遗传超参数进化;yolov7使用遗传超参数进化,提供的默认参数是通过在COCO数据集上使用超参数进化得来的。由于超参数进化会耗费大量的资源和时间,所以建议不要动这个参数。
#bucket:谷歌云盘;通过这个参数可以下载谷歌云盘上的一些东西,但是现在没必要使用了。
#cache:是否提前缓存图片到内存,以加快训练速度,默认False;开启这个参数就会对图片进行缓存,从而更好的训练模型。
#image-weights:是否启用加权图像策略,默认是不开启的;主要是为了解决样本不平衡问题;开启后会对上一轮训练效果不好的图片,在下一轮中增加一些权重;
#device:设备选择;这个参数就是指定硬件设备的,系统会自己判断。
#multi-scale:是否启用多尺度训练,默认是不开启的;多尺度训练是指设置几种不同的图片输入尺度,训练时每隔一定iterations随机选取一种尺度训练,这样训练出来的模型鲁棒性更强。
#single-cls:设定训练数据集是单类别还是多类别;默认为 false多类别。
#optimizer:选择使用 Adam 优化器
#sync-bn:是否开启跨卡同步BN;开启参数后即可使用 SyncBatchNorm多 GPU 进行分布式训练。
#local_rank:DDP参数,请勿修改
#workers:最大worker数量。
#project:指定训练好的模型的保存路径;默认在runs/train。
#entity:wandb 库对应的东西。
#name:设定保存的模型文件夹名,默认在exp;
#exist-ok:每次预测模型的结果是否保存在原来的文件夹;如果指定了这个参数的话,那么本次预测的结果还是保存在上一次保存的文件夹里;如果不指定就是每次预测结果保存一个新的文件夹下。
#quad:官方给出的开启这个功能后的实际效果:#好处是在比默认 640 大的数据集上训练效果更好#副作用是在 640 大小的数据集上训练效果可能会差一些
#linear-lr:用于调整学习率;含义是通过余弦函数来降低学习率。使用梯度下降算法来优化目标函数的时候,当越来越接近Loss值的全局最小值时,学习率应该变得更小来使得模型尽可能接近这一点,而余弦退火可以通过余弦函数来降低学习率。
#label-smoothing:是否对标签进行平滑处理,默认是不启用的;
#upload_dataset:wandb 库对应的东西。是否上传dataset到wandb tabel(将数据集作为交互式 dsviz表 在浏览器中查看、查询、筛选和分析数据集) 默认False
#bbox_interval:wandb 库对应的东西,可以忽略。设置界框图像记录间隔 Set bounding-box image logging interval for W&B 默认-1
#save-period:用于设置多少个epoch保存一下checkpoint,int 型,默认为 -1。
#artifact_alias:表示还未实现的内容,忽略即可if __name__ == '__main__':parser = argparse.ArgumentParser()parser.add_argument('--weights', type=str, default='yolo7.pt', help='initial weights path')parser.add_argument('--cfg', type=str, default='', help='model.yaml path')parser.add_argument('--data', type=str, default='data/coco.yaml', help='data.yaml path')parser.add_argument('--hyp', type=str, default='data/hyp.scratch.p5.yaml', help='hyperparameters path')parser.add_argument('--epochs', type=int, default=300)parser.add_argument('--batch-size', type=int, default=16, help='total batch size for all GPUs')parser.add_argument('--img-size', nargs='+', type=int, default=[640, 640], help='[train, test] image sizes')parser.add_argument('--rect', action='store_true', help='rectangular training')parser.add_argument('--resume', nargs='?', const=True, default=False, help='resume most recent training')parser.add_argument('--nosave', action='store_true', help='only save final checkpoint')parser.add_argument('--notest', action='store_true', help='only test final epoch')parser.add_argument('--noautoanchor', action='store_true', help='disable autoanchor check')parser.add_argument('--evolve', action='store_true', help='evolve hyperparameters')parser.add_argument('--bucket', type=str, default='', help='gsutil bucket')parser.add_argument('--cache-images', action='store_true', help='cache images for faster training')parser.add_argument('--image-weights', action='store_true', help='use weighted image selection for training')parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')parser.add_argument('--multi-scale', action='store_true', help='vary img-size +/- 50%%')parser.add_argument('--single-cls', action='store_true', help='train multi-class data as single-class')parser.add_argument('--adam', action='store_true', help='use torch.optim.Adam() optimizer')parser.add_argument('--sync-bn', action='store_true', help='use SyncBatchNorm, only available in DDP mode')parser.add_argument('--local_rank', type=int, default=-1, help='DDP parameter, do not modify')parser.add_argument('--workers', type=int, default=8, help='maximum number of dataloader workers')parser.add_argument('--project', default='runs/train', help='save to project/name')parser.add_argument('--entity', default=None, help='W&B entity')parser.add_argument('--name', default='exp', help='save to project/name')parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')parser.add_argument('--quad', action='store_true', help='quad dataloader')parser.add_argument('--linear-lr', action='store_true', help='linear LR')parser.add_argument('--label-smoothing', type=float, default=0.0, help='Label smoothing epsilon')parser.add_argument('--upload_dataset', action='store_true', help='Upload dataset as W&B artifact table')parser.add_argument('--bbox_interval', type=int, default=-1, help='Set bounding-box image logging interval for W&B')parser.add_argument('--save_period', type=int, default=-1, help='Log model after every "save_period" epoch')parser.add_argument('--artifact_alias', type=str, default="latest", help='version of dataset artifact to be used')parser.add_argument('--freeze', nargs='+', type=int, default=[0], help='Freeze layers: backbone of yolov7=50, first3=0 1 2')parser.add_argument('--v5-metric', action='store_true', help='assume maximum recall as 1.0 in AP calculation')

对应参数修改,一般来说修改这些就足够了:

parser.add_argument('--weights', type=str, default='weights/yolo7-e6e.pt', help='initial weights path')
parser.add_argument('--cfg', type=str, default='cfg/yolov7-e6e-ccpd', help='model.yaml path')
parser.add_argument('--data', type=str, default='data/license.yaml', help='data.yaml path')

当然也可能出现内存溢出等问题,需要修改:

arser.add_argument('--batch-size', type=int, default=16, help='total batch size for all GPUs')
parser.add_argument('--workers', type=int, default=8, help='maximum number of dataloader workers')

 这两个参数,具体参数根据自己硬件条件修改。

然后直接终端输入:

python train.py

 训练即可。生成的模型会自动保存到run/目录里面。之后在run/train/exp/weights目录下会产生两个权重文件,一个是最后一轮的权重文件,一个是最好的权重文件,一会我们就要利用这个最好的权重文件来做推理测试。除此以外还会产生一些验证文件的图片等一些文件。

4.推理

 然后修改detect.py:

f __name__ == '__main__':
"""
--weights:权重的路径地址
--source:测试数据,可以是图片/视频路径,也可以是'0'(电脑自带摄像头),也可以是rtsp等视频流
--output:网络预测之后的图片/视频的保存路径
--img-size:网络输入图片大小
--conf-thres:置信度阈值
--iou-thres:做nms的iou阈值
--device:是用GPU还是CPU做推理
--view-img:是否展示预测之后的图片/视频,默认False
--save-txt:是否将预测的框坐标以txt文件形式保存,默认False
--classes:设置只保留某一部分类别,形如0或者0 2 3
--agnostic-nms:进行nms是否也去除不同类别之间的框,默认False
--augment:推理的时候进行多尺度,翻转等操作(TTA)推理
--update:如果为True,则对所有模型进行strip_optimizer操作,去除pt文件中的优化器等信息,默认为False
--project:推理的结果保存在runs/detect目录下
--name:结果保存的文件夹名称
"""parser = argparse.ArgumentParser()parser.add_argument('--weights', nargs='+', type=str, default='yolov5s.pt', help='model.pt path(s)')parser.add_argument('--source', type=str, default='data/images', help='source')  # file/folder, 0 for webcamparser.add_argument('--img-size', type=int, default=640, help='inference size (pixels)')parser.add_argument('--conf-thres', type=float, default=0.25, help='object confidence threshold')parser.add_argument('--iou-thres', type=float, default=0.45, help='IOU threshold for NMS')parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')parser.add_argument('--view-img', action='store_true', help='display results')parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels')parser.add_argument('--nosave', action='store_true', help='do not save images/videos')parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --class 0, or --class 0 2 3')parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')parser.add_argument('--augment', action='store_true', help='augmented inference')parser.add_argument('--update', action='store_true', help='update all models')parser.add_argument('--project', default='runs/detect', help='save results to project/name')parser.add_argument('--name', default='exp', help='save results to project/name')parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')opt = parser.parse_args()

 这里需要将刚刚训练好的最好的权重传入到推理函数中去。然后就可以对图像视频进行推理了。

主要需要修改的参数是:

parser.add_argument('--weights', nargs='+', type=str, default='runs/train/exp/weights/best.pt', help='model.pt path(s)')parser.add_argument('--source', type=str, default='测试数据集目录或者图片', help='source') 

 推理测试结束以后,在run下面会生成一个detect目录,推理结果会保存在exp目录下。

 


备注

有问题的私信博主或者直接评论就可以了博主会长期维护此开源项目,目前此项目运行需要多部操作比较繁琐,我将不断更新版本优化,下一版本将加入UI以及一键部署环境和添加sh指令一键运行项目代码。下篇文章将详细解读LPRNet模型如何进行OCR识别, 再次希望对大家有帮助不吝点亮star~

基于Yolov7-LPRNet的动态车牌目标识别算法模型icon-default.png?t=N7T8https://github.com/Fanstuck/Yolov7-LPRNet

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/96430.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

零基础如何自学网络安全,基于就业前景全方位讲解,包教包会

你是否对网络空间安全充满好奇?想要解开网络世界神秘的面纱?你是否对黑客技术着迷?而找不到合适的学习途径?你是否遭到过各种各样的网络攻击,却因知识的匮乏束手无策? 那么接下来将为你全面介绍&#xff0c…

优化器optimizer

用来更新和计算影响模型训练和模型输出的网络参数,使其逼近或达到最优值,从而最小化(或最大化)损失函数。 总结 从SGD到Adam做了哪些改进自适应的学习率、动量 从SGD到Adam做了哪些改进Adamw 即 Adam + weight decate ,效果与 Adam + L2正则化相同,但是计算效率更高,因为L2正则…

css--踩坑

1. 子元素的宽高不生效问题 设置flex布局后,子元素的宽高不生效问题。 如果希望子元素的宽高生效,解决方法,给子元素添加如下属性: flex-shrink: 0; flex-shrink: 0;2. 横向滚动(子元素宽度不固定) /* tab…

Centos7升级OpenSSH9.1

最近遇到了服务器漏洞,需要对服务器的OpenSSH版本进行升级,查阅了相关资料,总结出了一套比较简单的方案。中间遇到的个别问题也进行了记录,供大家参考。 下载准备 从https://ftp.jaist.ac.jp/pub/OpenBSD/OpenSSH/portable/opens…

mysql 逻辑备份 恢复数据

一、逻辑备份 逻辑备份:备份的是建表,建库,插入数据等操作所执行SQL语句,适用于中小型数据库,效率相对较低,提供三种级别的备份,表级,库级和全库级。 本质:导出的是SQL语…

【外汇天眼】携手共护外汇投资:2023年WikiFX晚宴首次在越南圆满举行

9月23日,WikiFX在越南与Wsaas合作举办了一场晚宴,以此表达对合作伙伴的感谢。此次晚会不仅仅是各位行业精英聚一起分享经验、了解行业动向的机会,也是WikiFX在越南分部第一次思考与复盘的活动。 回顾过去——WikiFX在越南的四年 从2019年开始…

linearlayout中使用多个weight导致部分子控件消失异常

问题描述: 在一个linearlayout中写了两个用到weight的布局,在androidstudio中显示正常 但是代码跑起来之后最下面哪一行都消失了; 解决办法1 把两个用到weight的改成一个了,外面那层的weight写成固定宽度就能正常显示出丢失的…

软件设计师考试错题

删除线格式 1. 192.168.37.192/25是什么地址 知识点:主机号全为0的ip成为网络地址,全为1的ip地址成为定向广播地址,都不能做源地址。 192.168.37.192/25表示前25位为网络号,后7位为主机号,192.168.37.11000000 2. 如果…

LRU 缓存 -- 哈希链表

相关题目 146. LRU 缓存 要让 put 和 get ⽅法的时间复杂度为 O(1),我们可以总结出 cache 这个数据结构必要的条件: 1、显然 cache 中的元素必须有时序,以区分最近使⽤的和久未使⽤的数据,当容量满了之后要删除最久未使⽤的那个元…

Shibuya109 109 可穿戴系列来啦!

准备好用 “SHIBUYA109”可穿戴系列来提升你们的时尚感。该系列包含各种时尚相关单品,从 9 月 26 日起也将在 SHIBUYA109 体验中提供。用大量尖端的日本时尚单品来装扮你的人物化身吧。 探索元宇宙中 SHIBUYA109 的世界,穿上可爱的时尚单品,…

python scanpy spatial空转全流程

Spatial mapping of cell types across the mouse brain (1/3) - estimating reference expression signatures of cell types — cell2location documentation Spatial mapping of cell types across the mouse brain (2/3) - cell2location — cell2location documentation #…

深度学习基础之GFLOPS(2)

什么是GFLOPS 神经网络的GFLOPS(Giga FLoating-Point Operations Per Second)代表了神经网络模型执行计算的速度和计算能力。这可以用一个类比来解释: GFLOPS就像神经网络模型的"运算速度"标签。 想象你有两个数学家&#xff0c…

uniapp:动态修改页面标题

我们经常遇到这种情况,点击新增按钮,进入一个空白表单页面,点击修改按钮,其实也是进入这个表单页面,只是表单内容已经被数据库的记录反显了,为了区别页面,我们还需要动态设置页面的标题&#xf…

期望最大化(EM)算法:从理论到实战全解析

目录 一、引言概率模型与隐变量极大似然估计(MLE)Jensen不等式 二、基础数学原理条件概率与联合概率似然函数Kullback-Leibler散度贝叶斯推断 三、EM算法的核心思想期望(E)步骤最大化(M)步骤Q函数与辅助函数…

【Spring笔记05】Spring的自动装配

这篇文章,主要介绍的内容是Spring的自动装配、五种自动装配的方式。 目录 一、自动装配 1.1、什么是自动装配 1.2、五种自动装配方式 (1)no (2)default (3)byType (4&#xf…

Ansys Optics Launcher 提升客户体验

概述 为了改善用户体验,Ansys Optics 团队开发了一个新的一站式启动应用程序,简化了工作流程并提高了效率。随着Ansys 2023 R2的最新更新,Ansys Optics Launcher 现已安装在Ansys Speos, Ansys Lumerical和Ansys Zemax OpticStudio中。作为一…

React Hooks—— context hooks

什么是Hooks Hooks从语法上来说是一些函数。这些函数可以用于在函数组件中引入状态管理和生命周期方法。 React Hooks的优点 简洁 从语法上来说,写的代码少了上手非常简单 基于函数式编程理念,只需要掌握一些JavaScript基础知识与生命周期相关的知识不…

Docker之Dockerfile搭建lnmp

目录 一、搭建nginx ​编辑 二、搭建Mysql(简略版) 三、搭建PHP 五、补充 主机名ip地址主要软件mysql2192.168.11.22Docker 代码示例 systemctl stop firewalld systemctl disable firewalld setenforce 0docker network create --subnet172.18.…

OWASP Top 10漏洞解析(3)- A3:Injection 注入攻击

作者:gentle_zhou 原文链接:OWASP Top 10漏洞解析(3)- A3:Injection 注入攻击-云社区-华为云 Web应用程序安全一直是一个重要的话题,它不但关系到网络用户的隐私,财产,而且关系着用户对程序的新…

十进制分钟转时间类型

/*** 十进制分钟转时间类型** param decimalTime 十进制分钟数*/public static String tenToDate(int decimalTime) {// int decimalTime 3695; // 十进制时间数int hours decimalTime / 3600;int minutes (decimalTime % 3600) / 60;int seconds decimalTime % 60;Decimal…