计算机视觉算法——目标检测网络总结
- 计算机视觉算法——目标检测网络总结
-
- 1. RCNN系列
-
- 1.1 RCNN
-
- 1.1.1 关键知识点——网络结构及特点
- 1.1.2 关键知识点——RCNN存在的问题
- 1.1.3 关键知识点——非极大值抑制算法(NMS)
- 1.2 Fast RCNN
-
- 1.2.1 关键知识点——网络结构及特点
- 1.2.1 关键知识点——目标检测多任务损失
- 1.2.3 关键知识点——训练数据的采样
- 1.3 Faster-RCNN
-
- 1.3.1 关键知识点——网络结构及特点
- 1.3.2 关键知识点——RPN网络
- 1.3.3 关键知识点——RPN Loss和Fast RCNN Loss联合训练
- 2. SSD系列
-
- 2.1 SSD
-
- 2.1.1 关键知识点——网络结构及特点
- 2.2.1 关键知识点——Default Box的设定
- 2.2.2 关键知识点——Predictor的实现
- 3. YOLO系列
-
- 3.1 YOLO v1
-
- 3.1.1 关键知识点——网络结构及特点
- 3.1.2 关键知识点——损失计算函数
- 3.1.3 关键知识点——YOLO v1存在的问题
- 3.2 YOLO v2
-
- 3.2.1 关键知识点——网络的结构及特点
- 3.2.1 关键知识点——提升mAP参数的方法
- 3.3 YOLO v3
-
- 3.3.1 关键知识点——网络结构及特点
- 3.3.2 关键知识点——损失计算函数
- 3.4 YOLO v3 SPP
-
- 3.4.1 关键知识点——Mosaic图像增强
- 3.4.2 关键知识点——SPP模块
- 3.4.3 关键知识点——CloU Loss
- 4. FPN系列
-
- 4.1 FPN
-
- 4.2 RetinaNet
-
- 4.2.1 关键知识点——网络结构及特点
- 4.2.2 关键知识点——Focal Loss
计算机视觉算法——目标检测网络总结
由于后面工作方向的需要,也是自己的兴趣,我决定补习下计算机视觉算法相关的知识点,参考的学习资料主要是B站Up主霹雳吧啦Wz,强推一下,Up主的分享非常的细致认真,从他这里入门是个不错的选择,Up主也有自己的CSDN博客,我这里主要是作为课程的笔记,也会加入一些自己的理解,我也只是个入门的小白,如果有错误还请读者指正。
目标检测网络是计算机视觉一个重要的应用领域,主要分为One-Stage和Two-Stage两类方法,下面开始逐个总结各个图像分类网络的特点。
1. RCNN系列
RCNN系列是由RCNN->Fast RCNN->Faster RCNN组成,三个网络的框架分别如下图所示:
RCNN网络框架:
Fast RCNN网络框架:
Faster RCNN网络框架:
下面分别介绍这三个网络细节
1.1 RCNN
RCNN是2014年提出的,一经提出就将目标检测准确率提升了30%
1.1.1 关键知识点——网络结构及特点
RCNN网络结构如下图所示:
该算法主要分为四个步骤:
- 使用Selective Search方法在图像上生成1000至2000个候选区域;
Selective Search算法是通过图像分割的方法得到一些原始区域,然后使用合并策略将区域合并从而得到一个层次化的区域结构,而这些结构中就包含着可能需要检测的物体。
- 对每个候选区域使用深度网络(图像分类网络)提取特征;
将2000个候选区域缩放到 227 × 227 227\times227 227×227个像素大小,然后将候选区域输入实现训练好的AlexNet CNN网络获得4096维的特征,即 2000 × 4096 2000 \times 4096 2000×4096维的矩阵。
- 将特征送入每一类的SVM分类器,判断该区域是否属于该类;
将 2000 × 4096 2000 \times 4096 2000×4096维特征与20个SVM分类器组成的 4096 × 20 4096 \times 20 4096×20维权重矩阵相乘,获得 2000 × 20 2000 \times 20 2000×20维矩阵,该矩阵表示每个建议框是某个目标分类的得分,如下图所示:
分别对上述 2000 × 20 2000 \times 20 2000×20维矩阵中每一列即每一列进行非极大值抑制剔除重叠建议框,得到该类中得分最好的建议框。非极大值抑制算法在后文介绍。
- 使用回归器精细修正候选框位置;
对通过非极大值抑制处理后的剩余边界框进行进一步筛选,接着分别用20个回归器对上述20个类别的建议框进行回归操作,最终得到每个类别修正后得分最高的边界框,这个回归操作在后面的Fast RCNN进行详解。
1.1.2 关键知识点——RCNN存在的问题
- 测试速度慢,测试一张图片在CPU上需要53S,使用Selective Search算法提取候选框需要2S,一张图像内候选框之间存在大量重叠,提取特征操作存在大量冗余;
- 训练速度慢,过程极其繁琐,不仅需要训练图像分类网络,还需要训练SVM分类器、Bounding Box回归器,训练过程都是相互独立的;
- 训练所需空间大,对于SVM和Bounding Box回归训练,需要从每个图像中的每个目标候选框提取特征,并写入磁盘,对于非常深的网络,训练集上5K图像上提取的特征需要数百GB的存储空间。
1.1.3 关键知识点——非极大值抑制算法(NMS)
RCNN中应用的非极大值抑制算法的步骤如下:
- 在当前类别的候选边界框中寻找得分最高的边界框;
- 计算其他边界框与该边界框的IOU值;
- 删除所有IOU值大于给定阈值的目边界框;
经过上述步骤后就将最高得分的目标保存下来,再在剩下的边界框中寻找得分最高的边界框重复上述步骤。其中IOU值的计算即两个边界框交集的区域面积除以两个边界框并集区域面积,越大说明两个边界框重合区域越大,两个边界框越有可能检测到同一物体。
1.2 Fast RCNN
Fast RCNN使用VGG16作为网络的Backbone,与RCNN相比训练时间快了9倍,推理测试时间快了213倍,准确率从62%提高到66%
1.2.1 关键知识点——网络结构及特点
Fast RCNN网络结构如下图所示:
该算法主要有如下几个步骤:
- 使用Selective Search方法在图像上生成1000至2000个候选区域
该步骤与RCNN相同,在此不进行赘述。
- 将图像输入网络得到相应的特征图,将Selective Search生成的候选框投影到特征图上得到相应的特征矩阵
在RCNN中是将第一步获得的2000个候选区域缩放到同一大小后如数到特征提取网络中,而FastRCNN是将整张图像送入网络,紧接着从特征图上提取相应的候选区域,这样做的好处是避免了候选区域的特征重复计算。下面这张图就说明了RCNN和FastRCNN在这一关键步骤的不同之处
- 将每个特征矩阵通过ROI Pooling层缩放到 7 × 7 7 \times 7 7×7大小的特征图,接着将特征图展平通过一系列全连接成得到预测结果
所谓ROI pooling就是将输出特征划分为 7 × 7 7 \times 7 7×7的网格,每个网络输出该网格数值最大的特征值,最后无论原特征矩阵多大最终都得到一个 7 × 7 7 \times 7 7×7大小的特征图,接下来我们看一下最后全连接层的结构,如下图所示:
将 7 × 7 7 \times 7 7×7大小的特征图进行展平处理后通过两个全连接层后得到ROI feature vector,接下来并联了两个全连接层,最后就进行损失计算。
1.2.1 关键知识点——目标检测多任务损失
前文提到ROI Feature Vector后面并联了两个全连接层,其中左侧全连接层对接分类器,右侧全连接层对接边界框回归器,两个不同功能的模块组成目标检测中的多任务损失,在目标检测网络中这是通用的一种损失构建方式,下面具体介绍:
- 分类器:分类器输出 N + 1 N+1 N+1个类别的概率(其中 N N N为检测目标的种类,1为背景的概率),因此其对应的全连接层共 N + 1 N+1 N+1个节点,其中 N N N个种类概率是通过softmax输出的,因此这 N N N个种类的概率和为1,因此
- 边界框回归器:边界框回归器输出对应 N + 1 N+1 N+1个类别的候选边界框回归参数 d x , d y , d w , d h d_x,d_y,d_w,d_h dx,dy,dw,dh,因此其对应的全连接层共 ( N + 1 ) × 4 (N+1)\times 4 (N+1)×4个节点
候选框相关的计算公式如下: G ^ x = P w d x ( P ) + P x \hat{G}_{x}=P_{w} d_{x}(P)+P_{x} G^x=Pwdx(P)+Px G ^ y = P h d y ( P ) + P y \hat{G}_{y}=P_{h} d_{y}(P)+P_{y} G^y=Phdy(P)+Py G ^ w = P w exp ( d w ( P ) ) \hat{G}_{w}=P_{w} \exp \left(d_{w}(P)\right) G^w=Pwexp(dw(P)) G ^ h = P h exp ( d h ( P ) ) \hat{G}_{h}=P_{h} \exp \left(d_{h}(P)\right) G^h=Phexp(dh(P))其中 P x , P y , P w , P h P_{x}, P_{y}, P_{w}, P_{h} Px,Py,Pw,Ph分别为候选框的中心 x , y x,y x,y坐标以及宽高, G ^ x , G ^ y , G ^ w , G ^ h \hat{G}_{x}, \hat{G}_{y}, \hat{G}_{w}, \hat{G}_{h} G^x,G^y,G^w,G^h分别为最终预测的边界框中心 x , y x,y x,y坐标以及宽高,那么 d x , d y , d w , d h d_x,d_y,d_w,d_h dx,dy,dw,dh就分别是对候选框的中心和宽高调整的参数。
- 基于以上分类器和回归器计算的多任务损失如下: L ( p , u , t u , v ) = L c l s ( p , u ) + λ [ u ≥ 1 ] L l o c ( t u , v ) L\left(p, u, t^{u}, v\right)= L_{c l s}(p, u)+ \lambda[u \geq 1] L_{l o c}\left(t^{u}, v\right) L(p,u,tu,v)=Lcls(p,u)+λ[u≥1]Lloc(tu,v)其中 p p p是分类器预测的softmax概率分布 p = ( p 0 , … , p k ) p=\left(p_{0}, \ldots, p_{k}\right) p=(p0,…,pk), u u u对应目标真实分类标签, t u t^u tu对应边界框回归器预测的对应类别 ( t x u , t y u , t w u , t h u ) \left(t_{x}^{u}, t_{y}^{u}, t_{w}^{u}, t_{h}^{u}\right) (txu,tyu,twu,thu), v v v对应真实目标的边界框回归参数 ( v x , v y , v w , v h ) \left(v_{x}, v_{y}, v_{w}, v_{h}\right) (vx,vy,vw,vh)。
分类损失函数计算公式为: L c l s ( p , u ) = − log p u L_{c l s}(p, u)=-\log p_{u} Lcls(p,u)=−logpu这里的 p u p_{u} pu指的就是当前分类器预测结果为类别 u u u的概率,我们知道,于多分类问题,我们通常采用交叉熵损失(Cross Entropy Loss),计算公式如下: H = − ∑ i p i ∗ log ( p i ) H=-\sum_{i} p_{i}^{*} \log \left(p_{i}\right) H=−i∑pi∗log(pi)其中 p i ∗ p_{i}^{*} pi∗为one-hot编码的真实标签值,也就是说,该标签值只有在正确标签值的位置才为1,其他位置都为0,因此 L c l s ( p , u ) L_{c l s}(p, u) Lcls(p,u)实际就是交叉熵损失
边界框回归损失计算公式为: L l o c ( t u , v ) = ∑ i ∈ { x , y , w , h } smooth L 1 ( t i u − v i ) L_{l o c}\left(t^{u}, v\right)=\sum_{i \in\{x, y, w, h\}} \operatorname{smooth}_{L_{1}}\left(t_{i}^{u}-v_{i}\right) Lloc(tu,v)=i∈{ x,y,w,h}∑smoothL1(tiu−vi) smooth L 1 ( x ) = { 0.5 x 2 if ∣ x ∣ < 1 ∣ x ∣ − 0.5 otherwise \operatorname{smooth}_{L_{1}}(x)=\left\{\begin{array}{ll} 0.5 x^{2} & \text { if }|x|<1 \\ |x|-0.5 & \text { otherwise } \end{array}\right. smoothL1(x)={ 0.5x2∣x∣−0.5 if ∣x∣<1 otherwise 此外 λ \lambda λ为两类损失的权重系数, [ u ≤ 1 ] [u\leq1] [u≤1]是艾弗森括号,sunshi它的作用是控制确实有目标物体存在的正样本才会计算边界框回归损失。
1.2.3 关键知识点——训练数据的采样
数据平衡在网路训练中是非常重要的:
- 在FastRCNN的训练中,采用的mini-batches的大小为128,但是使用的训练数据并不是这128张图通过Selective Search算法中获得的2000个候选框,而是从每张图里面采样64个候选框,其中25%的候选框为与GroundTruth的IOU大于0.5,我们可以将这些候选框视为正样本,剩下的候选框与GroundTruth的IOU为0.1到0.5,这些候选框可以视为负样本
- 通过这样的数据采样手段可以保证我们每次采样过程中获得的正负样本基本都是均衡的,这样对于最后的训练结果的提升是有非常有帮助的。
1.3 Faster-RCNN
Faster R-CNN同样使用的是VGG16作为网络的Backbone,推理速度在GPU上达到了5fps,达到了接近实时的水平
1.3.1 关键知识点——网络结构及特点
Faster-RCNN网络结构如下:
Faster-RCNN已经是一个端到端的网络了,该算法主要有如下几个步骤:
- 将图像输入网络得到相应的特征图
该步骤与Fast RCNN相同,在此就不再进行赘述。
- 使用RPN结构生成候选框,将RPN生成的候选框投影到特征图上后获得相应的特征矩阵
这一步就是Faster RCNN的精华,前文我们提到,基于传统分割方法的Selective Search算法提取候选框需要2S,这相对网络的其他推理部分是非常耗时的,作者因此将这一部分也替换成网络结构,实现了端到端的网路推理,具体的RPN网络结构设计细节参考下文关键知识点。
- 将每个特征矩阵通过ROI Poling层缩放到 7 × 7 7 \times 7 7×7大小的特征图,接着将特征图展平通过一系列全连接层得到预测结果;
该步骤与Fast RCNN相同,在此不再进行赘述。
1.3.2 关键知识点——RPN网络
RPN网络结构如下图所示:
- 网络结构细节如下,RPN网络同Fast RCNN网络是通用的VGG16作为特征提取的backbone,因此上图拿到的实际上就是VGG16提取的特征图,对于特征图上的每个 3 × 3 3 \times 3 3×3的滑动窗口,计算出特征图中滑动窗口中心位置对应原始图像上的中心点坐标以及基于原始图像上的中心点坐标生成 k k k个Anchor Boxes,根据滑动窗口里的256维向量(ZF网络作为Backbone为256维,而VGG网络为512维),对于每个Anchor Box计算出2个概率(前景、背景的概率,这里不进行分类)以及4个坐标,也就是说,也就是说每个滑动窗口会输出 2 k 2k 2k个概率以及 4 k 4k 4k个坐标。在论文中提到的Anchor Box一共有3种尺度( 12 8 2 , 25 6 2 , 51 2 2 128^{2}, 256^{2}, 512^2 1282,2562,5122)和3种比例( 1 : 1 , 1 : 2 , 2 : 1 1:1, 1:2, 2:1 1:1,1:2,2:1),也就是说这里的 k = 9 k=9 k=9,如下图所示:
这里值得注意的一点是VGG的感受野是 228 228 228,而anchor的尺度最大的会达到 512 × 512 512 \times 512 512×512,这相当于是用一个小的感受野去预测一个大的物体,在论文中作者有提到这一点,并认为这是可行的。
- 多任务损失计算细节如下,RPN网络的的多任务损失定义如下:
L ( { p i } , { t i } ) = 1 N c l s ∑ i L c l s ( p i , p i ∗ ) + λ 1 N r e g ∑ i p i ∗ L reg ( t i , t i ∗ ) L\left(\left\{p_{i}\right\},\left\{t_{i}\right\}\right)=\frac{1}{N_{c l s}} \sum_{i} L_{c l s}\left(p_{i}, p_{i}^{*}\right)+\lambda \frac{1}{N_{reg}} \sum_{i} p_{i}^{*} L_{\text {reg }}\left(t_{i}, t_{i}^{*}\right) L({ pi},{ ti})=Ncls1i∑Lcls(pi,pi∗)+λNreg1i∑pi∗Lreg (ti,ti∗)其中:
p i p_i pi表示第i个Anchor预测为真实标签的概率;
p i ∗ p_i^* pi∗为正样本时为1,为负样本时为0,这和Faster RCNN中的艾弗森括号的作用是相同的;
t i t_i ti表示预测第 i i i个Anchor的边界框回归参数;
t i ∗ t_i^* ti∗表示第 i i i个Anchor对应的Ground Truth Box;
N c l s N_{cls} Ncls表示一个mini-batch中的所有样本数量;
N r e g N_{reg} Nreg表示Anchor位置的个数(注意不是Anchor的个数,Anchor的个数等于Anchor的位置个数乘以 k k k);
上述损失计算公式中前一部分为分类损失,如果使用多类别的Softmax交叉熵损失,因为此处的类别只有前景和背景两类,如下,那么对于每个Anchor分别计算出属于前景和背景的概率,对于 k k k个Anchor就需要计算出 2 k 2k 2k个值:
具体公式如下所示: L c l s = − log ( p i ) L_{cls}=-\operatorname{log}(p_i) Lcls=−log(pi)如果使用的是二分类的交叉熵损失,那么此处对于每个Anchor就只计算出一个概率,如下,对于 k k k个Anchor就需要计算出 k k k个值:
具体公式如下所示: L c l s = − [ p i ∗ log ( p i ) + ( 1 − p i ∗ ) log ( 1 − p i ) ] L_{c l s}=-\left[p_{i}^{*} \log \left(p_{i}\right)+\left(1-p_{i}^{*}\right) \log \left(1-p_{i}\right)\right] Lcls=−[pi∗log(pi)+(1−pi∗)log(1−pi)]损失计算公式中的后一部分为边界框回归损失,边界框回归损失的形式和Faster RCNN的形式是一样的,使用的也是Smooth L1损失,在这里就不进行赘述了。
1.3.3 关键知识点——RPN Loss和Fast RCNN Loss联合训练
原论文中采用RPN Loss和Fast RCNN Loss联合训练的方法如下:
- 利用ImageNet预训练分类模型初始化前置卷积网络层参数,并开始单独训练RPN网络参数;
- 固定RPN网络独有的卷积以及全连接层参数,利用ImageNet预训练分类模型初始化前置卷积网络参数,并利用RPN网络生成的目标建议框去训练Fast RCNN网络参数;
- 固定利用Fast RCNN训练好的前置卷积网络层参数,去微调RPN网络独有的卷积层以及全连接层参数;
- 同样保持固定前置卷积网络层参数,去微调Fast RCNN网络的全连接层参数。最后PRN网路与Fast RCNN网络共享前置军妓网络层参数,构成一个统一网络。
2. SSD系列
SSD是2016年在ECCV上发表的论文,在 300 × 300 300\times 300 300×300的网络上达到了74.3%mAP以及59FPS,在 512 × 512 512\times512 512×512的网络上,以76.3%mAP超越了Faster RCNN的73.2%mAP
2.1 SSD
2.1.1 关键知识点——网络结构及特点
在前文提到的Faster RCNN中存在两个问题分别是对
- 小目标检测效果较差:Faster RCNN中采用的都是高层特征信息,这部分信息细节信息保留少,因此对于小目标检测效果差;
- 模型大、检测速度慢:Faster RCNN采用的是Two Stage的结构,这是导致检测速度慢的主要原因。
而SSD网络结构如下:
从上图中可以看到,SSD的网络结构为One-Stage结构,并且在不同特征尺度上预测不同尺度的目标,下面我们具体来说,SSD网络是使用VGG16作为backbone,如下图所示:
- . SSD网络中的Conv4_3就对应VGG网络中 28 × 28 × 512 28 \times 28 \times 512 28×28×512卷积模块的第三个卷积层,输出为 38 × 38 × 512 38 \times 38 \times 512 38×38×512的特征矩阵;
- SSD网络中的Conv5_3就对应VGG网络中 14 × 14 × 512 14 \times 14 \times 512 14×14×512卷积模块的第三个卷积层位置,输出为 19 × 19 × 1024 19 \times 19 \times 1024 19×19×1024的特征矩阵;
- SSD网络中的Conv6就对应VGG网络中的第一个全连接层,由于SSD网络对VGG网络中的 7 × 7 × 512 7 \times 7 \times 512 7×7×512的池化层进行了修改,因此输出仍然为 19 × 19 × 1024 19 \times 19 \times 1024 19×19×1024的特征矩阵;
- SSD网络中的Conv7就对应VGG网络中的第二个全连接层,输出为 19 × 19 × 512 19 \times 19 \times 512 19×19×512的特征矩阵;
- 紧接着SSD网络中还跟着四个卷积层,输出分别是 10 × 10 × 512 10 \times 10 \times 512 10×10×512, 5 × 5 × 256 5 \times 5 \times 256 5×5×256, 3 × 3 × 256 3 \times 3 \times 256 3×3×256, 1 × 1 × 256 1 \times 1 \times 256 1×1×256的特征矩阵,特征矩阵的尺寸越来越小,说明所提取的特征也越来越高级,我们会用大尺寸的特征矩阵预测较小的目标,用小尺寸的特征矩阵预测较大的目标,因此以上提到的所有输出特征矩阵都会输出到Prediction层进行预测。
2.2.1 关键知识点——Default Box的设定
SSD中Default Box和前文Faster RCNN中提到的RPN网络的中Anchor Box是同一个概念,但是RPN网络的特征层就一层,而SSD网络用于预测的特征层是多层,因此Defaul Box的设定会更为复杂,具体规则如下:
- 对与SSD中每一个预测特征层的Default Box都会有不同的尺度(Scale)和长宽比(Aspect),论文中规定,对于Aspect,不同的特征层都只有 { 1 , 2 , 3 , 1 / 2 , 1 / 3 } \left\{1,2,3, {1}/{2}, {1}/{3}\right\} { 1,2,3,1/2,1/3}这五种类型,而对于Scale,不同特征层则不相同,第 k k k个预测特征层的Default Box的Scale的公式如下: s k = s min + s max − s min m − 1 ( k − 1 ) , k ∈ [ 1 , m ] s_{k}=s_{\min }+\frac{s_{\max }-s_{\min }}{m-1}(k-1), \quad k \in[1, m] sk=smin+m−1smax−smin(k−1),k∈[1,m]其中, s m i n s_{min} smin为最小的尺度, s m a x s_{max} smax为最大的尺度。最后还有一个规则是,对于Aspect为1的Default Box,还有一个额外的 s k s k + 1 \sqrt{s_ks_{k+1}} sksk+1 的尺寸,因此综上所属对于每一个特征层一共有6中不同的Default Box。
- 在学习视频中作者总结了如下一张表格,说明了SSD中具体的Default Box的设置
细心的同学可能会注意到,在第一、五、六个特征层中,实际Default Box的尺寸只有4种,那是因为在这几层忽略了Aspect为3和1/3的两个Default Box,那么整个SSD网络中Default Box的数量一共为 38 × 38 × 4 + 19 × 19 × 6 + 10 × 10 × 6 + 5 × 5 × 6 + 3 × 3 × 4 + 1 × 1 × 4 = 8732 38 \times 38 \times 4+19 \times 19 \times 6+10 \times 10 \times 6+5 \times 5 \times 6+3 \times 3 \times 4+1 \times 1 \times 4=8732 38×38×4+19×19×6+10×10×6+5×5×6+3×3×4+1×1×4=8732我们这里还需要注意的一点是,这里的尺度Scale指的是原图中Default Box大小,对于这一点视频作者还画了一个图我觉得非常有助于我们理解,如下
对于第一个特征层,左上角的Anchor使用如图三种Scale较小的Default Box(大小为21个像素左右)去检测左上角的那辆面积较小的白车,而对于第四个特征层,中间区域的Anchor使用如果所示的六种Scale较大的Default Box(大小为153个像素左右)去检测中间那辆面积较大的红车。
2.2.2 关键知识点——Predictor的实现
这里所谓的Predictor其实指的就是最后的用于进行分类和回归损失计算,在Faster RCNN中最后获得的特征矩阵是通过ROI Pooling Layer变换成大小相同的特征矩阵,再展开成ROI Pooling Vector,最后通过两个全连接层再进行分类和回归损失计算的,而在SSD中,是通过小尺寸的卷积核对特征矩阵进行变换在进行分类和回归层计算的,具体说来
- 对于尺寸为 m × n × p m \times n \times p m×n×p的特征矩阵,是通过 3 × 3 × p 3 \times 3 \times \ p 3×3× p的卷积核来生成概率分数以及相对Default Box的坐标偏移量,那么一共需要多少个这样的卷积核呢?对于每个Anchor会输出 k k k个Default Box,而每个Default Box会输出 c c c个类别的概率分数(包括背景的概率)以及 4 4 4个坐标偏移量,因此对于每个Anchor会需要 ( c + 4 ) k (c+4)k (c+4)k个卷积和,对于一个 m × n m\times n m×n的特征矩阵就会需要 ( c + 4 ) k m n (c+4)kmn (c+4)kmn个卷积核。
- 这里有一个值得注意的是,在SSD中每个Default Box输出 ( c + 4 ) (c+4) (c+4)个值,而在Faster RCNN中是对于每个类别都输出一个位置偏移量的估计,因此是 c × 4 c \times 4 c×4个值,因此Faster RCNN中输入到Predictor中的值要多一些。
- 当获得网路输出的概率分数以及坐标偏移量后,接下来就是进行损失计算了,损失计算公式如下: L ( x , c , l , g ) = 1 N ( L conf ( x , c ) i + α ′ L l o c ( x , l , g ) ) L(x, c, l, g)=\frac{1}{N}\left(L_{\text {conf }}(x, c)_{i}+\alpha^{\prime} L_{l o c}(x, l, g)\right) L(x,c,l,g)=N1(Lconf (x,c)i+α′Lloc(x,l,g))其中 N N N为匹配到正样本的个数,损失计算公式中前半部分为类别损失,后半部分为定位损失:
对于类别损失,具体计算公式为 L conf ( x , c ) = − ∑ i ∈ Pos N x i j p log ( c ^ i p ) − ∑ i ∈ N e g log ( c ^ i 0 ) where c ^ i p = exp ( c i p ) ∑ p exp ( c i p ) L_{\text {conf }}(x, c)=-\sum_{i \in \text { Pos }}^{N} x_{i j}^{p} \log \left(\hat{c}_{i}^{p}\right)-\sum_{i \in N e g} \log \left(\hat{c}_{i}^{0}\right) \quad \text { where } \quad \hat{c}_{i}^{p}=\frac{\exp \left(c_{i}^{p}\right)}{\sum_{p} \exp \left(c_{i}^{p}\right)} Lconf (x,c)=−i∈ Pos ∑Nxijplog(c^ip)−i∈Neg∑log(c^i0) where c^ip=∑pexp(cip)exp(cip)从类别损失的计算公式可以看出来,类别损失又可以分为两部分,前半部分为正样本类别损失的计算公式,所谓正样本就是与Ground Truth Box的IOU大于0.5的Default Box,第二部分为负样本类别损失的计算公式,所谓负样本就是与Ground Truth Box的IOU为0.1到0.5的Default Box,这些正负样本的损失其实就是Softmax交叉熵损失,其中
c ^ i p \hat{c}_{i}^{p} c^ip为预测第 i i i个Default Box对应的Ground Truth类别为 P P P的类别概率,通过公式可以看出其实就是一个经过Softmax处理后的一个概率;
x i j p = { 0 , 1 } x_{i j}^{p}=\{0,1\} xijp={ 0,1}表示第 i i i个Default Box匹配到的第 j j j个Ground Truth Box,而第 j j j个Ground Truth Box的类别又为 P P P时该值为1,否则为0,我理解为类似于艾弗森括号的作用;
c ^ i p \hat{c}_{i}^{p} c^ip为预测第 i i i个Default Box对应的Ground Truth类别为背景的概率;
对于定位损失,仅仅是针对正样本而言,和Faster RCNN的定位损失函数是一样的,具体公式如下: L l o c ( x , l , g ) = ∑ i ∈ Pos N ∑ m ∈ { c x , c y , w , h } x i j k smooth L 1 ( l i m − g ^ j m ) L_{l o c}(x, l, g)=\sum_{i \in \operatorname{Pos}}^{N} \sum_{m \in\{c x, c y, w, h\}} x_{i j}^{k} \operatorname{smooth}_{\mathrm{L} 1}\left(l_{i}^{m}-\hat{g}_{j}^{m}\right) Lloc(x,l,g)=i∈Pos∑Nm∈{ cx,cy,w,h}∑xijksmoothL1(lim−g^jm)其中 g ^ j c x = ( g j c x − d i c x ) / d i w \hat{g}_{j}^{c x}=\left(g_{j}^{c x}-d_{i}^{c x}\right) / d_{i}^{w} g^jcx=(gjcx−dicx)/diw g ^ j c y = ( g j c y − d i c y ) / d i h \hat{g}_{j}^{c y}=\left(g_{j}^{c y}-d_{i}^{c y}\right) / d_{i}^{h} g^jcy=(gjcy−dicy)/dih g ^ j w = log ( g j w d i w ) \hat{g}_{j}^{w}=\log \left(\frac{g_{j}^{w}}{d_{i}^{w}}\right) g^jw=log(diwgjw) g ^ j h = log ( g j h d i h ) \hat{g}_{j}^{h}=\log \left(\frac{g_{j}^{h}}{d_{i}^{h}}\right) g^jh=log(dihgjh) l i m l_{i}^{m} lim为预测对应第 i i i个正样本回归参数, g ^ j m \hat{g}_{j}^{m} g^jm为正样本 i i i匹配的第 j j j个Ground Truth Box的回归参数, g j m {g}_{j}^{m} gjm为第 j j j个Ground Truth Box的位置和长宽参数,Smooth L1的计算公式为: smooth L 1 ( x ) = { 0.5 x 2 if ∣ x ∣ < 1 ∣ x ∣ − 0.5 otherwise \operatorname{smooth}_{L_{1}}(x)=\left\{\begin{array}{ll} 0.5 x^{2} & \text { if }|x|<1 \\ |x|-0.5 & \text { otherwise } \end{array}\right. smoothL1(x)={ 0.5x2∣x∣−0.5 if ∣x∣<1 otherwise
3. YOLO系列
YOLO是我之前接触过的一个算法,当时还写过一篇博客关于如何调用Darknet版的YOLO v3的博客深度学习框架YOLOv3的C++调用,但是当时只是觉得好用却不懂原理,这里总结下。
3.1 YOLO v1
YOLO v1是和SSD同年在CVPR上发表的文章,当时的速度达到了45FPS,准确率达到了63.4mAP,速度和准确率都不及SSD,但是经过一步一步的发展, YOLO系列最终在性能上超过了SSD,这里先介绍下YOLO v1的基本方法
3.1.1 关键知识点——网络结构及特点
YOLO v1中实现目标检测的的主要思想如下:
- 将一幅图像分成 S × S S \times S S×S个网格,如果某个物体的中心落在这个网格中,则这个网格就负责预测这个物体;
- 每个网格要预测 B B B个Bounding Box(在YOLO v1中没有Faster RCNN和SSD中的Anchor的概念),每个Bounding Box包括4个位置参数和1个Confidence值,除此之外,每个网格还要预测 C C C个类别的分数。即每个网格输出的参数个数为 B × ( 4 + 1 ) + C B \times (4 +1) + C B×(4+1)+C,其中,位置参数包括 x , y , w , h x,y,w,h x,y,w,h这4个参数, x , y x,y x,y表示预测的Bounding Box的中心相对对应网格中心的偏移,而 w , h w,h w,h表示Bounding Box的长宽相对整幅图像长宽的比,Confidence这个参数在Faster RCNN和SSD中都是没有的,具体来说,Confidence的计算公式为: Pr ( Object ) ∗ IOU pred truth \operatorname{Pr}(\text { Object }) * \text { IOU }_{\text {pred }}^{\text {truth }} Pr( Object )∗ IOU pred truth 其中, Pr ( Object ) \operatorname{Pr}(\text { Object }) Pr( Object )指的是当Bounding Box中存在物体时,该值为1,不存在物体时,该值为0, IOU pred truth \text { IOU }_{\text {pred }}^{\text {truth }} IOU pred truth 指的是预测的Bounding Box与真实Bounding Box的交并比。在Test时,网格除了会输出每一个目标的Bounding Box的位置之外,还会输出每一个目标的检测概率,这个概率的计算公式为: Pr ( Class i ∣ Object ) ∗ Pr ( Object ) ∗ IOU pred truth = Pr ( Class i ) ∗ IOU pred truth \operatorname{Pr}\left(\text { Class }_{i} \mid \text { Object }\right) * \operatorname{Pr}(\text { Object }) * \text { IOU }_{\text {pred }}^{\text {truth }}=\operatorname{Pr}\left(\text { Class }_{i}\right) * \text { IOU }_{\text {pred }}^{\text {truth }} Pr( Class i∣ Object )∗Pr( Object )∗ IOU pred truth =Pr( Class i)∗ IOU pred truth 其中 Pr ( Class i ∣ Object ) \operatorname{Pr}\left(\text { Class }_{i} \mid \text { Object }\right) Pr( Class i∣ Object )为网格预测的 C C C个类别的分数,而 Pr ( Object ) ∗ IOU pred truth \operatorname{Pr}(\text { Object }) * \text { IOU }_{\text {pred }}^{\text {truth }} Pr( Object )∗ IOU pred truth 就是预测的Bounding Box的Confidence值,从化简公式可以看出,目标的检测概率既包含了该目标为某一个类别的概率,也包含了该目标与真实边界框的交并比。(因为是在Test时使用,这个目标的检测概率只是一个评测指标吗?这个需要后面自己去验证下)
YOLO v1网络的具体结构如下:
- 使用多层的卷积作为BackBone进行特征提取,最终输出 7 × 7 × 1024 7 \times 7 \times 1024 7×7×1024的特征矩阵;
- 将 7 × 7 × 1024 7 \times 7 \times 1024 7×7×1024的特征矩阵展平为向量,再连接一个全连接网络,输出长度为 4096 4096 4096维的特征向量;
- 将 4096 4096 4096维的特征向量再接一个全连接网络,输出长度为 1470 1470 1470维的特征向量,并最终将向量Reshape为 7 × 7 × 30 7 \times 7 \times 30 7×7×30的特征矩阵作为输出。
那么输出特征矩阵的尺寸为什么为 7 × 7 × 30 7 \times 7 \times 30 7×7×30呢?结合前文所说的YOLO v1进行目标检测的主要思想,我们对此进行分析,在实际的YOLO v1的搭建过程中,图像被划分为 S × S = 7 × 7 S \times S = 7 \times 7 S×S=7×7的网格,每个网格预测 B = 2 B = 2 B=2个Bounding Box以及 C = 20 C = 20 C=20个类别概率,即每个网格输出 B × ( 4 + 1 ) + C = 2 × ( 4 + 1 ) + 20 = 30 B \times (4 +1) + C = 2 \times (4 + 1) + 20 = 30 B×(4+1)+C=2×(4+1)+20=30个参数,因此输出的特征矩阵尺寸为 7 × 7 × 30 7 \times 7 \times 30 7×7×30,如下图所示,这是可以一一对应上的。
3.1.2 关键知识点——损失计算函数
在YOLO v1中,采用的是误差平方和的作为损失函数计算公式,具体公式如下:
如上图所示,损失计算函数主要包括三部分,下sunshi面分别介绍
- Bounding Box损失:对于Bounding Box的损失计算主要是对 ( x , y , w , h ) (x,y,w,h) (x,y,w,h)四个预测参数相对真实值的误差进行平方求和,其中表示位置的 x , y x,y x,y是直接计算,而表示宽高的 w , h w,h w,h是先开根号再计算,开根号的目的是为了保证大目标和小目标在偏移相同距离时,小目标的损失值要更大一些。
- Confidence损失:Confidence分为两部分,其中 ∑ i = 0 S 2 ∑ j = 0 B 1 i j obj ( C i − C ^ i ) 2 \sum_{i=0}^{S^{2}} \sum_{j=0}^{B} \mathbb{1}_{i j}^{\text {obj }}\left(C_{i}-\hat{C}_{i}\right)^{2} ∑i=0S2∑j=0B1ijobj (Ci−C^i)2为正样本损失,此时真实值 C ^ i \hat{C}_{i} C^i为1,而 λ noobj ∑ i = 0 S 2 ∑ j = 0 B 1 i j noobj ( C i − C ^ i ) 2 \lambda_{\text {noobj }} \sum_{i=0}^{S^{2}} \sum_{j=0}^{B} \mathbb{1}_{i j}^{\text {noobj }}\left(C_{i}-\hat{C}_{i}\right)^{2} λnoobj ∑i=0S2∑j=0B1ijnoobj (Ci−C^i)2为负样本损失,此时真实值 C ^ i \hat{C}_{i} C^i为0。
- Class损失:类别损失即预测与真实值的平方和损失。
3.1.3 关键知识点——YOLO v1存在的问题
- YOLO v1对群体性的小目标检测效果差,造成这个问题的主要原因是对每个网格只预测一种类型的目标以及两个Bounding Box,因此对于小目标的检测能力有限;
- 对于具备新比例的目标检测效果差;
- 网络主要的检测误差来源与定位不准确,造成这个问题的主要原因YOLO v1中是直接回归的目标的坐标信息,而不是像Faster RCNN和SSD那样回归到Anchor的参数;
3.2 YOLO v2
YOLO v2是发表于2017年的CVPR,由于其检测目标可以达到9000个,因此YOLO v2还有一个别名叫做YOLO 9000,从下面这张表格可以看出,YOLO v2在网络性能方面确实有了非常大的提升:
YOLO v2的论文一共分为三部分:Better、Faster、Stronger,下面主要介绍网络结构以及论文是如何各种方法提高网络性能的。
3.2.1 关键知识点——网络的结构及特点
论文中用于目标检测网络的BackBone网络Darknet-19,该网络一共有19层卷积层,网络结构如下:
其中
- 表格中每一个Convolutional层指代的都包括Conv2d-BatchNornalization-LeakyReLU这样三层结构,并且由于使用的Batch Normalization层,因此Conv2d中的卷积是没有偏置Bais的。
- 在Darknet-19的基础上,如下图所示:
YOLO v2再接了两个 1024 × 3 × 3 1024 \times 3 \times 3 1024×3×3的卷积层,然后在与来自前文提到的Passthrough Layer的底层特征信息进行Concate,再接一个 1024 × 3 × 3 1024 \times 3 \times 3 1024×3×3的卷积层,此时特征矩阵的大小为 13 × 13 × 1024 13 \times 13 \times 1024 13×13×1024,最后再接125维的 1 × 1 1 \times 1 1×1矩阵,最终输出的特征矩阵的大小即为 13 × 13 × 125 13 \times 13 \times 125 13×13×125.
4. 我们来解释下这个输出特征矩阵维度 13 × 13 × 125 13 \times 13 \times 125 13×13×125的意义,其中 13 × 13 13 \times 13 13×13可以理解为将图像划分为 13 × 13 13 \times 13 13×13的网格,每个网格输出5个Anchor Box,每个Anchor Box负责输出4个位置回归参数,1个置信度以及20个类别参数,因此每个网格一共需要输出 5 × ( 1 + 4 + 20 ) = 125 5 \times (1 + 4 + 20) = 125 5×(1+4+20)=125个参数。
3.2.1 关键知识点——提升mAP参数的方法
论文的Better章节中一共从这一下7个方面对进行了尝试提升网络的mAP参数:
- Batch Normalization,作者提出加入Batch Normalization层对于网络收敛有非常大的帮助,同时可以减少一系列正则化的操作(例如移除dropout层),加入Batch Normalization层后YOLO模型的mAP提升了2%。
- High Resolution Classifier,在YOLO v1中作者使用的是 224 × 224 224 \times 224 224×224的图像作为训练网络的输入,而在YOLO v2网络中使用的是 448 × 448 448 \times 448 448×448的图像作为网络输入,采用更高分辨率的分类器可以在模型的mAP参数上提升4%。
- Convolutional With Anchor Boxes,作者提出使用预测Bounding Box相对Anchor Box的Offset相对于直接学习Bounding Box的坐标要简化网络的学习难度,在没有使用Anchor Box时,模型的mAP为69.5,召回率为81%,而使用Anchor Box后,模型的mAP为69.2,召回率为88%,作者认为召回率的提高意味着模型有更大的提升空间。
- Dimension Clusters,这里指的是如何获得Anchor Box的预设尺寸,在Faster RCNN以及SSD中,Anchor Box的预设尺寸更多地像是工程经验获得的,而在YOLO v2中明确提出,在训练集上使用K-Means的方式来获得Anchor Box的预设尺寸。具体说来,步骤如下:
(1) 用来聚类的原始数据带有标注框的检测数据集,标注框的参数为 ( x j , y j , w j , h j ) , j ∈ { 1 , 2 , … , N } \left(x_{j}, y_{j}, w_{j}, h_{j}\right), j \in\{1,2, \ldots, N\} (xj,yj,wj,hj),j∈{ 1,2,…,N},因为和标注框位置无关,因此这里实际用到的参数只有 w j , h j w_j,h_j wj,hj;
(2) 首先给定 k k k个聚类中心点 ( W i , H i ) , i ∈ { 1 , 2 , … , k } \left(W_{i}, H_{i}\right), i \in\{1,2, \ldots, k\} (Wi,Hi),i∈{ 1,2,…,k},其中 k k k我们需要预设Anchor Box的尺寸的个数;
(3) 计算每个标注框和聚类中心点的距离 d = 1 − IOU d=1-\operatorname{IOU} d=1−IOU,这里计算的IOU指的是当每个标注框中心与Anchor Box中心重合的面积交并比,即 d = 1 − IOU [ ( x j , y j , w j , h j ) , ( x j , y j , W i , H i ) ] , j ∈ { 1 , 2 , … , N } , i ∈ { 1 , 2 , … , k } d=1-\operatorname{IOU}\left[\left(x_{j}, y_{j}, w_{j}, h_{j}\right),\left(x_{j}, y_{j}, W_{i}, H_{i}\right)\right], j \in\{1,2, \ldots, N\}, i \in\{1,2, \ldots, k\} d=1−IOU[(xj,yj,wj,hj),(xj,yj,Wi,Hi)],j∈{ 1,2,…,N},i∈{ 1,2,…,k}。将每个标注框分配给距离最近的聚类中心。
(4) 所有标注框分配完毕后,对每个簇的重新计算聚类中心 W i ′ = 1 N i ∑ w i , H i ′ = 1 N i ∑ h i W_{i}^{\prime}=\frac{1}{N_{i}} \sum w_{i}, H_{i}^{\prime}=\frac{1}{N_{i}} \sum h_{i} Wi′=Ni1∑wi,Hi′=Ni1∑hi,然后重复(3)(4)步骤。
如下图:论文中展示了在COCO数据集上VOC数据集上通过以上方法获得的不同的Achor Box的预设尺寸:
可以观察到,白色框与紫色框在不同尺度下长宽都有些许不同。通过聚类的方式获得的相对认为人为设定的方法更加充分地利用了数据集的信息,让网络回归更加轻松。
- Direct location prediction,在论文中,作者提出,如果直接使用Faster RCNN或者SSD中的参数回归方法,会导致在训练过程中,模型会出现不稳定的情况,而这中间导致不稳定的主要因素又是位置参数 x , y x,y x,y,我们知道,Faster RCNN和SSD中的位置参数方法如下: x = ( t x ∗ w a ) + x a x=\left(t_{x} * w_{a}\right)+x_{a} x=(tx∗wa)+xa y = ( t y ∗ h a ) + y a y=\left(t_{y} * h_{a}\right)+y_{a} y=(ty∗ha)+ya其中, t x , t y t_x,t_y tx,ty为网络预测的参数, x a , x b , w a , w b x_a,x_b,w_a,w_b xa,xb,wa,wb为Anchor Box的中心坐标以及宽高,作者提出,以上公式是没有收到限制的,因此网络预测的Bounding Box位置可能出现在图像中的任何位置,因此,在YOLO v2中,作者给出的位置 b x = σ ( t x ) + c x b_{x}=\sigma\left(t_{x}\right)+c_{x} bx=σ(tx)+cx b y = σ ( t y ) + c y b_{y}=\sigma\left(t_{y}\right)+c_{y} by=σ(ty)+cy b w = p w e t w b_{w}=p_{w} e^{t_{w}} bw=pwetw b h = p h e t h b_{h}=p_{h} e^{t_{h}} bh=pheth其中, t x , t y , t w , t h t_x,t_y,t_w,t_h tx,ty,tw,th为网络预测的参数, σ ( ) \sigma() σ()其实就是logistic激活函数,该函数的输出可以将网络预测的输出限制在一定范围内,论文指出,通过限制网络的输出以及通过聚类的方式获得Anchor Box使得网络mAP提升了5%。
- Fine-Grained Features,这一点指的是使用网络中更加低层的特征信息,因为低层的特征信息包含更多的细节,这对检测小目标是有帮助的,在YOLO v2中的操作方式是通过Passthrough Layer这样一种网络层将高层特征信息和底层特征信息融合的,具体说来,YOLO v2实际上就是将网络BackBone中 26 × 26 × 512 26 \times 26 \times 512 26×26×512的特征取出与最后输出的 13 × 13 × 1024 13 \times 13 \times 1024 13×13×1024的特征进行Concatenate操作,两个特征的维度不是不一样吗?对!PassThrough Layer的作用就是将 26 × 26 × 512 26 \times 26 \times 512 26×26×512的特征重新组合成维度为 13 × 13 × 2048 13 \times 13 \times 2048 13×13×2048的特征,具体操作方式如下图所示:
通过这种方式,YOLO v2的mAP提升了1%.
- Multi-Scale Training,即采用多尺度的训练方法,在训练过程中使用随机的输入图片大小替换掉固定的输入图片大小,具体来说,每迭代10个batch就将网络的输入图片大小进行随机选择,由于YOLO v2的网络缩放因子为32,因此输入图片的大小应该为32的整数倍,作者采用的是从 { 320 , 352 , … , 608 } \{320,352, \ldots, 608\} { 320,352,…,608}这一些列大小中进行随机选择的。
3.3 YOLO v3
YOLO V3发表于2018年的CVPR,其优势主要体现在如下这张图中
在极高的检测速度下仍然保证了很高的mAP-50的值,下面我们来简单看下网络的特点
3.3.1 关键知识点——网络结构及特点
YOLO v3中相对YOLO v2在网络的BackBone上又有了进一步的提升,YOLO v3使用的BackBone为Darknet-53,结构如下图所示:
其特点主要如下:
- Darknet-53和其他网络准确率以及速度的对比如下:
可以看到,相对于ResNet来说,网络在运行速度上有明显优势,在准确率上也有明显优势。
- 在Darknet-53中没有最大池化下采样层,而是通过卷基层代替了最大池化下采样层,最大池化下采样层能够增大感受野,让卷积看到更多的信息,但是它在降维的过程中丢失了一些信息,而步距等于2的卷积层相当于保留了相对更多的信息,因此效果会更好?(这是观点属于个人推测)
- 上图中Convolutional模块指的是Convolution层,Batch Normalization层,Leaky ReLU层的集合,结构如下图所示:
Residual模块加上它前两层的Convolutional模块,就是我们通常理解的残差模块,结构如下图所示:
- 在BackBone网络后接的预测特征层如下图所示,图片来源自YOLO v3网络结构分析:
从BackBone网络的后三层Residual模块开始就会输出分别接到不同尺度的预测特征层,以Predict One为例,Residual输出的特征矩阵会先输入至Convolutional Set模块,Convolutional Set模块入上右图所示,是由一系列Convolutional模块组成,通过Convolutional Set模块后,
一方面(图中向左的链路)经过Convolutional模块和 1 × 1 1\times1 1×1的卷积层输出,这里输出的特征的大小为 N × N × [ 3 ∗ ( 4 + 1 + 80 ) ] N \times N \times[3 *(4+1+80)] N×N×[3∗(4+1+80)],其中 N N N指输出特征层的维度,在Predict One中就是13,此外3指3个Anchor Box,4指位置相关的预测参数,1指Confidence,80指Coco数据集80个预测类别的分数,网路最后基于以上输出计算损失。
另一方面(图中向右的链路)经过Convolutional模块、UpSampling模块后,和BackBone中更低层的特征进行Concate,Concate后得到的特征矩阵,通过Convolutional Set后重复以上步骤,至此就完成了网络预测特征层的搭建,这里值得注意的是相对于YOLO v2的预测特征层网络来说,YOLO v3更加充分地利用了低层网络的信息,因此YOLO v3在小物体检测的能力上有了更大的提升。
3.3.2 关键知识点——损失计算函数
在进行损失计算函数之前,我们先提一下正负样本匹配的问题,也就是我们用哪些样本来计算损失,在YOLO v3的原文中提到, 对于正样本,只将与Ground Truth的IOU最大的预测Bounding Box作为正样本计算坐标、类别和置信度损失,其他与Ground Truth的IOU大于0.5的Bouding Box直接忽略掉,而与Ground Truth的IOU小于0.5的Bounding Box作为负样本,只计置信度损失。YOLO v3的算是计算函数与前两版有较大不同,在YOLO v1中我们介绍的使用的是误差平方损失,而在YOLO v3中主要使用的是二值交叉熵损失,具体如下:
- YOLO v3的损失函数主要由三部分组成,分别是置信度损失、类别损失、定位损失,如下所示: L ( o , c , O , C , l , g ) = λ 1 L conf ( o , c ) + λ 2 L cla ( O , C ) + λ L l o c ( l , g ) L(o, c, O, C, l, g)=\lambda_{1} L_{\text {conf }}(o, c)+\lambda_{2} L_{\text {cla }}(O, C)+\lambda L_{l o c}(l, g) L(o,c,O,C,l,g)=λ1Lconf (o,c)+λ2Lcla (O,C)+λLloc(l,g)其中 L conf ( o , c ) L_{\text {conf }}(o, c) Lconf (o,c)是置信读损失, L cla ( O , C ) L_{\text {cla }}(O, C) Lcla (O,C)是分类损失, L l o c ( l , g ) L_{l o c}(l, g) Lloc(l,g)是定位损失, λ 1 , λ 2 , λ 3 \lambda_{1}, \lambda_{2}, \lambda_{3} λ1,λ2,λ3为各项损失的平衡系数。
- 置信度损失采用的是二值交叉熵损失,公式如下所示: L conf ( o , c ) = − ∑ i ( o i ln ( c ^ i ) + ( 1 − o i ) ln ( 1 − c ^ i ) ) N L_{\text {conf }}(o, c)=-\frac{\sum_{i}\left(o_{i} \ln \left(\hat{c}_{i}\right)+\left(1-o_{i}\right) \ln \left(1-\hat{c}_{i}\right)\right)}{N} Lconf (o,c)=−N∑i(oiln(c^i)+(1−oi)ln(1−c^i)) c ^ i = Sigmoid ( c i ) \hat{c}_{i}=\operatorname{Sigmoid}\left(c_{i}\right) c^i=Sigmoid(ci)其中, o i ∈ [ 0 , 1 ] o_{i} \in[0,1] oi∈[0,1]表示预测目标边界框与真实目标边界框的IOU, c c c为预测值, c ^ \hat c c^为 c c c通过Sigmoid函数得到的预测置信度, N N N为正负样本个数。
- 类别损失采用的同样是二值交叉熵损失,公式如下: L c l a ( O , C ) = − ∑ i ∈ p o s j ∈ c l a ( O i j ln ( C ^ i j ) + ( 1 − O i j ) ln ( 1 − C ^ i j ) ) N p o s L_{c l a}(O, C)=-\frac{\sum_{i \in p o s j \in c l a}\left(O_{i j} \ln \left(\hat{C}_{i j}\right)+\left(1-O_{i j}\right) \ln \left(1-\hat{C}_{i j}\right)\right)}{N_{p o s}} Lcla(O,C)=−Npos∑i∈posj∈cla(Oijln(C^ij)+(1−Oij)ln(1−C^ij)) C ^ i j = Sigmoid ( C i j ) \hat{C}_{i j}=\operatorname{Sigmoid}\left(C_{i j}\right) C^ij=Sigmoid(Cij)其中 O i j ∈ { 0 , 1 } O_{i j} \in\{0,1\} Oij∈{ 0,1},表示预测目标边界框 i i i中是否存在第 j j j类目标, C i j C_{i j} Cij为预测值, C ^ i j \hat{C}_{i j} C^ij为 C i j C_{i j} Cij通过Sigmoid函数得到的目标概率,由于不是Softmax,因此输出的所有目标概率和并不为0, N pos N_{\text {pos }} Npos 为正样本的个数。
- 定位损失采用的仍然是误差平方和的计算公式: L l o c ( l , g ) = ∑ i ∈ p o s ∑ m ∈ { x , y , w , h } ( l ^ i m − g ^ i m ) 2 N p o s L_{l o c}(l, g)=\frac{\sum_{i \in p o s} \sum_{m \in\{x, y, w, h\}}\left(\hat{l}_{i}^{m}-\hat{g}_{i}^{m}\right)^{2}}{N_{p o s}} Lloc(l,g)=Npos∑i∈pos∑m∈{ x,y,w,h}(l^im−g^im)2 l ^ i x = Sigmoid ( t x ) , l ^ i y = Sigmoid ( t y ) \hat{l}_{i}^{x}=\operatorname{Sigmoid}\left(t_{x}\right), \quad \hat{l}_{i}^{y}=\operatorname{Sigmoid}\left(t_{y}\right) l^ix=Sigmoid(tx),l^iy=Sigmoid(ty) l ^ i w = t w , l ^ i h = t h \hat{l}_{i}^{w}=t_{w}, \quad \hat{l}_{i}^{h}=t_{h} l^iw=tw,l^ih=th g ^ i x = g i x − c i x , g ^ i y = g i y − c i y \hat{g}_{i}^{x}=g_{i}^{x}-c_{i}^{x}, \quad \hat{g}_{i}^{y}=g_{i}^{y}-c_{i}^{y} g^ix=gix−cix,g^iy=giy−ciy g ^ i w = ln ( g i w / p i w ) , g ^ i h = ln ( g i h / p i h ) \hat{g}_{i}^{w}=\ln \left(g_{i}^{w} / p_{i}^{w}\right), \quad \hat{g}_{i}^{h}=\ln \left(g_{i}^{h} / p_{i}^{h}\right) g^iw=ln(giw/piw),g^ih=ln(gih/pih)
3.4 YOLO v3 SPP
YOLO v3 SPP是在YOLO v3基础上使用了很多Trick是的网络的mAP进一步的得到了提高,这里同样做一个记录看看网络是如何锦上添花的
3.4.1 关键知识点——Mosaic图像增强
我们通常使用的图像增强算法指的是图像随机裁剪、图像随机翻转、图像色度和饱和度的随机调整,而Mosaic图像增强指的是将图像进行随机拼接再输入到网络中进行训练,Mosaic图像增强的好处是:
- 增加了数据的多样性;
- 增加了目标的个数;
- Batch Normalization能一次性统计多张图片的参数;
3.4.2 关键知识点——SPP模块
SPP模块的结构及位置如下图所示,就是将YOLO v3网络中的第一个预测特征中Convolutional Set拆开,在中间部分插入SPP结构:
这里的SPP模块和SPPNet中的SPP结构(Spatial Pyramid Pooling)不同,SPP模块结构也相对简单,第一个分支是直连的,第二个分支为大小为 5 × 5 5 \times 5 5×5的最大池化下采样层,第三个分支大小为 9 × 9 9 \times 9 9×9d的最大池化下采样层,第四个分之为大小 13 × 13 13 \times 13 13×13的最大池化下采样层 ,四个分支最后通过Concatenate组合在一起,实现了不同尺度的特征融合,对于网络的mAP值会有明显的提升。
3.4.3 关键知识点——CloU Loss
- IoU Loss:在原始的YOLO v3网络中使用的定位损失计算公式为误差平方和损失,而这里剔除的CloU损失是一种基于IoU的损失计算方法,如下图所示
其中绿色方框为真值,黑色方框为预测值,以上三种不同的结果如果计算误差平方和损失是一样的,这显然是不合理的,但是计算IoU就有明显不同,因为就有前辈提出IoU Loss,计算公式如下是: L I o U = − ln I o U L_{IoU} =-\ln{IoU} LIoU=−lnIoU通过这里例子我们就可以发现,IOU损失能够更好的反应重合程度并具有尺度不变形,但是缺点是不相交时损失为0.
- GIoU Loss:为了解决这个问题,在IoU Loss的基础上又有人提出Generalized IoU,即GIoU,计算公式如下: G I o U = I o U − A c − u A c G I o U={IoU}-\frac{A^{c}-u}{A^{c}} GIoU=IoU−AcAc−u L G I o U = 1 − G I o U L_{G I o U}=1-G I o U LGIoU=1−GIoU 0 ≤ L GIoU ≤ 2 0 \leq L_{\text {GIoU }} \leq 2 0≤LGIoU ≤2其中 A c A^c Ac为下图中蓝色框区域, u u u为下图中红色加上绿色区域
可以看出当两个边界框完全重合时,GIoU损失为0,当两个边界框相距无穷远时,GIoU损失为2,但是GIoU孙是同样拥有缺点,就是当预测边界框与真实边界框重合时,GIoU就退化为IoU。
- DIoU Loss:在GIoU的基础上又进一步优化出来了Distance IoU,即DIoU,计算公式如下: D I o U = IoU − ρ 2 ( b , b g t ) c 2 = IoU − d 2 c 2 D I oU=\operatorname{IoU}-\frac{\rho^{2}\left(b, b^{g t}\right)}{c^{2}}=\operatorname{IoU}-\frac{d^{2}}{c^{2}} DIoU=IoU−c2ρ2(b,bgt)=IoU−c2d2 L DIoU = 1 − DIoU L_{\text {DIoU }}=1-\text { DIoU } LDIoU =1− DIoU 0 ≤ L D I o U ≤ 2 0 \leq L_{D I o U} \leq 2 0≤LDIoU≤2其中 c c c为上图中蓝色方框对角线距离, d d d为上图中绿色方框与红色方框的中心点的距离,DIoU损失可以直接最小化两个边界框之间的距离,因此收敛速度更快。
- CIoU Loss:最后引出我们标题上的Complete IoU,即CIoU,计算公式如下: C I o U = IoU − ( ρ 2 ( b , b g t ) c 2 + α v ) C I o U=\operatorname{IoU}-\left(\frac{\rho^{2}\left(b, b^{g t}\right)}{c^{2}}+\alpha v\right) CIoU=IoU−(c2ρ2(b,bgt)+αv) v = 4 π 2 ( arctan w g t h g t − arctan w h ) 2 v=\frac{4}{\pi^{2}}\left(\arctan \frac{w^{g t}}{h^{g t}}-\arctan \frac{w}{h}\right)^{2} v=π24(arctanhgtwgt−arctanhw)2 α = v ( 1 − I o U ) + v \alpha=\frac{v}{(1-I o U)+v} α=(1−IoU)+vv L C I o U = 1 − C I o U L_{C I o U}=1-C I o U LCIoU=1−CIoU从公式可以看出来,相对DIoU,CIoU还多了一项 α v \alpha v αv,这一项考虑了边界框的长宽比,如下图展示了分别使用GIoU和CIoU的检测结果
4. FPN系列
FPN是Feature Pyramid Networks的简称,下图展现了FPN结构与其他网络结构的区别,如下图为四种不同的类金字塔网络结构:
- 图(a)为图像特征金字塔,即在不同尺度图像上生成特征层再进行目标检测,该结构的缺点就是计算量巨大。
- 图(b)为Faster RCNN的简化结构图,即通过BackBone网络提取特征,并在最终的特征图上进行预测,该结构对于小目标的检测效果较差。
- 图(c)的结构类似与SSD的网络结构,该网络同样会使用BackBone进行特征提取,但是会在BackBone的不同特征层上进行预测。
- 图(d)就是本节要介绍的的FPN结构,该结构的特征就是对BackBone网络中的不同特征层进行融合再进行预测。
实验证明FPN结构能有效提高目标检测精度,除此之外,据我了解,Feature Pyramid结构其实除了在目标检测领域,在很多其他领域也能够起到提升性能的作用。
4.1 FPN
首先提出该结构的论文《Feature Pyramid Networks for Object Detection》发表于2016年的CVPR,在Fast RCNN网络基础上使用了FPN结构后,在cocoAP上提升2.3个点,在pascalAP上提升3.8个点。
4.1.1 关键知识点——网络结构与特点
FPN网络中的细节如下,图片来源1.1.2 FPN结构详解:
如上图所示,
- 网络的BackBone采用的是ResNet50;
- 在上图右侧FPNj结构中,所有卷基层在进行融合之前都会先通过一个 1 × 1 1 \times 1 1×1的卷积层处理,目的就是为了使得不同特征层的Channel相同,然后高层的特征图需要进行2倍的上采样,目的是与低层的特征图达到同尺度然后进行融合,而融合方法就是对应通道的特征进行相加。
- 网络运行是首先是通过RPN网络在P2-P6特征层上运行获得Proposal,然后在通过Fast RCNN网络获得最终的预测结果。对于不同的预测特征层,RPN和Fast RCNN的权重共享,也就是说使用同一个RPN网络和Fast RCNN网络在不同的特征层上获得预测结果。
- 在原始的Faster RCNN网络中,是在相同的特征层上生成不同尺寸不同比例的Anchor,而在FPN网络中,在不同的特征层上对不同尺度的目标进行预测,换句话说,就是不同的特征层预测不同面积大小的物体,具体说来,一共有五种尺寸的Anchor分别是 { 3 2 2 , 6 4 2 , 12 8 2 , 25 6 2 , 51 2 2 } \left\{32^{2}, 64^{2}, 128^{2}, 256^{2}, 512^{2}\right\} { 322,642,1282,2562,5122}分别对应 { P 2 , P 3 , P 4 , P 5 , P 6 } \left\{P_{2}, P_{3}, P_{4}, P_{5}, P_{6}\right\} { P2,P3,P4,P5,P6},每个尺寸都有 { 1 : 2 , 1 : 1 , 2 : 1 } \{1: 2,1: 1,2: 1\} { 1:2,1:1,2:1}三种比例,因此在整个FPN网络中一种有15中不同的Anchor。
4.2 RetinaNet
RetinaNet的原论文为《Focal Loss for Dense Object Detection》,发表于2017年的CVPR上,其代表One-Stage网络首次超越Two-Stage网络,RetinaNet就是在FPN网络上的进一步升级。
4.2.1 关键知识点——网络结构及特点
RetinaNet的网络结构如下:
与FPN网络中不同之处主要有如下几点
- FPN结构中减少了P2层,由于P2层输出的特征层的维度较大,因此论文认为P2层占用了较大的计算资源,因此论文去掉了P2层,最大维度的特征层为P3层
- P6层在FPN网络中是通过 1 × 1 1 \times 1 1×1的最大池化下采样层获得的,而在RetinaNet网络中是通过卷积层获得;
- RetinaNet中增加了P7层用于检测更大的目标。
- 在FPN网络中同一种尺度下三种比例的的Anchar,而在Retina网络中,一共有三种尺度对应三种比例,在ReitinaNet网络中一共有 32 { 2 0 , 2 1 3 , 2 2 3 } 32\left\{2^{0}, \quad 2^{\frac{1}{3}}, \quad 2^{\frac{2}{3}}\right\} 32{ 20,231,232}, 64 { 2 0 , 2 1 3 , 2 2 3 } 64\left\{2^{0}, 2^{\frac{1}{3}}, 2^{\frac{2}{3}}\right\} 64{ 20,231,232}, 128 { 2 0 , 2 1 3 , 2 2 3 } 128\left\{2^{0}, 2^{\frac{1}{3}}, 2^{\frac{2}{3}}\right\} 128{ 20,231,232}, 256 { 2 0 , 2 1 3 , 2 2 3 } 256\left\{2^{0}, \quad 2^{\frac{1}{3}}, \quad 2^{\frac{2}{3}}\right\} 256{ 20,231,232}, 512 { 2 0 , 2 1 3 , 2 2 3 } 512\left\{2^{0}, \quad 2^{\frac{1}{3}}, \quad 2^{\frac{2}{3}}\right\} 512{ 20,231,232}共15中尺深度,每个尺寸同样对应 { 1 : 2 , 1 : 1 , 2 : 1 } \{1: 2,1: 1,2: 1\} { 1:2,1:1,2:1}三种比例。
对于每个特征层,都会对应同一个预测器,注意不同层特征层之间的预测器权值共享,预测器的结构如下图所示:
- 预测器中一共有两个分之,一个负责检测类别,每个Anchor预测 K K K个物体类别,一个负责检测边界框位置,每个Anchor预测 4 4 4个和位置相关的参数。
4.2.2 关键知识点——Focal Loss
在RetinaNet中除了网路结构外,最终的一个部分就是Focal Loss的计算了,这一点在标题中就已经体现出来了,Focal Loss的提出主要是为了解决One Stage网络中经常遇到的正负样本不匹配的问题,对于普通的交叉熵损失计算公式如下: C E ( p , y ) = { − log ( p ) if y = 1 − log ( 1 − p ) otherwise. \mathrm{CE}(p, y)=\left\{\begin{array}{ll} -\log (p) & \text { if } y=1 \\ -\log (1-p) & \text { otherwise. } \end{array}\right. CE(p,y)={ −log(p)−log(1−p) if y=1 otherwise. 为了表示简单,我们可以令 p t = { p if y = 1 1 − p otherwise p_{\mathrm{t}}=\left\{\begin{array}{ll} p & \text { if } y=1 \\ 1-p & \text { otherwise } \end{array}\right. pt={ p1−p if y=1 otherwise 因此二值交叉熵损失可以重写为 C E ( p , y ) = C E ( p t ) = − log ( p t ) \mathrm{CE}(p, y)=\mathrm{CE}\left(p_{\mathrm{t}}\right)=-\log \left(p_{\mathrm{t}}\right) CE(p,y)=CE(pt)=−log(pt)所谓Focal Loss就是引入一个 α \alpha α因子,对于正样本采用的系数为 α \alpha α,对于负样本采用的是 1 − α 1-\alpha 1−α,我们进一步重写为 C E ( p t ) = − α t log ( p t ) \mathrm{CE}\left(p_{\mathrm{t}}\right)=-\alpha_{\mathrm{t}} \log \left(p_{\mathrm{t}}\right) CE(pt)=−αtlog(pt)进一步地,我们引入一个新的因子 ( 1 − p t ) γ \left(1-p_{\mathrm{t}}\right)^{\gamma} (1−pt)γ,那么最终Focal Loss的计算公式为: F L ( p t ) = − ( 1 − p t ) γ log ( p t ) \mathrm{FL}\left(p_{\mathrm{t}}\right)=-\left(1-p_{\mathrm{t}}\right)^{\gamma} \log \left(p_{\mathrm{t}}\right) FL(pt)=−(1−pt)γlog(pt)在上文中, a l p h a alpha alpha是一个超参数,并不能区分哪些是适合用来训练的样本,而 ( 1 − p t ) γ \left(1-p_{\mathrm{t}}\right)^{\gamma} (1−pt)γ这个因子能够降低容易区分的样本的损失贡献,而增强困难区分的样本的损失。如下图所示:从上图可以看出来,当 γ \gamma γ不等于零时,概率为0.6-1的这些高概率类别获得的损失相应减小,这样网络就可以将更多的资源应用到区分难以区分的类别上。以上大概就是Focal Loss的基本思想。
如上就完成了计算机网络中目标检测网络的流水账式的学习,再一次感谢Up主霹雳吧啦Wz,以上论文并没有时间去仔细阅读论文,仅仅是根据霹雳吧啦Wz的学习视频过了一遍,以后有用到的时候再去仔细研究。如果文章中有理解不对之处还请大家多多指出。