您现在的位置是:首页 >技术交流 >人工智能学习07--pytorch21--目标检测:YOLO系列理论合集(YOLOv1~v3)网站首页技术交流
人工智能学习07--pytorch21--目标检测:YOLO系列理论合集(YOLOv1~v3)
如果直接看yolov3论文的话,会发现有好多知识点没见过,所以跟着视频从头学一下。
学习up主霹雳吧啦Wz大佬的学习方法:
想学某个网络的代码时:到网上搜这个网络的讲解 → 对这个网络大概有了印象 → 读论文原文(
很多细节都要依照原论文来实现,自己看原论文十分重要,发现更多原来没有发现的知识点)
→ 读代码 (
在github上找大牛实现了的源代码,挑选自己喜欢的框架、作者经常更新的代码仓库、标star比较多的,来克隆代码 进行学习
)
克隆第一步:根据作者的readme将作者代码跑通;
克隆第二步:分析作者代码(可以先看:
①网络搭建部分,结合原论文比较好理解;
②数据预处理、损失计算(损失函数);
看完以上基本上就掌握了网络的核心知识点
)
看代码时需要结合原论文进行参考。有时在读原论文时,有些地方不太好理解,但如果结合别人的代码,也可以更好地理解。
yolo v1
慢于SSD,但是比Faster RCNN快(精度比Faster RCNN低)
一般S取7(每行每列分成7等份)
如果某个object的中心落在这个网格,那么这个网格就负责预测这个object。
黄框就负责预测狗这个目标
- B一般取2,S一般取7。
confidence:在YOLO系列中独有的参数。
数据集PASCAL VOC,共20个类别 C=20,
grid cell是7*7大小的 S=7,
Bounding box取B=2,
预测的参数个数 7 * 7 * 30:
30 = 2个框 * 每个框5个参数(4个位置+1个confidence) +20类
通过YOLOV1网络传播,最终得到7 * 7,深度为30的矩阵。
对于沿着深度方向的每一行:
2组bounding box 的参数,该网格预测的c个类别分数。 - 每个bounding box由5个值组成:x,y(预测框中心坐标,数值在0 ~ 1之间(相对于grid cell而言)),w,h(数值在0 ~ 1之间,也是相对值,是相对于整个图像而言的),confidence。
相对值比实际值,相对值更方便运算(0 ~ 1之间的数字对训练有好处,收敛快,且不容易出现极端值)。 - confidence 预测bounding box与真实bounding box之间的交并比。
与Faster RCNN和SSD预测的目标概率是不一样的。
网络结构:
- 7 * 7卷积层,步距为2,通过一个maxpooling最大池化下采样(步距为2)
- 3 * 3卷积层,步距1(没有标s,那么步距就是默认为1),通过一个maxpooling最大池化下采样
- 通过1 * 1的卷积层、3 * 3的卷积层、1 * 1的卷积层、3 * 3的卷积层、……
- 将1 * 1的卷积层、3 * 3的卷积层重复四遍,……
- 将……重复两遍,再……
- 再通过两个3 * 3的卷积层,得到 7* 7,深度为1024的特征矩阵。
- Conn.Layer ①transpose不一定有,主要根据tensor通道排列顺序决定的。②展平处理。③通过节点个数为4096的全连接层连接。
→得到一个4096的向量。 - Conn.Layer ①通过一个节点个数为1470(7x7x30)的全连接层②通过reshape处理,得到7 * 7,深度为30的特征矩阵。
损失函数
三部分计算。使用误差平方和求解。
对宽和高开根号处理:
绿色:真实目标边界框。蓝色:预测得到的目标边界框。
假设对于大目标和小目标,预测边界框相对真实边界框都有偏移(假设一样)。
可以发现对小目标的预测结果很差,而对大目标的预测结果还行。(不同尺度IOU不一样)所以不能用真实宽度-预测宽度。
(
虽然是xy的偏移,但这种大小box不同的偏移差异却是wh带来的。
)
偏移相同的距离,小目标的差值要更大一些才行,这样会关注更多的小目标定位损失。
(
正样本置信度损失的回归值,论文里好像是IoU?
)
存在问题
对群体性的小目标检测很差。
因为在yolov1的思想中,对于每个cell,只预测两个bounding box,而且这两个bounding box属于同一类别。
主要错误原因来自于定位不准确。直接预测坐标信息,而不是像FasterRCNN或SSD那样,预测相对anchor的回归参数(但是从yolov2开始就改成这样预测相对anchor的回归参数了。)
yolo v2
七种尝试及其所带来的效果
Batch Normalization
Yolo v1没有使用BN层,而Yolo v2在每个卷积层后面都加上了BN层。
添加BN层后,对训练和收敛都有很大帮助,同时也减少了一系列的正则化处理。
对模型起到正则化作用。
可以移除掉dropout操作(减轻过拟合)。
High Resolution Classifier
采用更高分辨率的分类器。
Yolo v1 224x224的输入,Yolo v2 448x448。
Convolutional With Anchor Boxes
使用基于Anchor的目标边界框预测。
Yolo v1预测目标边界框:直接预测目标高度宽度以及中心坐标。定位效果差。
Yolo v2采用基于Anchor偏移的预测效果相比直接预测坐标,可以简化目标边界框预测问题,也可以使网络更加容易去学习和收敛。
使用后mAP有微小下降,但是召回率(预测正确的样本在总样本占的比例)大大提升(模型拥有更多提升空间)。
Dimension Clusters
anchor的聚类
使用Faster RCNN和SSD时作者没有明确给出为什么要采用作者给定的那些预设Anchor(Faster RCNN)或者defult box(SSD)。SSD中有给公式,但是用处不大。反正都没说怎么得到那个尺寸的,只说是根据工程经验确定的。
拿到新的网络该如何选择预设anchor或者default box?
Yolo v2采用k-means聚类方法获得anchor,称为prior。(Yolo v3中所有的priors也是通过聚类的方法获得的)
Direct location prediction
目标边界框预测(直接预测边界框中心坐标)
大部分不稳定因素在于预测边界框的中心坐标(x,y)。
论文中给出了Faster RCNN边界框预测公式:由于公式没有受到限制,所以基于anchor预测出的目标可能会出现在图片的任何一个地方。
yolo对图片划分了区域,而Faster RCNN中并没有。所以如果用Faster RCNN的预测方法会有很大问题。
yolov2对此改进:
如果将anchor设置在grid cell 的左上角,坐标(cx,cy)。预测的bounding box 的prior的宽度高度为pw、ph。
tx:关于anchor的偏移量,通过一个函数对它进行限制:
σ:logistic activation → sigmoid函数(将输入映射到0~1之间)。
如此一来,预测框的中心点只会出现在grid cell之间。
区域外的目标就不去管了。
由于限制了坐标信息,所以网络更容易进行学习,也更加稳定。
Fine-Grained Features
预测特征图结合一些更底层的信息。
**底层信息包含更多的图像细节,而这些细节就是在检测小目标时所需要的。**直接用高层的信息检测小目标的结果很差。
结合方式:通过passthrough layer来实现。
大佬太牛了:
passthrough layer如何将两个大小不同的特征图进行融合?举例:
对4x4的特征矩阵进行分割,分割成4个小方格(相同的位置用相同的颜色标注)。将同样颜色的数值放在同一个特征图中。
1个4x4的特征图 → 4个2x2的特征图,深度x4。
融合过程:
1*1卷积核可以用来缩减通道数减少参数量。
通过1x1的卷积层后,特征图的深度变为64。
26x26x512 → 26x26x64
通过passthrough layer:26x26x64 → 13(26➗2)x13x256(64x4)
将两个矩阵(13x13x256、13x13x1024)在深度方向进行拼接(在深度上相加) → 13x13x1280。
Multi-Scale Training
多尺度训练
在训练过程中,替换掉固定的输入尺寸(每个网络输入图像的尺寸都是固定的,要么是416x416,要么是480x480,要么是544
x544)
为了提升yolov2的鲁棒性,作者把图片缩放到不同的尺度来训练模型。
如何调整图像尺寸:每经过10个batch,就对输入尺寸进行随机选择。由于yolov2网络的缩放因子是32(32:
)所以采用的一系列的输入网络的尺寸都是32的整数倍。从这些中随机选取几个尺寸作为输入尺寸。
(
弹幕:yolov2网络是全卷积结构,输入大小不受限,不会改变网络结构
)
Backbone骨干网络 Darknet-19
Darknet-19:19个卷积层
表里224,实际输入时采用448x448作为高分辨率分类器进行训练。此处224x224是与之前别的网络进行对比。
(
top1:输出的所有类别准确率排序后第一名是正确的概率;
top5:输出的所有类别准确率排序后前五名包含正确类别的概率(5个有1个就算数);
top1指取最大概率模型预测判断正确才算正确,top5指概率前五只要有判断正确的就视为正确
)
框架
对于检测网络,移除了最后一个卷积层。保留了卷积核大小3x3,个数1024的卷积层(下图蓝色框上面那个)。
对应这个:
在后面添加3个3x3的卷积层,卷积核个数都为1024的卷积层。在后面接上一个1x1的卷积层,它输出的个数就是所需检测的目标参数。
对应VOC数据集,预测5个bounding box,每个bounding box会有5个参数(同yolov1中,偏移信息:xywh,+confidence(预测目标与真实目标的iou值))。由于采用的是VOC数据集,所以要预测20个类别对于每个bounding box而言的分数,所以最后一个卷积层采用125个卷积核。
x 5(采用5个anchor)
5(5个参数)+20(每个anchor分别对应20个类别的概率分数)=25
5 x 25 = 125
(
之前是直接预测,这里是基于anchor的偏移预测
)
yolo v3
https://blog.csdn.net/qq_37541097/article/details/81214953?ops_request_misc=&request_id=117f5f0e641e4e41a7963ed4a8c1e0a7&biz_id=&utm_medium=distribute.pc_search_result.none-task-blog-2blogkoosearch~default-1-81214953-null-null.268v1control&utm_term=yolov3&spm=1018.2226.3001.4450
主要是整合了当前比较主流的网络的优点
backbone的修改
FPS 每秒钟推理多少张。
Top1:最大概率的就是预测目标
Top5:预测概率前5里面有正确的标签
框:残差结构。
为什么DarkNet-53比ResNet一些深层网络效果更好?
都是通过堆叠一系列残差结构来得到最终网络。但是DarkNet-53中没有最大池化层,所有的下采样几乎都是通过卷积层实现。
如:步距为2,通过之后所有的高和宽都缩减为原来的一半。
通过卷积层替换原来的最大池化下采样 → 检测效果提升。
yolov3在3个预测特征层上进行预测(使用3种尺度)
yolo中称预设的目标边界框:bounding box prior,与之前讲的anchor、SSD的default box性质都差不多。
N:预测特征层大小,13或者26或者52.
3:每个特征层上预测3个尺度
每种尺度上预测4+1+80个参数
80:COCO数据集80个类别
4:对于每个anchor而言,预测4个偏移参数
1:yolo中独有的confidence score
目标边界框的预测
采用与yolov2中一样的机制,与ssd与faster rcnn中的不一样。
ssd与faster rcnn中的:
网络预测的关于目标中心点的回归参数是相对于anchor而言的。
在yolov3中:关于目标中心点的回归参数是相对于当前cell左上角点的。
最后通过一个1 * 1的卷积层在最终的预测特征层上预测所有的相关信息。
yolov3:3个预测特征层,每个特征曾采用了3个不同的模板。
假设上面这个图是针对某一预测特征层而言,1 * 1的卷积层滑动到红框这个窗口时,针对每一个anchor模板都会预测4个回归参数(tx ty tw th)+1个objectness参数+对应每个类别的分数score。
虚线框:anchor。pw:anchor宽度。ph:anchor高度。
蓝框:网络预测的最终位置以及大小。
计算得到的bx和by范围都是在grid cell之间的(一个grid cell边长是1),σ函数将范围限制在0~1.
正负样本匹配
原文中,针对每一个ground truth,都会分配一个bounding box prior(正样本)。
→ 一个图片中有几个gt目标就有几个正样本。
分配原则:将与gt重合程度最大的bounding box prior作为正样本。
当bounding box与gt重合超过了某一个阈值,但是重合程度不是最大,则直接丢弃这个预测结果。
如果bounding box prior没有被分配给某个gt(该bounding box prior不是正样本),则没有定位损失,也没有类别损失,则只有confidence score(objectness)。
按照论文中写的这样去分配正样本,则发现正样本数量特别少。对照U版(ultralytics公司?)YOLOV3网络看一下源码发现:
如果左边这三个IOU都大于阈值,是否是把GT同时分配给三个anchor?
是的,则在当前grid cell中对应的三个anchor模板都被是做正样本。正因如此,才可以扩充正样本的数量。
损失的计算
yolov3论文中没有给出具体公式
-
置信度损失
针对预测得到的confidence score
针对每个bounding box所预测的objectness使用的是逻辑回归。一般使用的逻辑回归就是二值交叉熵损失(binary cross entropy),yolov3源码也是使用的这个。
原文中:oi取0或者1. -
类别损失
也是用的二值交叉熵损失
对于这个Binary Cross Entropy公式,每个人上网查到的可能都不一样。这里up主通过实践检验来检验公式是否正确。
pytorch官方的:
自己定义的:
运行后结果:
注意:
-
定位损失
gx gy gw gh将gt映射在grid网格中得到的
gx hat:用gx减去对应grid cell左上角的x坐标cx后得到
gwhat ghhat:gw gh是真实的宽度和高度,要反向计算它们所对应的回归参数:除以pw ph,两边取ln
了解即可,后面的yolov3 spp和yolov4v5采用的定位损失都不是这种(是CIOU loss)。