ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

YOLOv5项目介绍

2021-05-26 22:52:19  阅读:317  来源: 互联网

标签:YOLOv5 maxDets 项目 -- IoU area 介绍 0.95 Average


YOLOv5 项目教程


作者:elfin  资料来源:YOLOv5

目录


1、前言

YOLOv5项目地址ultralytics/yolov5

​ 项目自发布以来,直到现在仍然在不断改进模型、项目。作者的更新频率很大,很多问题都能够及时解决,当然问题也很多!到写稿此时,项目的device参数仍然无法正常工作,查看源码,作者的代码写的GPU设备控制比较复杂,修改源码也没有解决,可能我里解决就差一步了吧!在项目提交bug后,得到作者的及时回应,但是最后仍然没有解决。难道使用GPU必须从GPU:0开始吗?查看bug请点击

  • ONNXOpen Neural Network Exchange

    开发式神经网络交换格式!

    它是深度学习模型的一种标准,可使模型在不同框架间转移

  • TensorRT

    英伟达官方提供的GPU版深度学习模型加速平台,可以和Tensor Serving一起部署模型,实现模型的快速运算,其特点是性能高、资源占用少。

1.1 模型训练

$ python train.py  --batch-size 64 --data coco.yaml --weights yolov5l.pt --device 0,1

使用 --device 0,1指定多个GPU是没有用的!会衰减计算速度。推荐多GPU使用数据并行的方法。

$ python -m torch.distributed.launch --nproc_per_node 2 train.py --batch-size 64 --data coco.yaml --weights yolov5x.pt
  • --nproc_per_node: 指定你的GPU节点数;

  • --batch-size:这里的批量是总的批量,实际每个GPU的的batch为 64/32.

    这里的处理方式和keras是一样的,采用数据并行可以提高我们的计算速度。

$ python -m torch.distributed.launch --nproc_per_node 2 train.py --batch-size 64 --data coco.yaml --cfg yolov5x.yaml --weights '' --device 2,3

数据并行运算的时候可以指定要使用的GPU: --device 2,3

$ python -m torch.distributed.launch --nproc_per_node 2 train.py --batch-size 64 --data coco.yaml --cfg yolov5x.yaml --weights '' --sync-bn

SyncBatchNorm多个GPU之间进行批量标准化!

​ 下面介绍将模型转为ONNX模型,使用TensorRT部署……


2、yolov5模型转ONNX模型

2.1 环境准备

$ git clone https://github.com/ultralytics/yolov5  # clone repo
$ cd yolov5
$ pip install -r requirements.txt  # base requirements
$ pip install onnx>=1.7.0  # for ONNX export
$ pip install coremltools==4.0  # for CoreML export

2.2 输出已训练的模型为ONNX模型

$ python models/export.py --weights yolov5x.pt --img 640 --batch 1  # export at 640x640 with batch size 1

export.py输出了三个模型,这里我们主要查看onnx模型!

使用https://netron.app/可以查看我们生成的ONNX模型结构。

文件中代码:

print('\nStarting ONNX export with onnx %s...' % onnx.__version__)
f = opt.weights.replace('.pt', '.onnx')  # filename
torch.onnx.export(model, img, f, verbose=False, opset_version=12, input_names=['images'],
                  output_names=['classes', 'boxes'] if y is None else ['output'])
# Checks
onnx_model = onnx.load(f)  # load onnx model
onnx.checker.check_model(onnx_model)  # check onnx model
# print(onnx.helper.printable_graph(onnx_model.graph))  # print a human readable model
print('ONNX export success, saved as %s' % f)
except Exception as e:
print('ONNX export failure: %s' % e)

torch.onnx.export()模型转换关键函数

关于torch.onnx的介绍见:https://pytorch.org/docs/stable/onnx.html


3、Test Time Augmentation (TTA)

添加命令行参数--augment实现测试、预测时的性能增强!

3.1 Test Normally

$ python test.py --weights yolov5x.pt --data coco.yaml --img 640

3.2 Test with TTA

$ python test.py --weights yolov5x.pt --data coco.yaml --img 832 --augment

3.3 Inference with TTA

$ python detect.py --weights yolov5s.pt --img 832 --source ./inference/images/ --augment

4、Model Ensembling模型嵌入

