0


YOLOv8

终于又说到了v8

出品YOLOv5的公司发布了最新的YOLOv8!一起来看看YOLOv8的结构亮点。

回顾一下YOLOv5

这里粗略回顾一下,这里直接提供YOLOv5的整理的结构图吧:

  1. Backbone:CSPDarkNet结构,主要结构思想的体现在C3模块,这里也是梯度分流的主要思想所在的地方;
  2. PAN-FPN:双流的FPN,必须香,也必须快,但是量化还是有些需要图优化才可以达到最优的性能,比如cat前后的scale优化等等,这里除了上采样、CBS卷积模块,最为主要的还有C3模块(记住这个C3模块哦);
  3. Head:Coupled Head+Anchor-base,毫无疑问,YOLOv3、YOLOv4、YOLOv5、YOLOv7都是Anchor-Base的,后面会变吗?
  4. Loss:分类用BEC Loss,回归用CIoU Loss。

**V8 **

直接上YOLOv8的结构图吧,小伙伴们可以直接和YOLOv5进行对比,看看能找到或者猜到有什么不同的地方?

下面就直接揭晓答案吧,具体改进如下:

  1. Backbone:使用的依旧是CSP的思想,不过YOLOv5中的C3模块被替换成了C2f模块,实现了进一步的轻量化,同时YOLOv8依旧使用了YOLOv5等架构中使用的SPPF模块;
  2. PAN-FPN:毫无疑问YOLOv8依旧使用了PAN的思想,不过通过对比YOLOv5与YOLOv8的结构图可以看到,YOLOv8将YOLOv5中PAN-FPN上采样阶段中的卷积结构删除了,同时也将C3模块替换为了C2f模块;
  3. Decoupled-Head:是不是嗅到了不一样的味道?是的,YOLOv8走向了Decoupled-Head;
  4. Anchor-Free:YOLOv8抛弃了以往的Anchor-Base,使用了Anchor-Free的思想;
  5. 损失函数:YOLOv8使用VFL Loss作为分类损失,使用DFL Loss+CIOU Loss作为分类损失;
  6. 样本匹配:YOLOv8抛弃了以往的IOU匹配或者单边比例的分配方式,而是使用了Task-Aligned Assigner匹配方式。

1、C2f模块是什么?与C3有什么区别?

我们不着急,先看一下C3模块的结构图,然后再对比与C2f的具体的区别。针对C3模块,其主要是借助CSPNet提取分流的思想,同时结合残差结构的思想,设计了所谓的C3 Block,这里的CSP主分支梯度模块为BottleNeck模块,也就是所谓的残差模块。同时堆叠的个数由参数n来进行控制,也就是说不同规模的模型,n的值是有变化的。

其实这里的梯度流主分支,可以是任何之前你学习过的模块,比如,美团提出的YOLOv6中就是用来重参模块RepVGGBlock来替换BottleNeck Block来作为主要的梯度流分支,而百度提出的PP-YOLOE则是使用了RepResNet-Block来替换BottleNeck Block来作为主要的梯度流分支。而YOLOv7则是使用了ELAN Block来替换BottleNeck Block来作为主要的梯度流分支。

C3模块的Pytorch的实现如下:

class C3(nn.Module):  
    # CSP Bottleneck with 3 convolutions  
    def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):  # ch_in, ch_out, number, shortcut, groups, expansion  
        super().__init__()  
        c_ = int(c2 * e)  # hidden channels  
        self.cv1 = Conv(c1, c_, 1, 1)  
        self.cv2 = Conv(c1, c_, 1, 1)  
        self.cv3 = Conv(2 * c_, c2, 1)  # optional act=FReLU(c2)  
        self.m = nn.Sequential(*(Bottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n)))  
  
    def forward(self, x):  
        return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), 1))  

下面就简单说一下C2f模块,通过C3模块的代码以及结构图可以看到,C3模块和名字思路一致,在模块中使用了3个卷积模块(Conv+BN+SiLU),以及n个BottleNeck。

通过C3代码可以看出,对于cv1卷积和cv2卷积的通道数是一致的,而cv3的输入通道数是前者的2倍,因为cv3的输入是由主梯度流分支(BottleNeck分支)依旧次梯度流分支(CBS,cv2分支)cat得到的,因此是2倍的通道数,而输出则是一样的。

不妨我们再看一下YOLOv7中的模块:

YOLOv7通过并行更多的梯度流分支,放ELAN模块可以获得更丰富的梯度信息,进而或者更高的精度和更合理的延迟。

C2f模块的结构图如下:

