前言
方针辨认现在以及迭代了这么多年,遍及受咱们认可和欢迎的方针辨认结构便是YOLO了。依照官方描绘,YOLOv8 是一个 SOTA 模型,它建立在以前 YOLO 版别的成功基础上,并引入了新的功用和改进,以进一步提升性能和灵活性。从根本的YOLOv1版别到现在v8版别,完结了屡次蜕变,现在现已恰当老练并且十分的亲民。
我见过很多初学方针辨认的同学根本上只花一周时刻就能够参照案例完成一个方针检测的项目,这全靠YOLO强壮的解耦性和布置简易性。初学者甚至只需求修正部分超参数接口,调整数据集就能够完成方针检测了。
可是我想表达的并不是YOLO的原理有多么难了解,原理有多难推理。一般工作中要求咱们能够运转并且能够完结方针检测出来就能够了,更重要的是数据集的标示。咱们不需求完结简直难以单人完结的造方针检测算法轮子的进程,咱们需求了解YOLO算法中每个超参数的作用以及影响。
就算咱们能够练习出必定准确度的方针检测模型,咱们还需求依据实践情况对生成成果进行必定的改写:例如关于图片来说总共出现了几种方针;关于一个视频来说,定位到详细时刻出现了辨认的方针。这都是需求咱们重复学习再练习的本领。
完结方针检测后,咱们应该输出定位出来的信息,YOLO是供给输出设定的超参数的,咱们需求依据输出的信息对方针进行裁剪得到咱们想要的方针之后再做上层处理。假如是车牌方针辨认的项目,咱们裁剪出来的车牌就能够进行OCR技能辨认出车牌字符了,假如是安全帽辨认项目,那么咱们能够核算一张图片或许一帧中出现检测方针的个数做出判断,一切都需求依据实践事务需求为主。
本篇文章首要是OCR模型对车牌进行字符辨认,结合YOLO算法直接定位方针进行裁剪,裁剪后生成OCR练习数据集即可。开源项目地址,假如有协助期望不惜点亮star~ :
其间数据集的质量是尤为重要的,决议了模型的上限,因而想要建立一个作用较好的方针辨认算法模型,就需求处理流程较为完善的开源数据集。本篇文章选用的是CCPD数据集,上篇文章现已详细描绘了整个项目的初步建立进程,包括数据集预备和数据预处理,大体体系结构和数据标签聚合。现在开始正式YOLOv7建立。
一、YOLOv7
YOLO算法作为one-stage方针检测算法最典型的代表,其依据深度神经网络进行对象的辨认和定位,运转速度很快,能够用于实时体系。
从近几年来看,模型结构重参化和动态标签分配现已成为了方针检测领域中的首要优化方向。针关于结构重参化,YOLOv7的作者是经过分析梯度的传达途径来为网络中的不同层进行结构重参化优化,作者还提出了扩展和复合缩放的方法,经过这种方法能够更高效运用参数量和核算量。这样不仅能够削减大量参数,还能够进步推理速度以及检测精度。
咱们这儿不作打开Yolov7详解,开源项目里边自带咱们可直接克隆就好,省去了一些冗余功用。可是github上面的版别删去了练习模块,供给了现已练习完结的模型和推理模型,这样克隆便利展现直接作用,练习的权重并不是最优的,自身并没有迭代屡次,想要精度更高的模型我将会在后续硬件支持下再练习,或许咱们也能够去下载他人现已练习好的模型。咱们如有需求能够经过网盘下载:
链接:pan.baidu.com/s/1rjkwqC0p…
提取码: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 webcam
parser.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~ :