当前位置: 首页 > 科技观察

目前火爆的YOLOv4是如何制作出来的?细数那些小细节

时间:2023-03-17 22:23:46 科技观察

前段时间YOLOv4的突然发布成为了计算机视觉领域的热点新闻。这个目标检测任务的SOTA模型有什么创新点?这篇解读文章为你一一拆解。目标检测近年来开始成熟,但即便如此,竞争还是很激烈。如下图,YOLOv4号称在保持高处理帧率的同时,达到了当前最先进技术的精度。使用TeslaV100GPU,YOLOv4在MSCOCO数据集上以接近65FPS的推理速度实现了43.5%AP(65.7%AP??)的准确率。但对于物体检测,高精度不再是唯一目标。我们还希望边缘设备也能顺利运行这些模型。因此,如何利用低成本的硬件对输入视频进行实时处理成为一个重要的研究方向。YOLOv4的开发是一个有趣的过程,评估、修改和集成了许多有趣的新技术。而且它还优化了计算效率,使检测器可以在单个GPU上得到很好的训练。为了提高准确率,Bagoffreebies(BoF)和Bagofspecials(BoS)可以针对训练过程进行优化,例如数据增强、类别不平衡、成本函数、软标签……这些改进不会影响推理速度,可以称为“免费赠品袋”。还有称为“特价包”的改进,可以产生良好的性能回报,而推理时间只需要很小的牺牲。这些改进包括增加感受野,使用注意机制,集成跳跃连接或FPN等特征,以及使用非最大抑制等后处理方法。本文将讨论特征提取器和颈部是如何设计的,以及那些好的BoF和BoS改进策略。Backbonenetworkdensemodule和DenseNet为了提高准确率,我们可以通过增加网络的深度来扩大感受野,增加模型的复杂度。同时,为了降低训练难度,也可以应用skipconnections。我们还可以进一步扩展这个概念以使用高度互连的层。密集块(DenseBlock)包含多个卷积层,其中每一层H_i由batchnormalization、ReLU和后续的卷积组成。H_i的输入不仅包含前一层的输出,还包含前所有层的输出以及原始输入,即x_?,x_?,…,x_{i-1}。下图中每个H_i输出4个featuremaps。因此,在每一层,特征图的数量增加了4倍——增长率。然后,可以通过将多个密集模块与中间的过渡层(由卷积和池化组成)相结合来构建DenseNet。下面给出了此架构设计的详细信息。Cross-StagePartialConnection(CSP)CSPNet将密集模块的输入特征图分为两部分。第一部分x_?'绕过密集模块并成为下一个过渡层的输入的一部分。第二部分x_?’’会经过dense模块,如下图所示。这种新设计通过将输入一分为二来降低计算复杂性——只有一部分输入通过密集块。CSPDarknet53YOLOv4使用上面的CSP和下面的Darknet-53作为特征提取的主干。CSPDarknet53模型的物体检测精度高于基于ResNet的设计,但ResNet的分类性能更好。然而,CSPDarknet53的分类精度可以通过使用Mish和后面讨论的其他技术来提高。因此,YOLOv4最终选择了CSPDarknet53。Neckobjectdetector由一个用于特征提取的backbone和一个用于物体检测的head组成(下图中最右边的模块)。为了检测不同大小的物体,需要使用层次结构,以便头部可以检测不同空间分辨率的特征图。为了使输入的表头信息量更大,在输入表头之前,将自下而上和自上而下的数据流逐个元素相加或拼接。因此,头部的输入将包含来自自下而上数据流的丰富空间信息以及来自自上而下数据流的丰富语义信息。系统的这一部分称为颈部。下面将更详细地讨论这种设计。FeaturePyramidNetwork(FPN)YOLOv3使用类似于FPN的方法来实现不同大小级别的物体检测预测。当对特定尺寸进行预测时,FPN对自上而下的数据流进行上采样(乘以2),并将其与自下而上的相邻层相加(见下图)。将获得的结果传递给3×3卷积核以减少上采样伪影,并为头部创建下图中的特征图P4。SPP(SpatialPyramidPoolingLayer)SPP应用略有不同的策略来检测不同大小的物体,即用空间金字塔池化层替换最后一个池化层(在最后一个卷积层之后)。它的特征图在空间上分为m×m个bin,其中m可以是1、2、4等。然后对于每个通道,每个bin应用一次最大池化。这导致固定长度的表示,然后可以使用FC层进一步分析。许多基于CNN的模型包含FC层,因此只能接受指定大小的输入图像。相反,SPP可以使用不同大小的图像。然而,也有不包括FC层的技术,例如FullyConvolutionalNetworks(FCN);这些技术可以接受不同尺寸的图像。这种类型的设计对于空间信息很重要的图像分割等任务尤为重要。因此,对于YOLO来说,没有必要将2D特征图转换成固定大小的1D向量。YOLOYOLO中使用SPP的SPP被修改以保留输出的空间维度大小。最大池化也应用于大小为1×1、5×5、9×9、13×13等的滑动内核。空间维度被保留。然后将来自不同内核大小的特征图连接起来作为输出。下图展示了SPP是如何集成到YOLO中的。路径聚合网络(PAN)的早期深度学习模型设计比较简单。每层的输入来自于它上面的层。较早的层提取局部纹理和图案信息,并构建后续层所需的语义信息。然而,随着网络向右推进,微调预测结果所需的局部信息可能会丢失。在后来的深度学习发展中,层的互连方式变得更加复杂。DenseNet在这方面做到了极致。这些层中的每一层都连接它之前的所有层。在FPN中,来自自下而上和自上而下数据流中相邻层的信息被组合在一起。信息在各层之间流动的方式成为模型设计中的另一个关键考虑因素。下图是一个用于物体检测的路径聚合网络(PAN)。其中增强了自下而上的路径,使得底层信息更容易向上传播。在FPN中,局部空间信息向上传播,如红色箭头所示。虽然在图中可能看不清楚,但这条红色的路径横跨了大约100层。PAN引入了一条捷径(绿色路径),仅需大约10层即可到达顶层N?层。这种短循环概念使顶层能够获得细粒度的本地信息。顺便说一句,颈部设计可以可视化如下:然而,YOLOv4不是将相邻层加在一起,而是将特征图连接在一起。在FPN中,不同大小的物体是分别独立检测的。这可能会导致重复预测并且无法利用来自其他特征图的信息。PAN首先使用element-wisemaximumoperation将这些信息融合在一起(具体细节这里不再赘述)。空间注意模块(SAM)注意已广泛用于深度学习设计。SAM将最大池化和平均池化应用于输入特征图,产生两组特征图。结果被送入卷积层,之后sigmoid函数产生空间注意力。然后将该空间注意力掩码应用于输入特征以输出优化的特征图。YOLOv4使用SAM的修改版本,其中不使用最大池化和平均池化。YOLOv4使用SPP、PAN和SAM的修改版本逐步实现/替换FPN概念。Bagoffreebies(BoF)forthebackbonepartYOLOv4backbone部分的BoF特性包括:这迫使模型在执行分类时不要过于相信某些特征。但是,如果图像的某些部分充满了无用信息,则此操作就被浪费了。CutMix的做法不同,它会剪切图像的一部分并将其粘贴到另一幅图像上。它的groundtruthlabel是根据patch的面积比例来调整的,比如dog部分是0.6,cat部分是0.4。从概念上讲,CutMix对对象的可能组成部分有更广泛的了解。修剪迫使模型学习使用不同的特征组合进行分类。这避免了过度自信。由于该区域被替换为另一幅图像,因此图像中的信息量和训练效率都不会受到显着影响。MosaicDataAugmentationMosaic是一种数据增强方法,它将4个训练图像组合成一个用于训练(而不是CutMix中的2个)。这允许模型在非常规环境中更好地执行对象检测。此外,由于每个mini-batch包含更多图像变体(4×),因此在估计均值和方差时不需要更大的mini-batch。DropBlockregularization在全连接层中,我们可以丢弃一些连接来强制模型学习不同的特征,而不是过分依赖少数特征。但是,这可能不适用于卷积层。相邻位置可能高度相关。所以即使丢弃了一些像素(如中图所示),仍然可以检测到空间信息。DropBlock正则化基于类似的概念,但应用于卷积层。但是,DropBlock丢弃的不是单个像素,而是大小为block_size×block_size的像素块。类别标签平滑每当您认为自己完全正确时,您可能只是想错了。如果预测的置信度为100%,则可能仅意味着模型记住了数据,而不是学习了一些东西。标签平滑将预测的目标上限调整为较低的值,比如0.9。然后在计算损失时,模型将以这个值为目标,而不是1.0。这种方法减轻了过度拟合的问题。p=tf.placeholder(tf.float32,shape=[None,10])#使用0.9而不是1.0.feed_dict={p:[[0,0,0,0.9,0,0,0,0,0,0]]#带有标签“3”的图像}#logits_real_image是由#真实图像的判别器计算的logits.d_real_loss=tf.nn.sigmoid_cross_entropy_with_logits(labels=p,logits=logits_real_image)主干部分的特价包(BoS)Mishactivationcross-stagepartialconnection(CSP)multi-inputweightedresidualconnection(MiWRC)Mishactivation假设激活函数的形式是:其中有许多不同的候选函数用于一元或二元算子,例如余弦函数.在选择这些函数时,我们可以进行随机猜测,然后根据不同的任务(如分类)和数据集来评估相应模型的性能。最终,我们可以选择使模型表现最佳的激活函数。我们还可以应用强化学习来更有效地搜索解决方案空间。使用这种方法并进行实验,我们发现了以下新的激活函数Swish,它优于ReLU以及许多其他激活函数。不同β值的Swish激活函数Mish是另一个与ReLU和Swish非常相似的激活函数。Mish的论文(arXiv:1908.08681)声称使用Mish的深度网络在许多不同的数据集上表现更好。将Mish用于CSPDarknet53和检测器,YOLOv4提高了两种精度。Multi-InputWeightedResidualConnections(MiWRC)在过去的几年里,研究人员主要关注哪些特征图应该输入到网络层。有时我们超越了仅使用前一层的传统方法。现在,更重要的是层的连接方式,尤其是在物体检测器中。前面讨论了FPN和PAN示例。下图中的d显示了另一种颈部设计BiFPN,其论文(arXiv:1911.09070)声称BiFPN在准确性和效率权衡方面表现更好。YOLOv4将其性能与EfficientDet进行了比较,EfficientDet被认为是最先进的技术之一。让我们来看看这个技术。如下图,EfficientDet使用EfficientNet作为backbone,BiFPN作为neck。作为参考,EfficientNet的架构建立在由倒置残差模块组成的MBConv层之上,如下所示。正如其论文(arXiv:1801.04381??)中所述,此逆残差模块的构建方式是第一层称为深度卷积,它是通过为每个输入通道应用单个卷积滤波器来实现的。执行轻量级过滤。第二层是一个1×1的卷积,称为逐点卷积,负责通过计算输入通道的线性组合来构建新的特征。假设输入的维度为h?×w?×d?。然后它应用d?k×k卷积滤波器——每个通道一个。然后它对所有通道应用1×1卷积滤波器,产生大小为h?×w?×d?的输出。因此,总的计算复杂度为:它的关键优势在于它需要的计算量比传统的卷积层少得多。在许多机器学习和深度学习问题中,我们学习输入的低维表示。我们将通过制造“信息”瓶颈来提取数据的核心信息。这迫使我们发现最重要的信息,这是学习的核心。遵循这一原则,反向残差模块将低维表示作为输入,然后使用卷积(线性运算)和非线性运算对其进行运算。然而,ReLU等非线性部分面临一个很大的问题:非线性操作会不成比例地拉伸或压缩某些区域。当发生这种压缩时,输入可能映射到相同的区域/点。例如,ReLU可能会将通道折叠到这个低维空间中,从而导致不可避免的信息丢失。如论文所述:重要的是去除窄层中的非线性以保持表征能力。为了解决这个问题,我们可以暂时扩大维度(通道数)。我们希望当我们有大量的通道时,信息可能在非线性操作后仍然存储在某些通道中。下面给出了逆残差模块的一些细节:可以看出,首先将低维表示扩展到t_k个通道。然后,使用轻量级3×3深度卷积对其进行过滤。在本模块的末尾,特征被缩减回更低的维度。在保留高维空间的同时,添加了非线性操作。在模块的开始和结束之间添加了一个剩余连接。下图左图是传统的残差模块,右图是这里介绍的反向残差模块。理解EfficientDet的核心概念很有趣。但EfficientDet在YOLOv4上的主要贡献是多输入加权残差连接。在EfficientDet论文中,可以观察到不同分辨率下的不同输入特征对输出特征的贡献并不相同。但是在前面的讨论中,我们胡乱地添加了这些特性。在EfficientDet中,在构建输出时输入特征的权重不同:w?的训练和学习方式与其他可训练参数相同。Bagoffreebies(BoF)fordetectorsYOLOv4detectors的BoFfeatures包括:函数可以为我们提供一个信号,告诉我们如何调整权重以降低成本。因此,当预测错误时,我们希望它们能为我们指明前进的方向。但是当使用IoU并且地面实况框不与预测重叠时,这是不可能的。鉴于有两个预测不与groundtruth重叠,IoU损失函数无法确定哪个更好——即使其中一个可能更接近groundtruth。GeneralizedIoU(GIoU)通过将这种损失优化为通常首先扩展其预测边界框直到与地面实况区域重叠的形式来解决这个问题。然后它缩小以增加IoU。这个过程实际上需要比理论上需要的迭代次数更多的迭代次数。首先,引入距离-IoU损失(DIoU):它引入了一个新的目标来减少两个框的中心点之间的距离。最后,引入CompleteIoULoss(CIoU)来:增加groundtruthbox和predictedbox的重叠区域;最小化它们中心点之间的距离;保持盒子纵横比的一致性。它最终的定义是:CmBN原始的batchnormalization会收集小batch数据中样本的均值和方差,输入到白化层。然而,如果mini-batch的大小很小,这些估计就会有很大的噪声。一种解决方案是在许多小批量上估计它们。但是,由于权重在每次迭代中都会发生变化,因此在这些权重下收集的统计数据在新权重下可能会变得不准确。简单的平均可能是错误的。幸运的是,重量的变化是逐渐发生的。交叉迭代批量归一化(CBM)使用以下调整来估计这些基于k先前迭代的统计数据。CmBN是一个修改后的选项,它只收集单个批次内小批量数据之间的统计信息。自我对抗训练(SAT)SAT是一种数据增强技术。它首先对训练样本执行正向传递。使用传统方法,我们在反向传播过程中调整模型的权重,以提高检测器检测图像中物体的能力。但是这里采样的方向是相反的。它以最小化检测器性能的方式修改图像,即创建针对当前模型的对抗性攻击——即使新图像在人眼看来可能与原始图像相同。接下来,使用带有原始边界框和类标签的新图像训练模型。这有助于提高模型的泛化能力,减少过拟合。消除网格灵敏度边界框b的计算方式是,对于b?=c?和b?=c?+1的情况,我们需要t?分别具有较大的负值和正值。但是我们可以通过将σ乘以比例因子(>1.0)来更容易地实现这一点。这是对源代码的修改:对单个地面实况使用多个锚点如果IoU(groundtruth,anchor)>IoUthreshold,则对单个地面实况使用多个锚点。(注:作者并没有在YOLOv4中详细解释这种方法的作用。)Cosineannealingscheduler余弦调度根据一个余弦函数来调整学习率。首先,较大的学习率以较慢的速度下降。然后中途,学习率下降的比较快,最后学习率又下降的很慢。该图显示了学习率如何衰减(下图中也应用了学习率预热)及其对mAP的影响。由于它可能看起来并不明显,这种新的调度方法取得了更稳定的进展,而不是在停滞一段时间后取得进展。余弦学习率+热身使用遗传算法(进化算法)选择超参数进化算法是一种有根据的猜测方法。它遵循“适者生存”的理念。例如,如果我们随机选择100组超参数。然后用它们训练100个模型。之后,我们从中选出了表现最好的10款机型。对于每个选定的模型,从原始模型创建了10个超参数略有不同的变体。然后使用这些新的超参数重新训练模型,并再次选择表现最好的模型。随着我们的迭代,我们应该能够找到最佳的超参数集。或者,我们可以从默认超参数开始,然后再执行突变。正如他们的论文(arXiv:2004.10934)中所写:遗传算法使用YOLOv3-SPP,使用GIoU损失进行训练,并为min-val5k数据集搜索300个epoch。我们使用0.00261的搜索学习率、0.949的动量、0.213的IoU阈值来分配基本事实,以及0.07的损失归一化算子用于遗传算法实验。随机训练形状许多单级目标检测器都是用固定的输入图像形状训练的。为了提高泛化能力,我们可以训练具有不同图像大小的模型。(YOLO中的多尺度训练。)BagofSpecials(BoS)fordetectorsYOLOv4探测器的BoS特性包括:出预测相同对象的其他边界框并保持具有最高置信度的边界框。DIoU(前面讨论过)被用作NMS的一个因素。该方法在抑制冗余边界框时使用IoU和两个边界框中心点之间的距离。这使得模型对遮挡更加稳健。评估的技术尽管本文介绍了已集成到YOLOv4中的技术,但YOLOv4也投入了大量精力来评估其他技术。最后,展示YOLOv4考虑的技术列表: