我们对yolo系列算法模型进行了简要整理


yolov1

CVPR 2016 Joseph Redmon

You only look once, real-time object detection

deepsystems.io 很不错的 yolov1幻灯片讲解

单阶段模型、两阶段模型:

目标检测模型,大致可分为"单阶段模型"、"两阶段模型"两种。前者以YOLO, SSD, Retina-Net等模型为代表;后者以RCNN, Fast RCNN等模型为代表。

"两阶段"是指,先从图像中提取若干候选框,再逐一对这些候选框进行分类和坐标调整;"单阶段"是指,直接将图像喂到网络中,由网络直接输出最终的分类以及定位结果,一步到位,端到端。(以yolo为例,其无需提取候选区域,也无复杂的上下游处理工作。仅一次前向推断即可得到bounding box定位和分类结果。)

一般而言,两者的区别在于:两阶段模型更准,单阶段模型更快。

两阶段模型(如RCNN, Fast RCNN等),一个弊端是慢,另一个弊端在于,其首阶段所提取到的候选框,只是图像中的一小部分,管中窥豹,丢失了整个图像的全景信息(如背景信息,背景和前景的关系信息,不同物体之间的关系信息等)。

网络结构

24层卷积层提取图像特征,2层全连接层

输入448 * 448 * 3的图像

输出7 * 7 * 30的tensor,包含了所有预测框的坐标,置信度信息,以及分类结果

学习yolov1算法模型,应分开去理解训练阶段预测阶段

训练阶段

将输入图片划分成 S * S 个grid cell,这里 S = 7

标签ground truth(gt)框的中心点落在哪个grid cell中,就应该由哪个grid cell负责去预测这个物体。每个grid cell预测B(B = 2)个bounding box(该bounding box的中心点位于其所属grid cell内部),其中与gt框IoU最大的bounding box负责预测这个物体,每个grid cell只能检测一个物体。

对于包含、不包含gt框的grid cell / bounding box,损失函数分别对其进行处理。

yolov1_loss_function

摘自B站大佬"同济子豪兄"yolov1系列

loss分为5个部分。其中第1、2部分属于"坐标回归误差",第3、4部分属于"置信度回归误差",第5部分属于"类别预测误差"。

  1. 负责检测物体的bounding box的中心点定位误差。(gt框的中心点与该bounding box的中心点位于同一个grid cell中) (坐标回归误差)

    λcoordi=0S2j=0B1ijobj[(xix^i)2+(yiy^i)2]\lambda _{coord}\sum_{i=0}^{S^{2}}\sum_{j=0}^{B}{\color{Red}\mathbb{1}_{i j}^{\mathrm{obj}}}\left[\left(x_{i}-\hat{x}_{i}\right )^{2}+\left(y_{i}- \hat{y}_{i}\right)^{2}\right]

  2. 负责检测物体的bounding box的宽高定位误差。 (坐标回归误差)

    +λcoordi=0S2j=0B1ijobj[(ωiω^i)2+(hih^i)2]+ \lambda _{coord}\sum_{i=0}^{S^{2}}\sum_{j=0}^{B} {\color{Red} \mathbb{1}_{i j}^{\mathrm{obj}}} \left[\left ( \sqrt{\omega _{i} } - \sqrt{\hat{\omega }_{i} } \right )^{2} + \left ( \sqrt{h_{i} } - \sqrt{\hat{h}_{i} } \right )^{2} \right]

    其中

    采用根号的方式计算loss,是为了让误差对形状较小的预测框更加敏感。(削弱形状较大的预测框,对不同大小的预测框一视同仁。) (一个很大的数开根号,结果变化会很大;一个较小的数开根号,结果变化会稍小。e.g 100=10\sqrt{100} = 104=2\sqrt{4} = 2,前者缩小了10倍,后者仅缩小了2倍)

  3. 负责检测物体的bounding box的置信度误差。 (置信度回归误差)

    +i=0S2j=0B1ijobj(CiC^i)2+ \sum_{i=0}^{S^{2}}\sum_{j=0}^{B} {\color{Red} \mathbb{1}_{i j}^{\mathrm{obj}}} \left ( {\color{Blue} C_{i}} - {\color{Green} \hat{C}_{i}} \right )^{2}

    其中

    Ci{\color{Blue} C_{i}} 是预测值,即从模型正向推断出的 S×S×(B×5+C)S \times S \times \left ( B \times 5 + C \right ) 维向量中找到的这个bounding box的confidience score。

    C^i{\color{Green} \hat{C}_{i}} 是标签值,为这个bounding box与ground truth的IoU。(C^i=Pr(object)×IoUpredtruth{\color{Green} \hat{C}_{i}} = Pr\left ( object \right ) \times IoU_{pred}^{truth} ,其中Pr(object)=1Pr\left ( object \right ) = 1)

  4. 不负责检测物体的bounding box的置信度误差。 (置信度回归误差)

    +λnoobji=0S2j=0B1ijnoobj(CiC^i)2+ \lambda _{noobj} \sum_{i=0}^{S^{2}}\sum_{j=0}^{B} {\color{Green} \mathbb{1}_{i j}^{\mathrm{noobj}}} \left ( {\color{Blue} C_{i}} - {\color{Orange} \hat{C}_{i}} \right )^{2}

    其中

    Ci{\color{Blue} C_{i}} 是预测值。

    C^i{\color{Orange} \hat{C}_{i}} 是标签值。(C^i=0{\color{Orange} \hat{C}_{i}} = 0)

  5. 负责检测物体的grid cell分类误差。 (类别预测误差)

    +i=0S21iobjcclasses(pi(c)p^i(c))2+ \sum_{i=0}^{S^{2}} {\color{Blue} \mathbb{1}_{i}^{\mathrm{obj}}} \sum_{c\in classes} \left ( p_{i}\left ( c \right ) - \hat{p}_{i}\left ( c \right ) \right )^{2}

loss函数中

若第 ii 个grid cell的第 jj 个bounding box负责预测物体,1ijobj{\color{Red} \mathbb{1}_{i j}^{\mathrm{obj}}} 为1,否则 1ijobj{\color{Red} \mathbb{1}_{i j}^{\mathrm{obj}}} 为0。(挑选出负责检测物体的bounding box)

若第 ii 个grid cell的第 jj 个bounding box不负责预测物体,1ijnoobj{\color{Green} \mathbb{1}_{i j}^{\mathrm{noobj}}} 为1,否则 1ijnoobj{\color{Green} \mathbb{1}_{i j}^{\mathrm{noobj}}} 为0。(挑选出不负责检测物体的bounding box)

