社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Git

实用目标检测器 | 性能超YoloV5,推理耗时不变(附github源码)

3D视觉工坊 • 5 年前 • 513 次点击  

点击上方“3D视觉工坊”,选择“星标”
干货第一时间送达

计算机视觉研究院专栏

作者:Edison_G

PP-YOLO的一次升级,从PP-YOLO出发,通过增量消融方式逐步添加有助于性能提升且不增加推理耗时的措施,取得了更佳的性能(49.5%mAP)-速度(69FPS)均衡,并优于YOLOv4与YOLOv5。
一、简要

在实际应用场景中,有效性与高效性对于目标检测器非常重要。为了满足这两个问题,研究者全面评估了现有的改进的集合,以提高PP-YOLO的性能,同时几乎保推理时间不变

百度研究者对现有改进措施进行了分析并通过增强消融研究评估了其对最终模型的影响,此外,那些不起作用的也进行了讨论。通过组合多种有效改进,将PP-YOLO在COCO2017 test-dev数据上的性能从45.9%mAP提升到了49.5%mAP,并将所得到的模型称之为PP-YOLOv2。在推理速度方面,PP-YOLOv2可以达到68.9FPS(输入尺寸为640*640);采用Paddle推理引擎+TensorRT+FP16+bs1,可以进一步将PP-YOLOv2的推理速度提升到106.5FPS。优秀的性能完全超越了同等参数量的YOLOv4-CSP、YOLOv5l等模型。除此之外,采用ResNet101为主干网络的PP-YOLOv2可以在COCO2017 test-dev数据集上取得50.3%mAP。

二、背景及PP-YOLO

目标检测是各种现实世界应用程序的一个关键组成部分,如自动驾驶、人脸识别和人的重识别。近年来,随着深度卷积神经网络(CNNs)的兴起,目标探测器的性能得到了迅速的提高。虽然最近的工作集中在新的检测pipeline(即 Cascade RCNN和HTC),复杂的网络架构设计(DetectoRS和CBNET)推动了最先进的目标检测方法,YOLOv3仍然是工业中使用最广泛的检测器之一。因为,在各种实际应用中,不仅计算资源有限,而且软件支持不足。没有必要的技术支持,two-stage检测器(如Faster RCNN,Cascade RCNN)可能会非常慢。

同时,在YOLOv3和two-stage检测器的精度之间存在着显著的差距。因此,如何在保持推理速度的同时提高YOLOv3的有效性是实际使用的一个重要问题。为了同时满足两个问题,研究者添加了一堆改进,几乎不增加推理时间来提高PP-YOLO的整体性能。要注意,尽管大量的方法声称可以独立地提高目标检测器的精度,但在实践中,有些方法在结合时是不有效的。因此,需要对这些技巧的组合进行实际的测试。研究者遵循增量的方法来逐一评估它们的有效性。所有的实验都是基于PaddlePaddle实现。

PP-YOLO

最近出现了yolov4和yolov5模型,这些模型也是基于yolo3算法改进得来。但PP-YOLO并不像yolov4探究各种复杂的backbone和数据增广手段,也不是靠nas暴力搜索得到一个结构。在resnet主干网络系列,数据增广仅靠mixup的条件下,通过合理的tricks组合,不断提升模型性能。最终与其他模型对比图如下:

一个单阶段的Anchor based的检测模型通常是由一个主干网络一个neck(通常是FPN),以及一个head(用于分类+定位)组成。PP-YOLO选择了ResNet50-vd-dcn作为骨架网络。

Backbone

直接用ResNet50-vd替换掉Darknet53会导致一部分的性能损失。因此,尝试替换了一些ResNet中的卷积为可变形卷积(Deformable Convolution Network)。可变形卷积的效果已经被很多论文证明了其有效性,但是过多的添加DCN层会导致增加预测时间。论文这里使用的一个平衡的方案就是替换了最后一个stage的3x3卷积为DCNs。

Detection Neck

使用FPN,将backbone的3,4,5个stage的输出作为FPN的输入,输出的大小变为输入大小的一半。

Detection Head

常规来说Head的组成都是很简单的,包含两个卷积层,一个3x3和一个1x1。当输出类别是K的时候,输出的维度就是3(K+5),每一个预测的特征图上的每一个预测位置都与三个不同的anchors相关。针对每一个anchor,前K个维度确定了类别,后4个确定了bounding box的定位,最后一个确定了是否有目标。然后CE和L1用于对这些预测值计算损失。