我们可以很容易的看出,C2f模块就是参考了C3模块以及ELAN的思想进行的设计,让YOLOv8可以在保证轻量化的同时获得更加丰富的梯度流信息。

C2f模块对应的Pytorch实现如下:

class C2f(nn.Module):  
    # CSP Bottleneck with 2 convolutions  
    def __init__(self, c1, c2, n=1, shortcut=False, g=1, e=0.5):  # ch_in, ch_out, number, shortcut, groups, expansion  
        super().__init__()  
        self.c = int(c2 * e)  # hidden channels  
        self.cv1 = Conv(c1, 2 * self.c, 1, 1)  
        self.cv2 = Conv((2 + n) * self.c, c2, 1)  # optional act=FReLU(c2)  
        self.m = nn.ModuleList(Bottleneck(self.c, self.c, shortcut, g, k=((3, 3), (3, 3)), e=1.0) for _ in range(n))  
  
    def forward(self, x):  
        y = list(self.cv1(x).split((self.c, self.c), 1))  
        y.extend(m(y[-1]) for m in self.m)  
        return self.cv2(torch.cat(y, 1))  

SPPF改进了什么?

这里讲解的文章就很多了,这里也就不具体描述了,直接给出对比图了

上图中,左边是SPP,右边是SPPF。

PAN-FPN改进了什么?

我们先看一下YOLOv5以及YOLOv6的PAN-FPN部分的结构图:

YOLOv5的Neck部分的结构图如下:

YOLOv6的Neck部分的结构图如下:

我们再看YOLOv8的结构图:

可以看到,相对于YOLOv5或者YOLOv6,YOLOv8将C3模块以及RepBlock替换为了C2f,同时细心可以发现,相对于YOLOv5和YOLOv6,YOLOv8选择将上采样之前的1×1卷积去除了,将Backbone不同阶段输出的特征直接送入了上采样操作。 whaosoft aiot http://143ai.com

Head部分都变了什么呢?

先看一下YOLOv5本身的Head(Coupled-Head):

而YOLOv8则是使用了Decoupled-Head,同时由于使用了DFL 的思想,因此回归头的通道数也变成了4*reg_max的形式:

对比一下YOLOv5与YOLOv8的YAML

损失函数

对于YOLOv8,其分类损失为VFL Loss,其回归损失为CIOU Loss+DFL的形式,这里Reg_max默认为16。

VFL主要改进是提出了非对称的加权操作,FL和QFL都是对称的。而非对称加权的思想来源于论文PISA,该论文指出首先正负样本有不平衡问题,即使在正样本中也存在不等权问题,因为mAP的计算是主正样本。

q是label,正样本时候q为bbox和gt的IoU,负样本时候q=0,当为正样本时候其实没有采用FL,而是普通的BCE,只不过多了一个自适应IoU加权,用于突出主样本。而为负样本时候就是标准的FL了。可以明显发现VFL比QFL更加简单,主要特点是正负样本非对称加权、突出正样本为主样本。

针对这里的DFL(Distribution Focal Loss),其主要是将框的位置建模成一个 general distribution,让网络快速的聚焦于和目标位置距离近的位置的分布。

DFL 能够让网络更快地聚焦于目标 y 附近的值,增大它们的概率;

DFL的含义是以交叉熵的形式去优化与标签y最接近的一左一右2个位置的概率,从而让网络更快的聚焦到目标位置的邻近区域的分布;也就是说学出来的分布理论上是在真实浮点坐标的附近,并且以线性插值的模式得到距离左右整数坐标的权重。

样本的匹配

标签分配是目标检测非常重要的一环,在YOLOv5的早期版本中使用了MaxIOU作为标签分配方法。然而,在实践中发现直接使用边长比也可以达到一阿姨你的效果。而YOLOv8则是抛弃了Anchor-Base方法使用Anchor-Free方法,找到了一个替代边长比例的匹配方法,TaskAligned。

为与NMS搭配,训练样例的Anchor分配需要满足以下两个规则:

  1. 正常对齐的Anchor应当可以预测高分类得分,同时具有精确定位;
  2. 不对齐的Anchor应当具有低分类得分,并在NMS阶段被抑制。基于上述两个目标,TaskAligned设计了一个新的Anchor alignment metric 来在Anchor level 衡量Task-Alignment的水平。并且,Alignment metric 被集成在了 sample 分配和 loss function里来动态的优化每个 Anchor 的预测。

Anchor alignment metric:

分类得分和 IoU表示了这两个任务的预测效果,所以,TaskAligned使用分类得分和IoU的高阶组合来衡量Task-Alignment的程度。使用下列的方式来对每个实例计算Anchor-level 的对齐程度:

