本文yolov1有具体的论文精读,后面v2-v4只是关键技术记录。v5参考我的其他文章(文章比较长,建议直接去目录翻感兴趣的看,我的其他文章还有代码详解)
yolo.py:yolo.py代码精读_epic_Lin的博客-CSDN博客
train.py:https://blog.csdn.net/epic_Lin/article/details/121270638
yolov4-v5知识点:yolov4,yolov5(学习记录)_epic_Lin的博客-CSDN博客
总讲:yolo系列学习(入门经过)_epic_Lin的博客-CSDN博客
ps:下面把Yolov1论文主要部分都翻译了一下,重点词语用英文标出来,确保原文词汇准确传达
目前的检测系统通过重新使用(reprupose)分类器来执行形式检测。为了检测一个目标,这些系统为该目标取一个分类器,并在test image的不同locations 和scales上来评估它。像可变形部件模型(DPM)这样的系统使用滑动窗口的方法,分类器在整个图像上均匀间隔的位置运行。
更近一些的方法像R-CNN用区域建议方法(region proposal methods),首先在图像中生成潜在的边界框,然后在这些建议的boxes上运行分类器。分类后,利用后处理对边界框进行细化(refine),消除重复检测,并基于场景中其他对象对边界框重新打分(rescore)。这些复杂的操作(pipelines)是缓慢和难以优化的,因为每个单独的组件(individual component)必须单独训练
我们将目标检测重构为一个单一的回归问题,直接从图像像素到边界框坐标和类别概率。
YOLO非常简单:一个卷及网络可以同时预测多个边界框和这些边界框的分类概率。YOLO对完整的图像进行训练,并直接优化检测性能。与传统的目标检测方法相比,这种统一模型有几个优点。
首先YOLO的速度非常快。由于帧检测是个回归问题,所以不需要复杂的pipeline。我们只需在测试时间对新图像运行神经网络来预测检测结果。
第二,YOLO在预测的时候推理整张图像。与基于滑动窗口(sliding window)和区域建议的技术(region proposal-based techniques)不同,YOLO在训练和测试期间看到整个图像,因此它隐式地编码关于类及其外观的上下文信息。(看整张图片不是很慢??是因为YOLO第一次用回归??回归指什么??其他技术不是用这种训练-推理回归的技术吗,YOLO的优势在哪??YOLO应该也用了类似的推荐框技术,这种技术和上面滑动窗口和区域建议技术有什么区别??)顶级的检测算法Fast R-CNN因为没法看到更大的背景,所以将图像中的背景补丁(background patches)误认为物体。于Fast R-CNN相比,YOLO的背景错误数量不到一半
第三,YOLO学习对象的可泛化表示。当在自然图像上进行训练并在artwork上进行测试时,YOLO 的表现远远超过顶级的检测方法,如DPM和R-CNN。
YOLO在精度上仍落后于最先进的检测系统。虽然它可以在图像中款速识别物体,但它很难精确定位一些小的物体。我们在实验中进一步研究了这些权衡(tradeoffs)。
我们将目标检测的各个部分统一为一个单一的神经网络。了我们的网络使用整个图像的特征来预测每个边界框。它还能同时预测一个图像中所有的边界框。这意味着我们的网络对完整的图像和图像中的所有物体进行全局推理。YOLO设计实现了端到端训练和实时速度,同时保持了较高的平均精度。
本系统将输入图像划分为s*s个网格。如果一个物体的中心落在一个网络单元格中,该网络单元格负责检测该物体。
每个网格单元预测B个边界框和这些边界框的置信度。这些置信度得分反映了模型对框中包含物体的置信程度,以及推测出的框的精度。通常,我们将置信度定义为。如果在单元格中没有对象,则置信度得分应为零。否则,我们希望置信度等于推测的框和标签之间的intersection over union(IOU)
每个边界框包含5个预测:x,y,w,h,conf.
每个单元格预测C个条件类(conditional class probabilities)概率,这些概率不取决于包含对象的网格单元格。每个单元格只负责一个类的检测(we only predict one set of class probabilities per grid cell),而不管boxes的数量B。
在测试时,我们将条件类概率(conditional class probabilities)和单个框的置信度预测相乘
就得到了每个box的特定类别的置信度得分。这些分数编码了该类别出现在方框中的概率,以及预测的方框与对象的匹配程度
我们网络架构的灵感来自于GoogLeNet模型,我们的网络有24个卷积层,然后是两层全连接层我们不使用GoogLeNet采用的初始模型(inception modules),而是简单地使用1×1还原层(reduction layers),然后是3×3卷积层。
我们还训练了一个快速版本的YOLO,旨在推动快速目标检测的边界。FastYOLO使用的神经网络的卷积层更少(9而不是24),并且在这些层中有更少的滤波器。除了网络的大小之外,YOLO和FastYOLO之间的所有训练和测试参数都是相同的。我们的网络的最终输出是预测的7×7×30张量。
我们在ImageNet1000类竞赛数据集上预训练卷积层。对于预训练,我们使用图3中的前20个卷积层,然后是一个平均池化层和一个完全连接的层。我们使用Darknet框架进行训练和推理。
然后我们改变模型来进行检测(detection)。Ren etal. 展示了在预训练网络中同时增加卷积层和全连接层可以优化性能。根据他们的例子,我们添加了四个卷积层和两个具有随机初始化权值的完全连接层。检测通常需要细粒度的视觉信息,因此我们将网络的输入分辨率从224×224提高到448×448。
我们的最后一层预测了类概率和边界框坐标。我们通过图像的宽度和高度将边界框的宽度和高度归一化,使它们落在0到1之间。我们将边界框x和y坐标参数化为特定网格单元格位置的偏移量,因此它们也被限定在0和1之间。所以它们的范围也在0和1之间。我们对最后一层使用线性激活函数,所有其他层使用以下泄漏校流线性激活(leaky rectified linear activation):
我们优化了模型输出的平方和误差(sum-squared error)。我们使用平方和误差是因为它很容易优化,但它并不完全符合我们的最大化平均精度(maximizing average precision)的目标。它对定位误差和分类误差同等权重,这可能不理想。此外,在每个图像中,许多网格单元格不包含任何对象。这将这些单元格的“置信度”分数推向零,通常超过了那些确实包含物体的单元格的梯度。 这可能会导致模型的不稳定,导致训练在早期出现分歧。
为了解决这一点,我们增加了对边界框坐标预测的损失,并减少了对不包含对象的框的置信度预测的损失。我们用了两个参数,来实现。我们设置
平方和误差(sum-squared error)对大框和小框是等价的。我们的误差度量应该反映出小偏差在大框中的影响较小,在小框中的影响较大。为了部分解决这个问题,我们预测了边界框宽度和高度的平方根,而不是直接预测了宽度和高度。 (平方和误差到底是什么??平方和误差和IOU什么关系??)
YOLO预测每个网格单元格有多个边界框。在训练时,我们只希望一个边界框预测器负责一个对象。(边界框预测期用什么方式存在??)我们分配了一个预测器来“负责”预测一个与标签的IOU最大的对象。这导致了边界框预测器之间的专门化。每个预测器都在预测特定大小、长宽比或对象类别方面做得更好,从而提高整体回忆率(overall recall)。
在训练过程中,我们优化了以下多阶段(multi-part)损失函数:
表示对象是否出现在单元格i中,表示单元格i中的第j个边界框预测器“负责”该预测。
ps:
第一行是负责检测的框的中心点误差,第二行是负责检测的框的w,h误差,第三行是置信度误差,第四行是不负责检测的框的置信度误差,第五行是负责检测的单元格的类概率误差
请注意,损失函数只有在该网格单元中存在一个对象时才会惩罚分类错误(因此在前面讨论条件类概率)。只有当预测器对truth“负责”(即该网格单元中任何预测器的IOU最高)时,它也会惩罚边界框坐标错误。
我们对PASCAL VOC2007和2012的训练和验证数据集训练了大约135个epoch。在2012进行测试时,我们还包括了VOC2007测试数据(test data)进行训练。训练中使用的batch size为64,动量为0.9,衰减为0.0005。
我们的学习率计划如下:在最初的阶段,我们慢慢地将学习率从 提高到。如果我们从一个较高的学习速率开始,我们的模型通常会由于不稳定的梯度而发散。我们继续用训练75个epoch,然后个训练30个epoch,最后个训练30个epoch。
为了避免过拟合,我们使用了dropout和广泛的数据增强(extensive data augmentation)。在第一个连接层之后,rate=.5的dropout层防止了层之间的共同自适应(co-adaptation between layers)。对于数据增强,我们引入了高达原始图像大小的20%的随机缩放和平移(random scaling and translations)。我们还随机调整了图像的曝光和饱和度高达1.5倍,在HSV颜色空间中。
就像在训练中一样,预测一个测试图像的检测只需要一个网络评估。 在PASCAL VOC上,网络在每幅图像上预测98个边界框和每个框的类概率。YOLO在测试时非常快,因为它不需要基于分类器的方法,只需要一个网络评估。
网格设计(grid design)加强了边界框预测中的空间多样性。通常很清楚一个对象属于哪个网格单元格,并且网络只预测每个对象的一个框。然而,一些靠近多个单元边界的大型物体会被多个单元很好地定位。非最大抑制可以用来修复这些多重检测(所以这些大型物体中心点会落在哪里,为什么会被多个单元格定位??怎么实现的定位??)。虽然在R-CNN或DPM中对性能没啥大用,但非最大抑制在我们的网络中增加了2-3%的mAP。
YOLO对边界框预测施加了很强的空间约束,因为每个网格单元只预测两个框,并且只能有一个类。这种空间限制限制了我们的模型可以预测的附近物体的数量。我们的模型正在努力识别成群出现的小物体,比如鸟群。
由于我们的模型学会了从数据中预测边界框,它很难推广到新的或不寻常的高宽比或配置的对象。我们的模型还使用了相对粗糙的特征来预测边界框,因为我们的体系结构从输入图像中有多个降采样层。
最后,我们的损失函数在小边界框与大边界框中的惩罚是相同的。大框里的小误差通常是良性的,但小框里的小误差对IOU有更大的影响。我们的主要损失来源是不正确的定位(这里大框小框对于IOU的误差不是很明白)。
对象检测是计算机视觉中的一个核心问题。检测管道(detection pipeline)通常从从输入图像中提取一组鲁棒特征开始,然后,使用分类器或定位器(分类器和定位器有什么区别)来识别特征空间中的对象。这些分类器或定位器都在整个图片上以滑动窗口(sliding windows)的方式运行或在图像中某些区域子集上运行。我们将YOLO检测系统与几个顶级检测框架进行了比较,突出了关键的相似性和差异性。
DPM使用滑动窗口(sliding windows找时间看一下)的方法来检测对象。DPM使用一个不相交的管道(disjoint pipeline)来提取静态特征(static features)、分类区域(classify regions)、对高得分区域预测边界框。我们的系统用一个单一的卷积神经网络取代了所有这些不同的部分。该网络执行特征提取、边界框预测、非最大抑制和上下文操作 同时推理。Instead fo static features(静态特征),网络trains the features in-line and 在检测任务中优化它们。我们的统一体系结构生成了一个比DPM更快、更准确的模型。
R-CNN及其变体使用区域建议(region proposals)而不是滑动窗口来寻找图像中的对象。选择性搜索(Selective Search,SS算法)生成潜在的边界框,卷积网络提取特征,SVM对框进行评分,线性模型调整边界框,非最大抑制消除了重复检测。这个复杂算法(pipeline)的每个阶段都必须精确地独立调谐(precisely tuned independently),并且由此产生的系统非常慢,在测试时每幅图像花费的时间超过40秒.
YOLO与R-CNN有一些相似之处。每个网格单元格提出了潜在的边界框,并使用卷积特征对这些框进行评分。然而,我们的系统对网格单元的建议施加了空间约束,这有助于减轻对同一对象的多次检测。我们的系统生成更少的边界框,每张图像只有98个,而SS算法大约有2000个。最后,我们的系统将这些单独的组件组合成一个单一的、联合优化的模型。
Fast and Faster R-CNN专注于通过共享计算(sharing computation)和使用神经网络生成区域而不是SS,来加快R-CNN框架的速度。虽然它们提供了比R-CNN更好的速度和准确性的改进,但两者仍然低于实时性能。
许多研究工作都集中在加快DPM pipeline。它们加快了HOG的计算,使用级联(cascades),并将计算推到gpu上。然而只能把DPM跑到30Hz。
YOLO没有试图优化大型检测算法的单个组件,而是完全脱离了pipeline,速度更快。
如面孔或人等单个类的检测器可以高度优化,因为它们只需处理较少的变化。YOLO是一种通用的检测器,它可以学习同时检测各种物体。
下面的对比和实验部分以后有时间补上
YOLO系列之yolo v2_木盏-CSDN博客_yolo_v2
归一化(normalization):将一批不太标准的数据统一到指定的格式.
我们在数据处理时常用的是将一组范围差距较大或者单位不同的数据依据一定规则变化到指定的范围之内。
有之前的工作说明对图像的像素值分布变换为以0为均值,单位方差的正态分布数值时(这种操作被称为whiten),可以加速网络收敛。现在换作深度神经网络每一隐藏层的输入也可以做whiten吧?这样BN出现了。
ps:one-stage,two-stage,精度不够用two-stage行不行先。
B站讲YOLO的:
【精读AI论文】YOLO V1目标检测,看我就够了_哔哩哔哩_bilibili
BN和dropout为什么不能一起用
yolov1的分类器是448*448,如果输入时224*224的小图片,需要转换成大分辨率再放到网络中,相当于网络学会了把小图片放大来识别的能力。(可能这对于大图片识别是不友好的),所以yolov2使用了大分辨率的图片来训练,提高了3.5的mAP(所以用来测试的数据集到底是什么大小的,还是都有,v2在训练的时候是用了小分辨率和大分辨率一起训练吗??如果只用大分辨率然后在大分辨率的数据集中测试效果会不会更好发??如果测试集中有很多不同大小的图片呢??)
到yolov5还是用了Anchor,但是在后来的很多算法中已经Anchor-free了。YOLOv2中分了13*13个grid cell,每个grid cell有5个Anchor。这些Anchor与ground truth IOU最大的框负责检测。YOLOv2中类别预测由框负责而不是单元格负责。YOLOv2对VOC 2007和COCO数据集中的物体长宽比进行了聚类(这是怎么聚类的??)
偏移量有x,y,w,h,对于在聚类的时候的IOU计算,应该不止有长宽比还有Anchor 的w,h初始值。
在计算坐标偏差的时候加入了sigmoid函数,把误差约束在grid cell内。如果没有这步会在模型训练初期Anchor到处乱跑,导致模型不稳定。
损失函数第一项把5个Anchor中与ground truthIOU小于0.6的置信度推向0,但其实在后面的项中也会把这些框的位置和大小推向标注框。前12800次迭代把预测框推向Anchor的位置,每个Anchor中把预测框推向的位置和大小都不同,让5个预测框产生分化。(Anchor的形状位置是什么样的,是由什么决定的,所以说其实预测框本质上和v1还是一样的,只是在损失函数里面加了一项在前12800次中把预测框推向Anchor,那)
IOU小于0.6的Anchor对应的预测框的置信度推向0,在下面把状元Anchor的位置和大小推向标注框。剩下的那些不好不差的就不管了。
在卷积中拿出来一个做1*1卷积,然后拆成四份(Pass Through),最后拼接到上面卷积下来的13*13的张量中,这样既有了低维的细粒度特征,又有了高维的语义特征 ,然后再用一个3*3的卷积核给卷成了1024
在训练过程中往模型中喂了不同scale的图片,强迫模型适应不同大小的图片识别。
DarkNet-19中有Global Average Pooling(全局平均池化),它会把输出的feature map的每一个通道求平均,来替代全连接层(这跟输入有关系吗,输入图片大小不是固定的吗??这怎么替代全连接层??得去看看全局平均池化的原理)。 如果像YOLOv1一样用全连接层的话输入的大小必须是固定的。(这是因为在模型输入的前端就固定了输入大小还是因为性能原因使用全连接层不能放入不同大小的图片??也就是说图片输入了之后是什么层,直接卷积吗??那这用GAP也不能放入不同大小图片吧)。还有一个附加功能是,如果输入的是大图片,那么预测的慢,精度高;如果是小图片,那么预测的快,精度低。可以根据需求选择。
增大recall是什么意思 YOLOv2产生了800多个预测框,可以把目标尽可能检测出来,recall增大了,但是那些没用的框的比例也增大了,所以precision降低了。
FASTER:
Resnet50网络很深,有很多跳连接,所以内存占用比较大。YOLOv3采用了Darknet53,YOLOv2采用了Darknet19
Darknet分为分类和检测模型,在训练模型中大量使用1*1卷积 来降维,减少运算量。先降维再升维。
ImageNet有几万个类别,1400张图片,但是只有分类的标签,没有检测和定位的标签。coco只有10万张图片,80个类别,但是有检测标签。
下面stronger没看了,以后看,论文也跳过了
mAP的算法后面可以了解一下
53=52层卷积+1层全连接
在这里把分类器拿掉了,backbone是一个全卷积网络,可以适应任意尺度的输入。但输入的大小要是32的别墅,因为要下采样32,16和8倍
Residual是什么
这里有三种尺度的感受野,不同尺度感受野对应不同尺度的物体
Concat操作是两个截面积一样的张量在高度上摞起来
52*52的感受野三种大小的信息都有,既有深层的语义特征,也有浅层网络的细粒度特征(像素级别的边缘、转角等底层特征)
论文名称:Random erasing data augmentation
论文地址:https://arxiv.org/pdf/1708.04896v2.pdf
github:GitHub - zhunzhong07/Random-Erasing: Random Erasing Data Augmentation. Experiments on CIFAR10, CIFAR100 and Fashion-MNISTRandom Erasing Data Augmentation. Experiments on CIFAR10, CIFAR100 and Fashion-MNIST - GitHub - zhunzhong07/Random-Erasing: Random Erasing Data Augmentation. Experiments on CIFAR10, CIFAR100 and Fashion-MNISThttps://github.com/zhunzhong07/Random-Erasing
随机擦除增强,非常容易理解。作者提出的目的主要是模拟遮挡,从而提高模型泛化能力,这种操作其实非常有用,因为我把物体遮挡一部分后依然能够分类正确,那么肯定会迫使网络利用局部未遮挡的数据进行识别,加大了训练难度,一定程度会提高泛化能力。其也可以被视为add noise的一种,并且与随机剪裁,随机水平翻转具有一定的互补性,综合应用他们,可以取得更好的模型表现,尤其是对噪声和遮挡具有更好的鲁棒性。具体操作就是:随机选择一个区域,然后采用随机值进行覆盖,模拟遮挡场景。
在细节上,可以通过参数控制擦除的面积比例和宽高比,如果随机到指定数目还无法满足设置条件(这是啥意思),则强制返回。一些可视化效果如下:
对于目标检测,作者还实现了3张做法,如下图所示(然而我打开开源代码,发现只实现了分类的随机擦除而已)。
当然随机擦除可以和其他数据增强联合使用,如下所示。
Random Croping技术有空了解一下,看起来像是随机放大
torchvision已经实现了:https://pytorch.org/docs/master/_modules/torchvision/transforms/transforms.html#RandomErasinghttps://pytorch.org/docs/master/_modules/torchvision/transforms/transforms.html#RandomErasing
注意:torchvision的实现仅仅针对分类而言,如果想用于检测,还需要自己改造(不知道现在是啥样了,本人没调用过)。调用如下所示:
torchvision.transforms.RandomErasing(p=0.5, scale=(0.02, 0.33), ratio=(0.3, 3.3), value=0, inplace=False)
论文名称:Improved Regularization of Convolutional Neural Networks with Cutout
论文地址:https://arxiv.org/abs/1708.04552v2
github:GitHub - uoguelph-mlrg/Cutout: 2.56%, 15.20%, 1.30% on CIFAR10, CIFAR100, and SVHN https://arxiv.org/abs/1708.04552
出发点和随机擦除一样,也是模拟遮挡,目的是提高泛化能力,是实现上比random erasing简单,随机选择一个固定大小的正方形区域,然后采用全0填充就OK了,当然为了避免填充0值对训练的影响,应该要对数据进行中心归一化操作,norm到0
本文和随机擦除几乎同时发表,难分高下(不同场景下谁好难说),区别在于cutout中,擦除矩形区域存在一定概率不完全在原图像中的。而在Random Erasing中,擦除矩形区域一定在原图像内。Cutout变形的实现了任意大小的擦除,以及保留更多重要的区域。
需要注意的是,作者发现cutout区域的大小比形状重要,所以cutout只要是正方形就行,非常简单。具体操作是利用固定大小的矩形对图像进行遮挡,在矩形范围内,所有的值都被设置为0,或者其他纯色值。而且擦除矩形区域存在一定概率不完全在原图像中的(文中设置为50%)
论文中有一个细节可以看看:作者其实开发了一个早期做法,具体是:在训练的每一个epoch过程中,保存每张图片对应的最大激活特征图(以resnet为例,可以是layer4层特征图),在下一个训练回合,对每张图片对应的最大激活图进行上采样到和原图一样大,然后使用阈值分割切分为二值图,盖在原图上再输入到cnn中进行训练,有点自适应的意味。
这部分以后再看
YOLOv3结构图:
YOLOv4结构图:
在YOLOv3中卷积层的激活函数都是leaky relu,模块都是CBL。在YOLOv4中多了Mish激活函数,多了CBM模块。残差模块和YOLOv3是一样的,但是两个卷积层不是用CBL的形式,而是CBM。
还多了CSP结构,走过CBM之后,上面的分支走一个CBM然后是X个残差,然后再CBM,下面的分支直接就是一个CBM,最后再Concat起来
主干网络和YOLOv3一样进行不同程度的下采样
Neck部分中只有FPN结构不同,在FPN中增加了SPP模块,在后面也增加了两个PAN模块
为了能在单GPU上达到更好的效果,在数据增强方面使用了Mosaic;
从减少内存的角度,增加了cross mini-batch normalization,即cmBN的方式;
又从训练角度,增加了SAT自对抗训练的方式(但感觉cmBN和SAT自对抗训练的影响并不是很大,up主说的)
在backbone中在YOLOv3的基础上 采用了CSPDarknet结构,而且在主干网络的所有卷积层中,激活函数都没有用Leaky relu的方式,而是采用Mish激活函数。此外,还增加了Dropblock方式
在YOLOv4的neck中,一方面增加了SPP模块,另一方面,在FPN结构的基础上,借鉴PANet结构的方式,采用FPN加上PAN的结构通过这种方式,让网络特征更好的融合。
在输出中主要改进的是损失函数CIOU_Loss,以及在后处理中,预测框筛选的Nms变成了DIOU_Nms