若第 ii 个grid cell包含物体,即有ground truth框的中心点落在此grid cell中,1iobj{\color{Blue} \mathbb{1}_{i}^{\mathrm{obj}}} 为1,否则 1iobj{\color{Blue} \mathbb{1}_{i}^{\mathrm{obj}}} 为0。 (挑选出包含物体的grid cell)

(因kaTex的公式渲染问题,指示函数\mathbb{1}_{i j}^{\mathrm{obj}的展示可能存在问题,loss function具体以图片为准)

另外,由于绝大多数预测框都是不负责预测物体的,仅少部分预测框是负责预测物体的。为了避免绝大多数不负责预测物体的预测框在loss计算的过程中占据压倒性的影响,yolov1对不同部分的loss计算进行了权重设置,即 λcoord=5\lambda coord = 5, λnoobj=0.5\lambda noobj = 0.5

预测阶段

使用已训练好的模型进行预测

模型输出 S * S * (5 * B + C) 维的向量,接着进行置信度(conf)过滤、**非极大值抑制(NMS)**等后处理操作后,最终得到目标检测的结果。

上式中,5代表(x, y, h, w, conf),即预测框的坐标、宽高,置信度信息。conf为该预测框是否检测到一个物体的置信度;C = 20,即已预测到是物体的条件下,20个类别分别的预测概率,即 Pr(ClassiObject)Pr\left ( Class_{i} \mid Object \right )

yolov1将一张输入是 448 * 448 的图像,分割成 7 * 7 = 49 个grid cell,因此该图片最多只能预测出49个物体。这也是为什么yolov1检测小目标和密集目标比较差的原因

预测阶段的后处理:

置信度过滤

去掉conf很小的预测框

非极大值抑制(NMS)

目标:

去掉重叠的预测框

原理:

经过置信度过滤后,留下的预测框,对某一个类别,按置信度从左到右,从大到小排序。接下来,1号最优预测框分别与2、3、4、…号次优预测框做IoU比较(最优预测框与次优预测框的置信度分数都是大于0的)。假设1号最优预测框与3号次优预测框的IoU超过了某一阈值,说明1号最优预测框与3号次优预测框重叠过大,重复预测了某一位置,我们将3号次优预测框去掉,即将3号次优预测框的置信度置零。假设1号最优预测框与4号次优预测框的IoU未超过某一阈值,则4号次优预测框暂且保留。

1号预测框处理一轮后,2号预测框同样分别与4、5、6、…号次优预测框处理一轮(3号预测框置信度被置零了)。接着,4号预测框同样分别与5、6、7、8、…号次优预测框处理一轮。以此类推,即NMS操作。

NMS一次处理一个类别,分别对所有类别进行上述操作即可。

(注意,NMS只针对预测阶段,训练阶段是不需要进行NMS的。训练阶段每个框都会参与loss计算,不能随意把某个预测框去掉。)

参考自B站大佬"同济子豪兄"yolov1系列


yolov2

CVPR 2017 Joseph Redmon

YOLOV9000: Better, Faster, Stronger

Better: 在yolov1的基础之上,性能、准确率进一步提升

  • Batch Normalization

对每一个神经元的输出,除以均值,乘以标准差。

很多激活函数,例如sigmoid函数,在0附近是非饱和区。输出太大或太小会进入饱和区,意味着梯度消失,难以训练。所以用BN,将神经元的输出集中到0附近。

yolov2_BN层_1

yolov2_BN层_2

yolov2_BN层_3

摘自B站大佬"同济子豪兄"yolov2系列

  • High Resolution Classifier (高分辨率的分类器)

  • Anchor

训练前首先对数据集中的物体进行聚类,得到不同尺寸的anchor。

将单张图片划分为 13 * 13 的grid cell (13为奇数长宽,使整张图片的中心点落在中心grid cell中,避免整张图片的中心点落在grid cell边界。这对中心一个大物体的图片输入,更加优雅。)

yolov2_grid_cell_奇数长宽

摘自B站大佬"同济子豪兄"yolov2系列

每个grid cell包含5个anchor。(即事先指定5种长宽大小不同的先验框)

  • Dimension Cluster

  • Direct location prediction

  • Fine-Grained Features (细粒度特征)

整合不同尺度的特征,叠加融合底层细粒度特征与高层语义特征,有利于小物体的目标检测。

yolov2_passThrough_layer_1

yolov2_passThrough_layer_2

摘自B站大佬"同济子豪兄"yolov2系列

具体实现:

将 26 * 26 * 512 的feature map拆分成4份(4 * 13 * 13 * 512)(passThrough layer),与原本正常进行卷积、下采样的feature map叠加在一起。

  • Multi-Scale Training

将不同尺寸的图像输入到网络进行训练,使网络适应不同尺寸的图像输入。

全局平均池化层(global average pooling),对输出feature map的每一个通道求平均,替代原有的全连接层,使网络支持任意输入图像的尺寸。

Faster: 修改骨干网络,速度进一步提升

Stronger: 该目标检测算法支持检测9000+的类别

网络输出结构与yolov1的区别

yolov1没有anchor的概念,每张图片划分成 7 * 7 的grid cell,每个grid cell预测出2个bounding box,每个 bounding box预测4个位置参数(x, y, w, h)和一个置信度参数(conf)。且2个grid cell共享20个类别的条件类别概率。所以每个grid cell的输出为:5 * B + C。其中B = 2,C = 20。

yolov2有了anchor的概念。原yolov1中各类别的条件概率归各个grid cell管理,现yolov2中各类别的条件概率归各个anchor管理。每张图片划分成 13 * 13 的grid cell,每个grid cell有5个不同尺寸的anchor,每个anchor预测25个参数(4个位置参数 + 1各置信度参数 + 20个条件类别概率参数)。所以每个grid cell的输出为:5 * (4 + 1 + 20)。

yolov2_网络输出结构对比yolov1_1

yolov2_网络输出结构对比yolov1_2

摘自B站大佬"同济子豪兄"yolov2系列

yolov2对anchor位置的限制

yolov1对每个grid cell的bounding box没有做大小、位置的限制,只要该bounding box的中心点位于该grid cell内部即可。

yolov2对每个grid cell的5个预测框(即5个anchor经位置偏移、尺寸变换后的结果)做了位置的限制。公式表示如下:

bx=σ(tx)+cxb_{x} = \sigma \left ( t_{x} \right ) + c_{x}

by=σ(ty)+cyb_{y} = \sigma \left ( t_{y} \right ) + c_{y}

bw=pwetwb_{w} = p_{w} e^{t_{w}}

bh=phethb_{h} = p_{h} e^{t_{h}}

Pr(object)IOU(b,object)=σ(to)P_{r}(object)\ast IOU\left ( b,object \right ) = \sigma \left ( t_{o} \right )

其中

模型的输出是txt_{x}tyt_{y}twt_{w}tht_{h}tot_{o}

bxb_{x}byb_{y}是预测框的(x, y)坐标;bwb_{w}bhb_{h}是预测框的(w, h)宽高。

σ\sigma即sigmoid函数,将txt_{x}控制在(0, 1)之间,即将预测框的中心点限制在其所属grid cell内部。

cxc_{x}cyc_{y}是该grid cell左上角的坐标。(grid cell的大小归一化为1*1)

pwp_{w}php_{h}是原始anchor的宽和高。

因图片中物体的大小并不确定,故yolov2并没有对预测框的大小进行限制,bwb_{w}bhb_{h}可以是任意大小。

tot_{o}是置信度信息。

yolov2_anchor位置的限制

摘自B站大佬"同济子豪兄"yolov2系列

anchor的意义

yolov2每个grid cell给出5个不同尺寸的anchor,即面向5种不同大小形状的物体。高瘦的anchor更倾向于去预测高瘦的物体,矮胖的anchor更倾向于去预测矮胖的物体。每个anchor天生就有自己的使命,能够更好地去完成自己所倾向的工作,加速模型的稳定。

loss function

yolov2_loss_function

摘自B站大佬"同济子豪兄"yolov2系列

losst=i=0Wj=0Hk=0Aloss_{t} = \sum_{i=0}^{W}\sum_{j=0}^{H}\sum_{k=0}^{A}

其中

W=13,H=13,A=5。即遍历 13 * 13 * 5 所有的预测框。(预测框是通过,对原始anchor进行位移和尺度变换,所得来的,因此有多少个anchor,就有多少个预测框)

  1. 不负责预测物体的预测框(background)的置信度误差。(越小越好)

+1MaxIOU<Threshλnoobj(bijko)2+ {\color{Orange} 1_{MaxIOU<Thresh}} \lambda_{noobj}\ast(-b_{ijk}^{o})^{2}

其中

若anchor与gt框的IOU小于0.6,1MaxIOU<Thresh{\color{Orange} 1_{MaxIOU<Thresh}}为1;否则1MaxIOU<Thresh{\color{Orange} 1_{MaxIOU<Thresh}}为0。(IOU的计算方式:将anchor与gt框的中心点重合,计算IOU的大小。即只看形状,不看位置。)

bijko-b_{ijk}^{o}为预测框置信度,实际为(0bijko)\left( 0-b_{ijk}^{o} \right),不负责预测物体的预测框(background)的置信度label为0。

  1. 训练初期,预测框与初始anchor的位置误差。

+1t<12800λpriorr(x,y,w,h)(priorkrbijkr)2+ {\color{Orange} 1_{t<12800}} \lambda_{prior}\ast {\textstyle \sum_{r\in \left ( x,y,w,h \right ) }}\left ( prior_{k}^{r} - b_{ijk}^{r} \right )^{2}

其中

前12800次迭代1t<12800{\color{Orange} 1_{t<12800}}为1;否则1t<12800{\color{Orange} 1_{t<12800}}为0。

priorkrprior_{k}^{r}为初始anchor的位置;bijkrb_{ijk}^{r}为预测框的位置。

即在训练初期,让模型预测框快速学到anchor信息,使txt_{x}tyt_{y}twt_{w}tht_{h}更加稳定。

  1. 负责预测物体的预测框的定位误差、置信度误差、分类误差。

+1ktruth(λcoordr(x,y,w,h)(truthrbijkr)2+λobj(IOUtruthkbijko)2+λclass(c=1C(truthcbijkc)2))\begin{aligned} +{\color{Orange} 1_{k}^{truth}} &\left ( \lambda_{coord} \ast {\textstyle \sum_{r\in \left ( x,y,w,h \right )} \left ( truth^{r} - b_{ijk}^{r} \right )^{2} } \right. \\ &\left. + \lambda_{obj} \ast \left ( IOU_{truth}^{k} - b_{ijk}^{o} \right )^{2} \right. \\ &\left. + \lambda_{class} \ast \left ( \sum_{c=1}^{C} \left ( truth^{c} - b_{ijk}^{c} \right )^{2} \right ) \right ) \end{aligned}

其中

若anchor与gt框的IOU最大,1ktruth{\color{Orange} 1_{k}^{truth}}为1;否则1ktruth{\color{Orange} 1_{k}^{truth}}为0。(即忽略掉IOU大等于0.6,但非最大IOU的anchor的损失)

一个gt仅由一个anchor进行预测。

truthrtruth^{r}为gt框的位置,bijkrb_{ijk}^{r}为预测框的位置。(定位误差)

IOUtruthkIOU_{truth}^{k}为anchor与gt框的IOU,bijkob_{ijk}^{o}为预测框的置信度。(置信度误差)

C为20个类别,truthctruth^{c}为gt框类别,bijkcb_{ijk}^{c}为预测框类别。(分类误差)

参考自B站大佬"同济子豪兄"yolov2系列


yolov3

2018 Joseph Redmon

YOLOv3: An Incremental Improvement

yolov3网络结构

yolov3_网络结构

摘自知乎大佬江大白老师

yolov3的网络由三部分组成:backbone + neck + head

backbone

负责特征提取

backbone是一个全卷积网络,不含全连接层,因此支持任意尺寸的图像输入(但考虑到下采样的倍数,输入图像的尺寸一般都是32的倍数)。

neck

负责融合不同尺度的特征。

head

负责预测输出。

yolov3网络会输出3种不同尺度的feature map

假定输入图像的尺寸是416 * 416 * 3。

输出feature_map_1:13 * 13 * 255 (下采样32倍,即每个grid cell在原图上的感受野是32 * 32,即每个grid cell代表原图上32 * 32的区域) (负责预测大物体);

输出feature_map_2:26 * 26 * 255 (下采样16倍,即每个grid cell在原图上的感受野是16 * 16,即每个grid cell代表原图上16 * 16的区域) (负责预测中等大小物体);

输出feature_map_3:52 * 52 * 255 (下采样8倍,即每个grid cell在原图上的感受野是8 * 8,即每个grid cell代表原图上8 * 8的区域) (负责预测小物体)。

其中,255 = 3 * (5 + 80)。每个grid cell生成3个anchor,每个anchor对应一个预测框,每一个预测框对应5 + 80;

5 = (x,y,w,h,c)。x,y,w,h为预测框中心点坐标和预测框宽高; c(conf)为是否预测成一个物体的置信度 。

80是coco数据集中,80个类别的条件概率(在已判断是物体的条件下,各个类别的条件概率)。

关于anchor

yolov3_不同尺度feature_map_对应不同尺度anchor

摘自B站大佬"同济子豪兄"yolov3系列

yolov3对不同尺度的feature map,所分配的anchor大小也不同。

13 * 13的feature map,anchor会比较大,负责预测大物体;

e.g. (116 * 90); (156 * 198); (373 * 326)

26 * 26的feature map,anchor大小中等,负责预测中等大小物体;

e.g. (30 * 61); (62 * 45); (59 * 119)

52 * 52的feature map,anchor会比较小,负责预测小物体。

e.g. (10 * 13); (16 * 30); (33 * 23)

yolov3一共聚类了9种不同形状的anchor,每个尺度的feature map分配3种anchor。

与yolov2一样,同一feature map下的3个初始anchor,大小相似,但形状不同。

关于多尺度特征融合

yolov3_多尺度特征融合

摘自CSDN,pikaqiu_n95老师

yolov3网络结构中,Neck部分对不同尺度的特征进行了融合。

具体操作为:

深层网络的13 * 13的feature map,用于预测大物体;

深层网络的13 * 13的feature map,经过上采样操作,变成26 * 26的feature map,与中层网络的26 * 26的feature map堆叠在一起,用于预测中等大小的物体;

中层网络的26 * 26的feature map,经过上采样操作,变成52 * 52的feature map,与浅层网络的52 * 52的feature map堆叠在一起,用于预测小物体。

多尺度特征融合的作用:既发挥了深层网络的语义特化抽象的特征,也利用了浅层网络的细粒度的、像素级别的、边缘、转角、和结构信息的底层特征。

关于物体预测

与yolov1、yolov2一样,对于任意尺度输出feature map(13 * 13, 26 * 26, 52 * 52),标签ground truth框中心点落在该feature map下的哪一个grid cell中,就应该由该feature map下的这个grid cell预测这个物体。该feature map下每个grid cell对应3个anchor,用与标签ground truth框IOU最大的anchor去预测该物体。

不同尺度的feature map会得到多个不同的结果,取IOU最大的feature map的结果,作为最终的预测结果。

最大检测物体的数量

yolov3

(13 * 13 * 3) + (26 * 26 * 3) + (52 * 52 * 3) = 507 + 2028 + 8112= 10647

即对于416 * 416的输入图像,最多支持预测10647个物体。

yolov2

每张图片划分成13 * 13 = 169个grid cell,单张图像最多仅支持预测169个物体。

yolov1

每张图片划分成7 * 7 = 49个grid cell,单张图像最多仅支持预测49个物体。

在检测小目标和密集目标的情况下,yolov3要优于yolov1和yolov2。

关于"正样本"与"负样本"

yolov3_正负样本说明

摘自CSDN,"不知语冰"大佬

yolov3中

如果一个anchor与gt框的IOU最大,那么该anchor就是正样本;

如果一个anchor与gt框的IOU高于某一阈值,但非最大IOU,那么该anchor将不参与loss的计算;

如果一个anchor与gt框的IOU小于某一阈值,那么该anchor就是负样本。

(这里的IOU是指,anchor与gt框中心点对齐后的IOU)

loss function

yolov3_loss_function

摘自B站大佬"同济子豪兄"yolov3系列

loss分为3个部分,即正样本的回归误差,正样本的置信度误差,负样本的置信度误差。

  1. 正样本的回归误差

    λcoordi=0S2j=0B1i,jobj[(bxbx^)2+(byby^)2+(bwbw^)2+(bhbh^)2](2wihi)\lambda _{coord} \sum_{i=0}^{S^{2}}\sum_{j=0}^{B} {\color{Green} 1_{i,j}^{obj}} \cdot \left [ \left ( b_{x} - \hat{b_{x}} \right )^{2} + \left ( b_{y} - \hat{b_{y}} \right )^{2} + \left ( b_{w} - \hat{b_{w}} \right )^{2} + \left ( b_{h} - \hat{b_{h}} \right )^{2} \right ] \cdot {\color{Violet} \left ( 2 - w_{i} \ast h_{i} \right ) }

    计算正样本的中心点回归误差与宽高误差。

    其中

    (2wihi){\color{Violet} \left ( 2 - w_{i} \ast h_{i} \right ) }是小框惩罚项,wiw_{i}hih_{i}是宽高。这样相对于大框而言,小框的loss会更大,即对小框赋予更大的loss。

    bxb_{x}byb_{y}为正样本的中心点坐标;

    bwb_{w}bhb_{h}为正样本的宽高。

  2. 正样本的置信度误差

    +i=0S2j=0B1i,jobj[log(pc)+i=1nBCE(ci^,ci)]+ \sum_{i=0}^{S^{2}}\sum_{j=0}^{B} {\color{Green} 1_{i,j}^{obj}} \cdot \left [ -log\left ( p_{c} \right ) + \sum_{i=1}^{n}BCE\left ( \hat{c_{i}},c_{i} \right ) \right ]

    其中

    与yolov1和yolov2不同,yolov1和yolov2的正样本置信度标签,是预测框(anchor)与gt框的IOU。而yolov3将正样本的置信度标签置为1;(1. 很多预测框与gt框的IOU最高也只有0.7,即最好的结果也只能给到70分,取乎其中得乎其下;2. coco中的小目标,IOU对像素偏移很敏感,无法有效学习。)

    n为类别数;

    BCE(ci^,ci)BCE\left ( \hat{c_{i}},c_{i} \right )为逐类别计算二元交叉熵损失函数(Binary Cross Entropy),(可以是多分类问题(multi-class classification);也可以是多标签分类问题(multi-label classification))

    BCE=ci^log(ci)BCE = -\hat{c_{i}} \cdot log\left ( c_{i} \right ),其中ci^\hat{c_{i}}是该类别的标签值(非0即1),cic_{i}是该类别的预测值(0~1之间)。

  3. 负样本的置信度误差

    +λnoobji=0S2j=0B1i,jnoobj[log(1pc)]+ \lambda_{noobj} \sum_{i=0}^{S^{2}} \sum_{j=0}^{B} {\color{Brown} 1_{i,j}^{noobj}} \cdot \left [ -log\left ( 1 - p_{c} \right ) \right ]

    其中

    与yolov1和yolov2相同,负样本的置信度标签为0。

loss函数中

i=0S2j=0B\sum_{i=0}^{S^{2}}\sum_{j=0}^{B}表示,遍历所有grid cell的所有anchor;

1i,jobj{\color{Green} 1_{i,j}^{obj}}表示,是否为正样本;

1i,jnoobj{\color{Brown} 1_{i,j}^{noobj}}表示,是否为负样本;

训练过程

yolov3_训练过程

摘自B站大佬"同济子豪兄"yolov3系列

训练阶段,网络输出3个尺度的feature map。

在不同尺度的feature map,分别计算损失函数,最终整合到一起计算总损失,反向传播更新网络参数。

预测过程

yolov3_预测过程

摘自B站大佬"同济子豪兄"yolov3系列

预测阶段,网络输出3个尺度的feature map,计算预测框的信息。

设置置信度阈值,过滤掉置信度过低的预测框。

进行非极大值抑制(NMS),去掉重复的次优预测框。

参考自B站大佬"同济子豪兄"yolov3系列


yolov4

2020 Alexey Bochkovskiy, Chien-Yao Wang, Hong-Yuan Mark Liao

YOLOv4: Optimal Speed and Accuracy of Object Detection

(yolov4我们仅简单了解。相较于yolov3,yolov4做了许多方面的改进,这里对部分内容进行简单记录。)

yolov4的优化改进分为两个部分,即Bag of Freebies(BoF)Bag of Specials(BoS)

BoF指的是在训练阶段可以提升模型性能,但在推理阶段不额外增加计算成本的技术。这些技术通常涉及训练过程的调整,不会改变模型的结构或增加推理时的计算负担。

BoS指的是在模型的架构中引入特定的模块或技巧,可能会在推理阶段增加一些计算成本,但能显著提升模型的性能或效率。

Bag of freebies

数据增强(data augmentation)

增加输入图像的可变性,使目标检测模型对从不同环境获得的图像具有更高的鲁棒性。

photometric distortions(光度畸变) and geometric distortions(几何畸变)

随机图像遮挡,多张图像拼接(Mosiac data augmentation)等。

标签平滑(label smoothing)

减少模型对硬标签(hard labels)的依赖,硬标签通常是指完全确定的分类标签,如one-hot编码。硬标签可能会导致模型对输入数据的过分自信,从而降低泛化能力。

软标签(soft labels)将一部分的置信度从真实类别转移到其他类别上,使得标签"更柔软"。例如对于一个K分类的问题,真实标签yy的平滑版本yy'可如下计算:

yi=yi×(1α)+αKy_{i}' = y_{i} \times \left ( 1 - \alpha \right ) + \frac{\alpha}{K}

其中yiy_{i}是原始标签中的第i个元素,α\alpha是一个很小的平滑因子(例如0.1),K是类别总数。

作用:

  1. 减少模型对单个类别的过度自信,提高模型的泛化能力。
  2. 防止过拟合。在训练数据有限,或类别不平衡的情况下,特别有效。
  3. 更平滑的决策边界。软标签有助于模型学习到更平滑的决策边界,对于不明确或边界上的样本,处理更加有效。
  4. 改善模型鲁棒性。

解决类别不平衡的问题

训练数据中,不同类别的数量可能不平衡;训练数据中,背景类可能会绝大多数。

可使用焦点损失(Focal Loss, 出自论文《Focal Loss for Dense Object Detection》),解决不同类别不平衡的问题。适合存在大量背景类(negative class),但较少前景类(positive class)的场景。

对于多分类Focal Loss,计算公式如下:

FL(pt)=c=1Cαc(1pt,c)γyclog(pt,c)FL\left ( p_{t} \right ) = - {\textstyle \sum_{c=1}^{C}} \alpha _{c} \left ( 1 - p_{t,c} \right )^{\gamma}y_{c}log\left ( p_{t,c} \right )

其中:

  • CC是类别总数。
  • αc\alpha_{c}是类别cc的专属平衡因子,用于平滑不同类别的重要性。
  • pt,cp_{t,c}是模型预测样本属于cc类别的概率。
  • ycy_{c}是真实标签,如果样本属于类别cc,则yc=1y_{c} = 1,否则yc=0y_{c} = 0

解释:

  1. αc\alpha_{c}
    • 该项是各个类别的专属平衡因子,可以根据每个类别的样本数量或每个类别的重要性调整αc\alpha_{c},对于样本量较少,或者更重要的类别,αc\alpha_{c}可以调大一些。
  2. (1pt,c)γ\left ( 1 - p_{t,c} \right )^{\gamma}
    • 该项是Focal Loss的核心,称为调焦项(focusing term),γ\gamma是调焦参数。该项的作用是减少易于分类的样本(即模型对其预测很有信心的样本)的损失贡献。当模型对一个样本很有信心时,即pt,cp_{t,c}接近于1,这样减少了该样本的损失贡献;反之,对于难以分类的样本,即pt,cp_{t,c}接近于0,可以保持该样本的损失贡献。
    • 通常,对于目标检测场景,背景样本是易于分类的样本。
  3. yclog(pt,c)- y_{c}log\left ( p_{t,c} \right )
    • 该项是交叉熵损失,用于预测值和真实标签的基础loss计算。

通过上述设计,Focal Loss减少了大量易分类样本对损失的贡献,使得模型能够更专注于学习难样本。这对高度不平衡的数据集(即大量背景类样本,少量前景类样本)特别有效。

优化bounding boxes定位误差损失函数

yolov3通过均方误差(MSE)损失函数,对bounding boxes的坐标和宽高进行回归。(未考虑物体本身的完整性)

yolov4使用CIoU Loss作为bounding boxes的回归损失,考虑了更多的几何因素来提高定位准确性。

CIoU Loss是IoU Loss的改进版,旨在解决原始IoU Loss在某些情况下的缺陷,比如边界框不重叠时梯度消失的问题。

CIoU在损失计算时,考虑了如下三个几何因素:

  1. 重叠面积:CIoU损失保留了IoU损失的特点,即计算预测框和真实框的重叠面积。
  2. 中心点距离:CIoU损失增加了一个项,用于最小化预测框和真实框中心点之间的距离。
  3. 宽高比例:CIoU损失还考虑了预测框和真实框的宽高比例差异,即预测框的宽高比例与真实框的宽高比例不同,模型也会受到惩罚。

CIoU损失的计算公式如下:

CIoU=1IoU+ρ2(b,bgt)c2+αvCIoU = 1 - IoU + \frac{\rho^{2}\left ( b,b_{gt} \right ) }{c^{2}} + \alpha \cdot v

其中:

  • IoU是预测框与真实框的交并比。
  • ρ(b,bgt)\rho \left ( b,b_{gt} \right )是预测框中心点和真实框中心点之间的欧几里得距离。
  • cc是覆盖预测框和真实框最小闭合区域对角线的长度。
  • vv是预测框和真实框宽高比例差异的一个度量。
  • α\alpha是权衡参数,用于平衡IoU与宽高比例差异的影响。

关于IoU Loss的优化改进,是一个不断迭代的过程。大致可以分为:

IoU Loss -> GIoU Loss -> DIoU Loss -> CIoU Loss -> EIoU Loss

IoU Loss:

yolov4_IoU_Loss_问题说明

摘自51CTO博客"zstar"大佬

优点:考虑了重叠面积,归一化坐标尺度。

缺点:如果两个框不相交(即上图状态1),IoU=0,此时将无法反应两个框之间的距离,此时损失函数不可导,IoU Loss无法优化两个框不相交的情况。另外,若两个框相交,但IoU相同(即上图状态2,状态3),此时无法区分状态2与状态3相交情况的不同与优劣。

GIoU Loss:

yolov4_GIoU_Loss

摘自B站"多喝water"大佬

优点:在IoU Loss的基础之上,解决了边界框不相交时loss为0的问题。

缺点:当一个框完全包含另一个框的时候,GIoU Loss会退化成IoU Loss。

DIoU Loss:

优点:在GIoU Loss的基础之上,额外考虑了两个框中心点的欧式距离。

缺点:尚未考虑预测框与gt框的横纵比(宽高比)。

CIoU Loss:

优点:在DIoU Loss的基础之上,额外考虑了预测框与gt框的横纵比(宽高比)

EIoU Loss:

优点:在CIoU Loss的基础之上,分别计算宽高的差异值取代了横纵比。

关于IoU Loss系列,可详细参考下面各位大佬的讲解:

知乎"Chuck"大佬

B站"多喝water"大佬

知乎"陈伟"大佬

51CTO博客"zstar"大佬

DropBlock regularization

(以下内容出自gpt4)

"DropBlock regularization"是一种正则化技术,用于训练卷积神经网络。它是"Dropout"的一种变体,特别适用于卷积层。DropBlock通过随机丢弃连续区域的特征图(feature map)上的神经元,而不是像传统Dropout那样随机丢弃单个神经元,从而提高了模型的泛化能力。

DropBlock与Dropout的区别

  • Dropout随机丢弃单个神经元,适用于全连接层,但在卷积层中不够高效,因为卷积层中相邻的神经元往往高度相关。
  • DropBlock专为卷积层设计,通过丢弃连续的区域,它更有效地减少了特征图中信息的冗余,强迫网络学习更鲁棒的特征,有效防止过拟合的出现。

Batch Normalization与DropBlock共同使用

  1. Batch Normalization

    Batch Normalization通过规范化层的输入,减少了内部协变量偏移(Internal Covariate Shift),可以加快训练速度,提高泛化能力,并使网络对初始化不那么敏感。它通常应用于卷积层或全连接层之后,激活函数之前。

  2. DropBlock

    DropBlock是一种正则化技术,专为卷积层设计,通过在训练过程中随机丢弃特征图上的连续区域,迫使网络不过分依赖于局部特征,从而提高模型的泛化能力。

  3. 共同使用的效果

    当Batch Normalization和DropBlock一起使用时,Batch Normalization负责保持训练过程的稳定性和加速收敛,而DropBlock增强模型的泛化能力。这两种技术的结合可以在加快训练的同时,减少过拟合的风险。

Batch Normalization和Dropout的问题

  • Batch Normalization和Dropout一起使用可能会导致性能下降,主要原因在于Dropout会随机丢弃神经元,这可能会干扰Batch Normalization对特征分布的估计。
  • Batch Normalization依赖于批次中数据的统计特性,而Dropout通过随机丢弃神经元改变了这些统计特性,可能会导致Batch Normalization无法准确估计每个批次的均值和方差。

尽管Batch Normalization和Dropout一起使用可能会遇到一些问题,但Batch Normalization和DropBlock的组合通常是有效的。DropBlock作为一种专为卷积层设计的正则化技术,不会像Dropout那样显著改变特征分布的统计特性,因此与Batch Normalization兼容性更好。在实际应用中,这两种技术的结合经常被用于构建高效和鲁棒的深度学习模型。

Bag of specials

SPP-block

Spatial Pyramid Pooling (SPP) 空间金字塔池化

出自论文《Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition》

Kaiming He, Xiangyu Zhang, Shaoqing Ren, and Jian Sun

yolov4_SPPnet_网络结构

SPP解决了传统CNN网络对输入图片尺寸固定的限制。(CNN中全连接层需固定输入图像尺寸)

采用"比例池化"的方法,对任意输入图像的尺寸,输出固定维度的特征,传给后续的全连接层。

可以增加感受野并分离出上下文特征。

具体实现细节:

SPP分别使用三个不同维度的pooling核进行池化操作,各池化核大小根据实际输入特征维度自适应改变,但池化后的结果维度是固定的。以上图为例,对于任意维度的输入特征(channel=256),SPP均会输出4 * 4,2 * 2,1 * 1维度的结果(channel=256)。即不论你的输入是多大,SPP在每个channel上都会提取4 * 4 + 2 * 2 + 1 * 1 = 21维的特征向量。(池化操作对每个channel都是独立进行的)

yolov4_传统CNN网络与SPPnet网络结构对比

上图中,流程1是传统CNN架构,图像(image)经过裁剪或拉伸(crop/warp)统一尺寸,再传给卷积层(conv layers),再传给全连接层(fc layers);流程2是SPPnet架构,图像(image)直接传给卷积层(conv layers),然后经过SPP处理,统一维度尺寸,再传给全连接层(fc layers)。

关于SPPnet,可详细参考下面各位大佬的讲解:

CSDN"yanghaoplus"大佬

知乎"论智"大佬

b站"蒙特卡洛家的树"大佬

PAN

PAN结构是在FPN结构上做的改进。

FPN

Feature Pyramid Network 特征金字塔网络

出自论文《Feature Pyramid Networks for Object Detection》

Tsung-Yi Lin, Piotr Dollár, Ross Girshick, Kaiming He, Bharath Hariharan, Serge Belongie

yolov4_FPN网络结构

摘自知乎大佬"薰风初入弦"

FPN的主要意义在于:

  1. 借鉴了ResNet的跳接,结合了浅层特征和深层特征。(深层高等语义,低分辨率;浅层低等语义,高分辨率)
  2. 借鉴了SSD的检测策略,在不同分辨率的特征图上分别做预测。

识别小物体是目标检测算法的困难所在,特征金字塔网络(FPN)可以用来解决不同尺寸目标预测的问题。

  1. 在图像金字塔提取特征 (Featurized Image Pyramid) (图a)

    最原始的想法,既然图片太小预测不出来,那么就把图片缩放到不同的大小,分别进行预测。

    流程:把一张图片提取特征预测 -> 放大 -> 提取特征预测 -> 放大 -> 提取特征预测…

    每次特征提取/预测都是独立进行的,模型预测更加耗时,原本一张图片预测需要5秒,一个5级图像金字塔耗时可能会高于25秒。

    上述内容仅为模型预测,而模型训练会更加耗时。出于这种考虑,图像金字塔通常只用于预测阶段。此时模型本质上只是在某一个分辨率上训练的,但是却强行去检测别的分辨率,检测效果较差。

  2. 原始CNN (图b)

    CNN可以有层次地学习图片特征,深度越深,特征的语义越高级(从线到面,再到物体特征),而浅层网络的特征图可以保留更多的分辨率,但是特征的语义较为低级。

    因此CNN只能寄希望于小物体的特征能够在最后一层"存活下来",但由于分辨率的损失,这往往很难做到。

    相较于图a而言,CNN对各层级的特征是"共享的",而不是相互独立的。

    因此,考虑使用多个层级、不同分辨率的特征进行预测

  3. 金字塔型特征层级 (Pyramidal feature hierarchy) (图c)

    SSD(Single Shot MultiBox Detector)目标检测网络,就是使用不同分辨率特征进行预测的。想法是正确的,但仍存在两个问题:

    1. 底层特征语义不够
    2. 深层分辨率不高

    因此,考虑结合深浅层网络的特征,兼顾分辨率和特征语义

  4. 特征金字塔网络 (Feature Pyramid Network, FPN) (图d)

    FPN可以分为三个部分:

    • 自底向上的部分 (底=高分辨率)
    • 自顶向下的部分 (顶=低分辨率)
    • 连接两部分的跳接

    FPN将浅层的特征跳接到深层的特征

    FPN将深/浅层特征融合多分辨率预测结合了起来。

PAN

Path Aggregation Network (PAN) 路径聚合网络

出自论文《Path Aggregation Network for Instance Segmentation》

Shu Liu, Lu Qi, Haifang Qin, Jianping Shi, Jiaya Jia

yolov4_PAN网络结构

PAN网络旨在促进特征于网络中的信息流动。

PAN的主要内容分为三个部分:bottom-up path augmentation、adaptive feature pooling、fully-connected feature fusion。

bottom-up path augmentation

低层特征有助于实例的边缘信息定位识别,但从底层结构到最高层特征有很长的路要走(即上图中的红色虚线路径,可能会超过100层),这增加了获取准确定位信息的难度。

PAN在FPN的基础之上,通过自下而上的路径增强(bottom-up path augmentation),用较低层中准确的定位信息增强了整个特征金字塔,缩短了较低层和最顶层特征之间的信息路径(即上图中的绿色虚线路径,不超过10层)。

adaptive feature pooling

对于FPN,会根据proposal(提取的候选区域,候选框)的大小,将其分配到不同的特征层级。即将小尺寸的proposal分配给低特征层级,将大尺寸的proposal分配给高特征层级。

单一的特征层级分配可能并非最优解法,比如两个proposal大小仅相差10个像素,但有可能会被分配到不同的特征层级,即使它们非常相似。

高级别的特征由大的感受野生成并提取了更丰富的上下文信息,让小的proposal获取这些信息可以更好的进行预测;低级别的特征包含丰富的细节信息以及更好的定位精度,让大的proposal获取这些信息也是有意义的。

为避免了单一分配的不良结果,PAN提出了"自适应特征池化"的概念。对于每个proposal,首先将它映射到所有特征层级,即上图(b)中的灰色区域,然后延续Mask R-CNN的做法,对每个特征层级进行ROI Align操作(准确提取出于原始图像中感兴趣区域(Region of Interest, ROI)相对应的特征),接着对不同层级的feature grid进行融合(即上图中©的操作)。

fully-connected feature fusion

原始的Mask R-CNN中,mask预测分支是FCN的结构,因为全连接层可以提取到和卷积层不同的信息,作者在mask预测分支新增了一个fc分支。

关于FPN和PAN,可详细参考下面各位大佬的讲解:

知乎"薰风初入弦"大佬

CSDN"00000cj"大佬

消除网格敏感度(Eliminate grid sensitivity)

优化yolov2对anchor位置的限制。

观察yolov2对anchor位置限制说明图(即"yolov2_网络输出结构对比yolov1_1.png"),如果希望预测框中心点位于网格边界,则txt_xtyt_y需取到非常小或非常大的值。

yolov4_消除网格敏感度

参考自B站"霹雳吧啦Wz"大佬

yolov4对上述问题进行优化,将公式:

bx=σ(tx)+cxb_{x} = \sigma \left ( t_{x} \right ) + c_{x}

by=σ(ty)+cyb_{y} = \sigma \left ( t_{y} \right ) + c_{y}

修改为:

bx=(σ(tx)scalexyscalexy12)+cxb_{x} = \left ( \sigma \left ( t_{x} \right ) \cdot scale_{xy} - \frac{scale_{xy} - 1}{2} \right ) + c_{x}

by=(σ(ty)scalexyscalexy12)+cyb_{y} = \left ( \sigma \left ( t_{y} \right ) \cdot scale_{xy} - \frac{scale_{xy} - 1}{2} \right ) + c_{y}

一般scalexyscale_{xy}取为2,即

bx=(2σ(tx)0.5)+cxb_{x} = \left ( 2 \cdot \sigma \left ( t_{x} \right ) -0.5 \right ) + c_{x}

by=(2σ(ty)0.5)+cyb_{y} = \left ( 2 \cdot \sigma \left ( t_{y} \right ) -0.5 \right ) + c_{y}

扩充正样本数量

yolov3中,只将与gt框共属同一个grid cell,且IOU最大的anchor作为正样本(即仅取唯一正样本),其他anchor要么直接放弃(anchor与gt框IOU高于某一阈值,但非最大),要么作为负样本(anchor与gt框IOU低于某一阈值)。这可能会导致训练时,正样本数量非常的少。

为扩充正样本,可尝试采用如下方案:

  1. 设定IOU阈值,若anchor与gt框IOU高于该阈值,则将该anchor置为正样本。

  2. 根据gt框中心点相对于当前grid cell的位置,若gt框中心点偏向于左上角,则可将当前grid cell的左侧相邻、上侧相邻的grid cell的anchor,纳入正样本的考察范围(即相邻grid cell的anchor,若与gt框的IOU大于某一阈值,可将该相邻grid cell的anchor取为正样本)。若gt框中心点偏向其他位置,可同样处理。

    yolov4_扩充正样本

    摘自B站"霹雳吧啦Wz"大佬

yolov5

我们基于yolov5实现了"目标人员是否佩戴安全帽检测"。代码、详细注释、网络预测效果,请详见github与wandb。

https://github.com/YADIANNADETIANFA/yolov5

https://wandb.ai/icarus_athena/YOLOv5/overview?workspace=user-icarus_athena

yolov5_网络结构

摘自CSDN大佬"满船清梦压星河HK"


附录

map的概念

任何一个预测框,都必属于这4类之一

  • TP (true positive):真正例

  • FP (false positive):假正例

  • TN (true negative):真负例

  • FN (false negative):假负例

附录_map_1

精确度,查准率

“预测为正且实际为正”,占"预测为正"的比例。

Precision=TPTP+FPPrecision = \frac{TP}{TP + FP}

召回率,查全率

“预测为正且实际为正”,占"实际为正"的比例。

Recall=TPTP+FNRecall = \frac{TP}{TP + FN}

准确率

“预测为正且实际为正"和"预测为负且实际为负”,占总样本数的比例。

Accuracy=TP+TNTP+FP+TN+FNAccuracy = \frac{TP + TN}{TP + FP + TN + FN}

预测阶段,某一个预测框在预测某一个类别时,给出的预测结果,即置信度,ConfConf.

人为设定一个置信度门限值,即阈值,PthreshPthresh.

IoUIoU:某一个预测框与gt框面积的交并比。

IoUthreshIoU_{thresh}:人为设定一个门限值。

所以

  1. IoU>IoUthreshIoU > IoU_{thresh},站在上帝视角,该预测框成功识别了该物体,不论该预测框自己是否这样认为。
  2. IoU<IoUthreshIoU < IoU_{thresh},站在上帝视角,该预测框失败识别了该物体,不论该预测框自己是否这样认为。
  3. Conf>PthreshConf > Pthresh,该预测框"自认为"成功识别了该物体,不论真实情况如何(预测框没办法开上帝视角)。
  4. Conf<PthreshConf < Pthresh,该预测框"自认为"失败失败了该物体,不论真实情况如何(预测框没办法开上帝视角)。

简言之,IoUIoUIoUthreshIoU_{thresh}之间的比较,决定了真实情况的如何;而ConfConfPthreshPthresh之间的比较,决定了预测情况的如何。

TP:{Conf>Pthresh,IoU>IoUthresh}TP: \left \{ Conf > Pthresh, IoU > IoU_{thresh} \right \}

FP:{Conf>Pthresh,IoU<IoUthresh}FP: \left \{ Conf > Pthresh, IoU < IoU_{thresh} \right \}

FN:{Conf<Pthresh,IoU>IoUthresh}FN: \left \{ Conf < Pthresh, IoU > IoU_{thresh} \right \}

TN:{Conf<Pthresh,IoU<IoUthresh}TN: \left \{ Conf < Pthresh, IoU < IoU_{thresh} \right \}

综上,想计算TP、FP、FN、TN,就必须给定"PthreshPthresh置信度"和"IoUthreshIoU_{thresh}交并比阈值"。进而,想计算PrecisionPrecisionRecallRecall,必须给定上述两阈值。

每给定一组"PthreshPthresh置信度阈值"和"IoUthreshIoU_{thresh}交并比阈值",就能计算出一组"PrecisionPrecision"和"RecallRecall"。

有了以上的概念,我们就可以定义下面的性能指标。

AP@0.5AP@0.5IoUthresh=0.5IoU_{thresh} = 0.5PthreshPthresh从1到0,P-R曲线所围成的面积。

mAP@0.5mAP@0.5:各类别的AP@0.5AP@0.5求平均。

mAP@0.5:0.95mAP@0.5:0.95mAP@0.5mAP@0.5mAP@0.55mAP@0.55mAP@0.6mAP@0.6,…(以0.05为步长)…,mAP@0.95mAP@0.95求平均。

关于AP@0.5AP@0.5,P-R曲线

附录_P-R曲线

P-R曲线大致如上图所示。P越大则R越小;P越小则R越大。

Pthresh=1Pthresh = 1,FP根据公式会达到最小值,FN根据公式会达到最大值。

Precision=TPTP+FP=Precision_maxPrecision = \frac{TP}{TP + FP} = Precision\_max

Recall=TPTP+FN=Recall_minRecall = \frac{TP}{TP + FN} = Recall\_min

Pthresh=0Pthresh = 0,FP根据公式会达到最大值,FN根据公式会达到最小值。

Precision=TPTP+FP=Precision_minPrecision = \frac{TP}{TP + FP} = Precision\_min

Recall=TPTP+FN=Recall_maxRecall = \frac{TP}{TP + FN} = Recall\_max

PthreshPthresh从1到0变化,Precision:maxminPrecision: max \to minRecall:minmaxRecall: min \to max

与P-R曲线变化一致。