s 和 u 分别为分类得分和 IoU 值,α 和 β 为权重超参。从上边的公式可以看出来,t 可以同时控制分类得分和IoU 的优化来实现 Task-Alignment,可以引导网络动态的关注于高质量的Anchor。

Training sample Assignment:

为提升两个任务的对齐性,TOOD聚焦于Task-Alignment Anchor,采用一种简单的分配规则选择训练样本:对每个实例,选择m个具有最大t值的Anchor作为正样本,选择其余的Anchor作为负样本。然后,通过损失函数(针对分类与定位的对齐而设计的损失函数)进行训练。

YOLOv8 是由小型初创公司 Ultralytics 创建并维护的,值得注意的是 YOLOv5 也是由该公司创建的。

YOLOv8 项目地址:https://github.com/ultralytics/ultralytics

YOLOv8 的主要具有以下特点:

  • 对用户友好的 API(命令行 + Python);
  • 模型更快更准确;
  • 模型能完成目标检测、实例分割和图像分类任务;
  • 与先前所有版本的 YOLO 兼容可扩展;
  • 模型采用新的网络主干架构;
  • 无锚(Anchor-Free)检测;
  • 模型采用新的损失函数。

YOLOv8 还高效灵活地支持多种导出格式,并且可在 CPU 和 GPU 上运行该模型。YOLOv8 的整体架构如下图所示:

值得注意的是,YOLOv8 是一个无锚(Anchor-Free)模型。这意味着它直接预测对象的中心,而不是已知锚框的偏移量。由于减少了 box 预测的数量,因此这种新方法加速了一个非常复杂的推理步骤 —— 非极大值抑制 (NMS)。

YOLOv8 系列包含 5 个模型,其中 YOLOv8 Nano(YOLOv8n)是最小的模型,但速度最快;而 YOLOv8 Extra Large (YOLOv8x) 是最准确的模型,但速度最慢。

此外,YOLOv8 捆绑(bundle)了以下预训练模型:

  • 在图像分辨率为 640 的 COCO 检测数据集上训练的目标检测检查点;
  • 在图像分辨率为 640 的 COCO 分割数据集上训练的实例分割检查点;
  • 在图像分辨率为 224 的 ImageNet 数据集上预训练的图像分类模型。

YOLO 不同版本之间的对比

相比于之前的 YOLO 系列,YOLOv8 模型似乎表现得更好,不仅领先于 YOLOv5,YOLOv8 也领先于 YOLOv7 和 YOLOv6 版本。


YOLOv8 与其他 YOLO 模型的对比。

在与 640 图像分辨率下训练的 YOLO 模型相比,所有 YOLOv8 模型在参数数量相似的情况下都具有更好的吞吐量。

接下来我们详细了解一下最新的 YOLOv8 模型与 Ultralytics 的 YOLOv5 模型的性能比较。

YOLOv8 和 YOLOv5 之间的综合比较

YOLOv8 和 YOLOv5 目标检测模型对比

YOLOv8 和 YOLOv5 实例分割模型对比

YOLOv8 和 YOLOv5 图像分类模型对比


除了一个分类模型之外,最新的 YOLOv8 模型比 YOLOv5 要好得多。

差异点

(1). Backbone:CSP是不变的思想,但是v8中选用了C2f模块替换v5的C3模块,每个stage的blocks数也改为了[3,6,6,3]而不是[3,6,9,3],此外x版本的depth因子仍然为1.0和L版本一样而不是常规的1.33,明显是为了轻量化。stem卷积在v8里是k=3的卷积而不是k=6的了,而最后的SPPF模块v8还是照搬沿用v5的;

(2). Neck:除了同样是C2f模块替换C3模块外,v8还将v5中PAN-FPN的top down上采样阶段中的卷积直接删除了;

(3). Head:Decoupled-Head,和yolov6 ppyoloe的head类似,除了cls reg两个branch外还有一个projection conv,是为DFL用的,不同于v6 ppyoloe的是reg_max没有加1;

(4). Label Assign:v8终于还是使用了Anchor-Free,TaskAlignedAssigner(TAL)动态匹配的方式也是和v6 ppyoloe很相似的,但topk alpha参数略有不同,v8也没有ATSS静态匹配阶段;

(5). Loss:v8的分类loss还是使用的BCE,虽然也写了VFL(varifocal_loss)但是注释了没用上,回归loss是DFL Loss+CIoU Loss,loss_weight的设置也和v6 ppyoloe略有区别;

总的来看,最大的改动就是Anchor Base换成Anchor Free了,主要就是TOOD的思想,也参考了一些v6 ppyoloe的代码。

关于精度:

首先还是直接看下YOLOv5和YOLOv8的精度对比,可以看出同级别模型YOLOv8至少高出3个多点,nano版本更是高出9.3。参数量FLOPs上YOLOv8不可避免的增加了些,然后l x版本参数量少了点。

关于模型结构:

参数量FLOPs不可避免增加,n s m上已经有点明显了,但l x版本参数量反而减小了很多,我觉得主要还是减少了东西导致的,比如Backbone每个stage的输出的通道数只有 n/s 和YOLOv5的n/s相同,m/l/x 最后一个stage都缩减了很多,再配合最大的stage的blocks数也减少了,以及FPN去除了top-down上采样卷积,x版本的depth因子仍然为1.0而不是常规的1.33,所以YOLOv8各个模型尤其是大模型上参数量减小了,而小模型上增加的也不太多。

同时带来的一个问题也是设计上的不统一了,包括v6 damo-yolo都是大小模型各一套backbone,v7的设计个版本就更没有章法了。一套模型X L M S T N只改depth width因子是最理想状态,但是估计这些新的YOLO的作者往往发现和竞品对比时某一个版本稍弱或优势没那么大,于是就针对它调,效果是跳上去了,但是每个版本差别也越来越大,换版本的时候不能只是改下depth width因子了,各自调优稍显刻意了点。

关于Assign和Loss:

其实主要还是TOOD的思想,总结下来就是分类和回归任务具有较高一致性。但是v8分类loss目前还是使用的BCE,不知道使用VFL的时候精度如何,至于IoU loss可能也已经排列组合尝试过了采用了CIoU,loss_weight也调大了iou loss的比例。v8的Assign是全程采用TAL ,没有静态匹配ATSS,其实看v6的最新代码里也逐渐去除了ATSS阶段,而PPYOLOE里还是保留着约前1/3 阶段ATSS+后期TAL的设置。本人之前训TOOD也跳过ATSS和TAL的epoch数,ATSS静态匹配确实稍显生硬,但对于较简单的数据集还是挺有用。全程TAL对于遮挡多较难的数据集更合适。

关于训练细节:

早在前几天ultralytics 作者放出yolov8权重后,就有一群热心网友火急火燎的去做trt部署开源自卖自夸,但都没有eval出精度和速度,事实上ultralytics目前也只公布了精度,没有速度的具体数据,甚至很多训练细节还有待公布。几个综合YOLO的集合代码库也是火速安排上了复现的PR,比如MMYOLO和PaddleYOLO,今早看到了PaddleYOLO里已经率先支持了YOLOv8的inference和部署速度。

具体训练可能都还得等的官方先公布完全吧。包括训练epoch数和预训练权重,这个已经在issue中有人问到了,这是对训练精度影响最大的两个方面,现在各个YOLO也已经很难做到公平对比了,以前还默认都是300epoch下640单尺度eval精度,所以后面的YOLO纷纷使用了1280尺度、加P6层、obj365预训练、自蒸馏、大蒸小蒸馏等外挂拼命往上刷,现在则是只剩下640单尺度eval精度。

关于部署和速度:

之前我的T4机器上就测过PaddleYOLO里的ppyoloe和v5 v7的速度对比,这下正好也直接验证了下v8的几个权重onnx的速度。最基础的测速,是640*640尺度下去nms bs=1的trt测速,各家YOLO发布时这个也是必测必写的,其实换算到FPS更直观点,但是FPS波动太大,多打20都有可能,而毫秒耗时则最多差个0.2ms。

看到PaddleYOLO里yolov8表格的TRT-FP16-Latency的数据,发现和yolov5比小模型上速度比较接近,但大模型m l x上则变慢了不少,精度的巨大提升也牺牲了速度,这也可能是之前讨论的m l x比yolov5缩减了backbone的模块和通道数有关吧。理论上看模型结构改动尤其是head加大了很多,的确可能变慢的,具体等v8公布速度数据再看看。

PaddleYOLO 的modelzoo页面可以直观的看到几乎所有YOLO的精度速度对比,虽然是paddle框架但都是同一T4 GPU环境下册的还算是可以参考的

当然也期待yolov8论文中的超级大表格,那样会更直观。

参考:

https://github.com/PaddlePaddle/PaddleYOLO

标签: 人工智能

本文转载自: https://blog.csdn.net/qq_29788741/article/details/128626422
版权归原作者 whaosoft143 所有, 如有侵权,请联系我们删除。

“YOLOv8”的评论:

还没有评论