还记得决策树吗?而现在我们一般使用随机森林、LightGBM等模型。Ensembling的思想在深度学习模型中同样适应,这里我们对yolov5的不同模型进行融合,结果发现,预测显著性明显提升。

4.1 Test Normally

$ python test.py --weights yolov5x.pt --data coco.yaml --img 640

4.2 Ensemble Test

$ python test.py --weights yolov5x.pt yolov5l.pt --data coco.yaml --img 640

4.3 Ensemble Inference

$ python detect.py --weights yolov5x.pt yolov5l.pt --img 640 --source ./inference/images/

这里测试结果为:齐达内是人的概率从0.8上涨到0.9!


5、Pruning/Sparsity Tutorial 剪枝/稀疏教程

5.1 Test Normally

$ python test.py --weights yolov5x.pt --data coco.yaml --img 640
Average Precision  (AP) @[ IoU=0.50:0.95 | area=   all | maxDets=100 ] = 0.492 < -------- baseline mAP
Average Precision  (AP) @[ IoU=0.50      | area=   all | maxDets=100 ] = 0.676
Average Precision  (AP) @[ IoU=0.75      | area=   all | maxDets=100 ] = 0.534
Average Precision  (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.318
Average Precision  (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.541
Average Precision  (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.633
Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets=  1 ] = 0.376
Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets= 10 ] = 0.616
Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets=100 ] = 0.670 < -------- baseline mAR
Average Recall     (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.493
Average Recall     (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.723
Average Recall     (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.812

5.2 Test with 30% Pruned Model

我们现在用一个修剪过的模型重复上面的测试,设置修剪30%,这里我们需要修改test.py文件的torch_utils.prune(model, 0.3)

$ python test.py --weights yolov5x.pt --data coco.yaml --img 640
Average Precision  (AP) @[ IoU=0.50:0.95 | area=   all | maxDets=100 ] = 0.462 < -------- lower mAP
Average Precision  (AP) @[ IoU=0.50      | area=   all | maxDets=100 ] = 0.649
Average Precision  (AP) @[ IoU=0.75      | area=   all | maxDets=100 ] = 0.505
Average Precision  (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.293
Average Precision  (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.507
Average Precision  (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.602
Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets=  1 ] = 0.361
Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets= 10 ] = 0.590
Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets=100 ] = 0.643 < -------- lower mAR
Average Recall     (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.465
Average Recall     (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.691
Average Recall     (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.786

在结果中我们可以观察到,我们的模型在剪枝后达到了30%的稀疏性,这意味着30%的模型权重参数nn.Conv2d层等于0。测试时间(在P100 GPU上)保持不变,而模型的AP和AR分数略有降低。


6、 Hyperparameter Evolution超参数调优

超参数对模型的影响是很大的,但是具体是如何影响的,通过严格的数学推导我们是做不到的。科学家在如何获取最优参数的道路上做了很多尝试,遗传算法(GA)就是比较出名的存在。

6.1 初始化超参数

YOLOv5有大约25个用于各种训练设置的超参数。这些是在/data目录的yaml文件中定义的。更好的初始猜测将产生更好的最终结果,因此在演化之前正确初始化这些值是很重要的。如果有疑问,只需使用默认值,这是优化YOLOv5在COCO数据集的配置参数。

6.2 定义适应性函数

适应性是我们追求最大化的价值。在YOLOv5中,我们将默认适应度函数定义为度量的加权组合:mp@0.5贡献了10%、mp@0.5:0.95占其余90%。您可以根据需要调整这些值,也可以使用默认的适应度定义。

def fitness(x): 
    # Returns fitness (for use with results.txt or evolve.txt) 
    w = [0.0, 0.0, 0.1, 0.9]  # weights for [P, R, mAP@0.5, mAP@0.5:0.95] 
    return (x[:, :4] * w).sum(1) 

6.3 遗传算法演变

evolution是在一个我们寻求改进的基本场景下进行的。本例中的基本场景是使用预训练的yolov5对COCO128进行10个时期的微调。基本场景训练命令是:

$ python train.py --epochs 10 --data coco128.yaml --weights yolov5s.pt --cache

为了进化特定于这个场景的超参数,从我们在第6.1节中定义的初始值开始,并最大化第6.2节中定义的适应度,增加--evolve

# Single-GPU
python train.py --epochs 10 --data coco128.yaml --weights yolov5s.pt --cache --evolve

# Multi-GPU
for i in 0 1 2 3; do
  nohup python train.py --epochs 10 --data coco128.yaml --weights yolov5s.pt --cache --evolve --device $i > evolve_gpu_$i.log &
done

# Multi-GPU bash while (not recommended)
for i in 0 1 2 3; do
  nohup "$(while true; do python train.py ... --evolve --device $i; done)" > evolve_gpu_$i.log &
done

​ 主要的遗传算子是交叉变异。在这项工作中,使用了变异,以90%的概率和0.04的方差,根据所有前几代最好的父母的组合来创造新的后代。结果记录在yolov5中/evolve.txt,每一代都保存着最适合的后代于yolov5/runs/evolve/hyp_evolved.yaml中。

​ 我们建议至少300代进化才能获得最佳结果。请注意,进化通常是昂贵和耗时的,因为基本场景需要数百次训练,可能需要数百或数千个小时的GPU训练。

项目超参数进化说明


7、迁移学习冻结yolov5层

​ 本指南解释了如何在迁移学习时冻结YOLOv5层。迁移学习是一种有用的方法,可以快速地在新数据上重新训练模型,而不必重新训练整个网络。相反,一部分初始权重被冻结在原位,其余权重用于计算损失,并由优化器更新。这需要比正常训练更少的资源,并且允许更快的训练时间,尽管它也可能导致最终训练精度的降低。

Transfer Learning with Frozen Layers

7.1 冻结骨干网络

# Freeze 
freeze = []  # parameter names to freeze (full or partial) 
for k, v in model.named_parameters(): 
    v.requires_grad = True  # train all layers 
    if any(x in k for x in freeze): 
        print('freezing %s' % k) 
        v.requires_grad = False

查看模型的参数名:

for k, v in model.named_parameters():
    print(k)

# Output
model.0.conv.conv.weight
model.0.conv.bn.weight
model.0.conv.bn.bias
model.1.conv.weight
model.1.bn.weight
model.1.bn.bias
model.2.cv1.conv.weight
model.2.cv1.bn.weight
...
model.23.m.0.cv2.bn.weight
model.23.m.0.cv2.bn.bias
model.24.m.0.weight
model.24.m.0.bias
model.24.m.1.weight
model.24.m.1.bias
model.24.m.2.weight
model.24.m.2.bias

发现模型的backbone是0~9层,所以在freeze中添加这几层的name。

freeze = ['model.%s.' % x for x in range(10)]  # parameter names to freeze (full or partial)

7.2 冻结全部yolov5的layers

这个简单,你可以将name全部放入freeze中,也可以设置所以层v.requires_grad = False

7.3 总结

​ 冻结yolov5的backbone之后,GPU的占用率下降了20%,显存占用下降了40%+。训练其他数据即的性能指标下降了0.0021%,这种性能损失还是可以接受的。

既然训练非backbone部分训练时间更快,GPU占用、显存占用更少,是不是可以先训练非backbone部分,再一起训练呢?


8、TensorRT模型加速

yolov5里面涉及的一些结构在TensorRT里面还没有支持,这些结构要加速就只能自己用C++实现。使用C++编程对很多人来说都是非常麻烦的事情,这里借鉴TensorRTx项目进入这个领域。

TensorRTx旨在通过TensorRT网络定义API实现流行的深度学习网络。我们知道,TensorRT有内置的解析器,包括caffeparser、uffparser、onnxparser等,但当我们使用这些解析器时,常常会遇到一些“不支持的操作或层”问题,特别是一些最新的模型正在使用新型的层。

​ 我们为什么不跳过所有的解析器呢?我们只需要使用TensorRT网络定义API来构建整个网络,并不复杂。

​ 这个项目是为了熟悉TensorRT API,也为了分享和向社区学习。

​ 所有模型首先在pytorch/mxnet/tensorflow中实现,并导出一个权重文件xxx.wts然后使用TensorRT进行权值加载、网络定义和推理。一些pytorch实现可以在我的repo Pytorchx中找到,其余的来自热门的开源实现。

标签:YOLOv5,maxDets,项目,--,IoU,area,介绍,0.95,Average
来源: https://blog.51cto.com/u_15228753/2819937

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有