A->B

首先就是搭建基础版本的PP-YOLO,在尝试替换backbone后,虽然参数小了很多,但是mAP也下降了不少。我们通过增加了DCN卷积,将mAP提高到39.1%,增加的参数仍远远小于原始yolo3。

B->C

基础模型搭建好后,尝试优化训练策略,选用的是更大的batch和EMA,并且加入DropBlock防止过拟合,mAP提升到了41.4%。

C->F

我们在这个阶段分别增加了IOU Loss,IOU Aware,Grid Sensitive这三个损失函数的改进。分别得到了0.5%, 0.6%, 0.3%的提升,将mAP提升到了42.8%,推理速度下降仍属于可接受范围内。

F->G

检测框的处理部分也是能提升性能的,通过增加Matrix NMS,mAP提高了0.6%。这个表格暂时不考虑NMS对推理时间的影响,在实际测试中,MatrixNMS是能比传统NMS降低推理时间的。

G->I

到了最后阶段,很难通过增加网络复杂度来提高mAP,因此我们将SPP和CoordConv放到这里再来考虑。这两个结构所带来的额外参数较少,而实验也证明了将mAP提高到44.3%。

I->J

分类模型的好坏不能代表整个检测模型的性能,因此我们最后才考虑是否用更好的预训练模型。仍然是在ImageNet上进行预训练得到了一个更好的模型,并且提升了0.3%的mAP。

三、新框架

Path Aggregation Network

对不同尺度的目标进行检测是目标检测的一个基本挑战。实际上,检测Neck需要为所有尺度构建高级语义特征。研究者参考PAN的设计集成了top-down信息。可参见上面图示部分。

def pan_module(self, input, filter_list, name=None):        for i in range(1, len(input)):            ch_out = input[i].shape[1] // 2            conv_left = self._conv_bn(                input[i],                ch_out=ch_out,                filter_size=1,                stride=1,                padding=0,                name=name + '.{}.left'.format(i))            ch_out = input[i - 1].shape[1] // 2            conv_right = self._conv_bn(                input[i - 1],                ch_out=ch_out,                filter_size=1,                stride=1,                padding=0,                name=name + '.{}.right'.format(i))            conv_right = self._upsample(conv_right)            pan_out = fluid.layers.concat([conv_left, conv_right], axis=1)            ch_list = [pan_out.shape[1] // 2 * k for k in [1, 2, 1, 2, 1]]            input[i] = self.stack_conv(                pan_out,                ch_list=ch_list,                filter_list=filter_list,                name=name + '.stack_conv.{}'.format(i))        return input

Mish Activation Function

已有研究YOLOv4与YOLOv5表明:Mish对于改进目标检测器的性能非常有效。由于已经有了一个非常强有力的预训练主干模型(82.4%top1精度),为保持主干结构不变,仅将Mish用到了Neck部分。

def mish(x):    return x * paddle.tanh(F.softplus(x))

Larger Input Size

提升输入尺寸可以增强目标面积,因此小尺度的目标信息可以更好的保持,进而可以提升模型性能。然而更大尺寸输入会占用更多内存,为使用这个技巧,需要减少batch。具体来说,将每个GPU的batch从24下降到12,并将输入尺寸从608提升到768。

IoU Aware Branch 

在PP-YOLO中,IoU损失采用了软加权方式;在这里采用软标签形式,IoU损失定义如下:


其中t表示锚点与其匹配真实框之间的IoU,p表示原始IoU分支的输出。

注:仅仅正样本的IoU损失进行了计算。通过替换损失函数,IoU损失分支表现更佳。

@register@serializableclass IouAwareLoss(IouLoss):    """    iou aware loss, see https://arxiv.org/abs/1912.05992    Args:        loss_weight (float): iou aware loss weight, default is 1.0        max_height (int): max height of input to support random shape input        max_width (int): max width of input to support random shape input    """
def __init__(self, loss_weight=1.0, giou=False, diou=False, ciou=False): super(IouAwareLoss, self).__init__( loss_weight=loss_weight, giou=giou, diou=diou, ciou=ciou)
def __call__(self, ioup, pbox, gbox): iou = bbox_iou( pbox, gbox, giou=self.giou, diou=self.diou, ciou=self.ciou) iou.stop_gradient = True loss_iou_aware = F.binary_cross_entropy_with_logits( ioup, iou, reduction='none') loss_iou_aware = loss_iou_aware * self.loss_weight return loss_iou_aware

四、实验及可视化

首先,参考原始的PP-YOLO构建新框架的基线模型,由于CPU端的重度预处理会减慢训练,将每个GPU的图像数从24下调到了12,降低bs会导致0.2%mAP指标下降。

A->B

PP-YOLO上添加的第一个正向改进为PAN,为稳定训练,为PAN模块添加了几个跳过连接,具体可以参见前面的图示部分。可以看到:PAN+Mish的添加可以将模型的性能从45.4%mAP提升到47.1%mAP。尽管B模型要比A模型稍慢,但这种程度的性能提升促使将PAN应用到最终的模型中。

B->C

由于YOLOv4与YOLOv5评估过程中的输入尺寸为640,将训练与评估的输入尺寸同样调整到了640以进行公平对比。可以看到:模型性能得到了0.6%mAP提升。

C->D

持续输入尺寸应该受益更多,然而不可能同时采用大输入尺寸与大batch。因此采用更大输入尺寸+每个GPU12图像训练模型D。此时可以带来额外的0.6%mAP指标提升。

D->E

在训练阶段,改进IoU损失表现更好。通过该损失的替换,模型E的提升提升到了49.1%mAP指标且不造成推理效率的损失。

上表给出了所提方法与其他SOTA方案的性能、效率对比,从中可以看到:

  • PP-YOLOv2显著优于YOLOv4-CSP与YOLOv5;

  • 在同等FPS下,PP-YOLOv2以2%mAP优于YOLOv4-CSP,以1.3%AP优于YOLOv5l;

  • 替换ResNet50为ResNet101后,PP-YOLOv2的性能与YOLOv5x相当且推理速度快15.9%。

本文仅做学术分享,如有侵权,请联系删文。
下载1
在「3D视觉工坊」公众号后台回复:3D视觉即可下载 3D视觉相关资料干货,涉及相机标定、三维重建、立体视觉、SLAM、深度学习、点云后处理、多视图几何等方向。

下载2
「3D视觉工坊」公众号后台回复:3D视觉github资源汇总即可下载包括结构光、标定源码、缺陷检测源码、深度估计与深度补全源码、点云处理相关源码、立体匹配源码、单目、双目3D检测、基于点云的3D检测、6D姿态估计汇总等。

下载3
「3D视觉工坊」公众号后台回复:相机标定即可下载独家相机标定学习课件与视频网址;后台回复:立体匹配即可下载独家立体匹配学习课件与视频网址。

重磅!3DCVer-学术论文写作投稿 交流群已成立

扫码添加小助手微信,可 申请加入3D视觉工坊-学术论文写作与投稿 微信交流群,旨在交流顶会、顶刊、SCI、EI等写作与投稿事宜。

同时也可申请加入我们的细分方向交流群,目前主要有3D视觉CV&深度学习SLAM三维重建点云后处理自动驾驶、多传感器融合、CV入门、三维测量、VR/AR、3D人脸识别、医疗影像、缺陷检测、行人重识别、目标跟踪、视觉产品落地、视觉竞赛、车牌识别、硬件选型、学术交流、求职交流、ORB-SLAM系列源码交流、深度估计等微信群。


一定要备注:研究方向+学校/公司+昵称,例如:”3D视觉 + 上海交大 + 静静“。请按照格式备注,可快速被通过且邀请进群。原创投稿也请联系。

▲长按加微信群或投稿

▲长按关注公众号

3D视觉从入门到精通知识星球:针对3D视觉领域的视频课程(三维重建系列三维点云系列结构光系列 手眼标定相机标定orb-slam3等视频课程)、知识点汇总、入门进阶学习路线、最新paper分享、疑问解答个方面进行深耕,更有各类大厂的算法工程人员进行技术指导。与此同时,星球将联合知名企业发布3D视觉相关算法开发岗位以及项目对接信息,打造成集技术与就业为一体的铁杆粉丝聚集区,近2000星球成员为创造更好的AI世界共同进步,知识星球入口:

学习3D视觉核心技术,扫描查看介绍,3天内无条件退款
 圈里有高质量教程资料、可答疑解惑、助你高效解决问题
觉得有用,麻烦给个赞和在看~  

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/114100