暑校


2、yolo系列-yolov2

<h1>改进目标</h1> <p>1、解决YOLOv1召回率和定位精度方面的不足。 2、因为YOLOV1的目标检测数据集非常有限,能检测的对象种类也只有20类。所以YOLOV2使用了联合数据集进行训练。</p> <h1>网络结构</h1> <p><strong>修改1:</strong>yolo v2在网络结构上更换了backbone(主干网络),替换了v1中所使用的GoogLeNet网络,采用了一个新的主干网络DarkNet-19。DarkNet-19中有19层卷积层,具体一层卷积包含的内容如下图所示,包括线性卷积、BN层以及激活函数: &lt;center&gt;&lt;img src=&quot;<a href="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=d8076933dc62e153e8cf3cdc3ff943c5&amp;file=file.png&quot">https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=d8076933dc62e153e8cf3cdc3ff943c5&amp;file=file.png&quot</a>; width=&quot;30%&quot; height=&quot;auto&quot;&gt;&lt;/center&gt; <strong>修改2:</strong>每个卷积层后新增BN层(批量归一化)以加快模型收敛同时防止过拟合。</p> <p><strong>修改3:</strong>YOLO V2中删除了V1当中最后的那两层全连接层,因为全连接层需要很多的权重参数。最后用average pooling(平均池化)层代替全连接层进行预测。</p> <p>整体网络结构如下图所示: &lt;center&gt;&lt;img src=&quot;<a href="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=7e9b2bf1d34f896632eaeb49a2878376&amp;file=file.png&quot">https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=7e9b2bf1d34f896632eaeb49a2878376&amp;file=file.png&quot</a>; width=&quot;40%&quot; height=&quot;auto&quot;&gt;&lt;/center&gt;</p> <p>&amp;emsp;&amp;emsp;为什么删掉了全连接层?<strong>因为全连接层容易过拟合,而且训练慢。如下图所示,YOLOv1中通过全连接层将7×7×1024的特征图变换为7×7×30的特征图。但是这种变换完全可以通过一个3×3的卷积核做到,从而节省参数。</strong> &lt;center&gt;&lt;img src=&quot;<a href="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=92728639960362f947836c3ef6eeaaac&amp;file=file.png&quot">https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=92728639960362f947836c3ef6eeaaac&amp;file=file.png&quot</a>; width=&quot;40%&quot; height=&quot;auto&quot;&gt;&lt;/center&gt;</p> <h6>v2的训练过程</h6> <ul> <li>第一阶段就是先在ImageNet分类数据集上预训练Darknet-19,此时模型输入为 224x224 ,共训练160个epochs。</li> <li>第二阶段将网络的输入调整为 448x448,继续在ImageNet数据集上finetune分类模型,训练10个epochs,此时分类模型的top-1准确度为76.5%,而top-5准确度为93.3%。</li> <li>第三个阶段就是修改Darknet-19分类模型为检测模型,移除最后一个卷积层、global avgpooling层以及softmax层,并且新增了三个3x3x1024卷积层,同时增加了一个passthrough层,最后使用1x1卷积层输出预测结果。 <img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=a6d83f4b32cb4e4f0574e3551f802756&amp;amp;file=file.jpg" alt="" /></li> </ul> <h1>改进细节</h1> <h3>Batch Normalization—批量归一化</h3> <h6><strong>目的</strong></h6> <p>防止过拟合</p> <h6>v1</h6> <p>YOLO V1是通过在全连接层添加dropout来防止过拟合。dropout防止过拟合是利用极端正则化实现的,具体操作是通过抛弃一些全连接层中神经元实现的正则化。</p> <h6>v2</h6> <p>YOLO V2里删除了V1当中最后两层的全连接层,通过在所有卷积层上添加批量归一化,防止过拟合,在mAP上得到了<strong>超过2%的改善</strong>。</p> <ul> <li>(1)为什么要提出批量归一化? &amp;emsp;&amp;emsp;在标准的CNN训练中,每一层网络的输入数据分布会随着网络的深入而发生变化。因为每一层都在对前一层的输出进行某种形式的变换。随着训练的进行,这些变换可能会导致数据分布发生偏移或扩展,这种现象称为&quot;内部协变量偏移&quot;(Internal Covariate Shift,ICS)。内部协变量偏移会增加训练难度,因为网络需要不断地适应输入数据分布的变化。 &amp;emsp;&amp;emsp;批量归一化在每个卷积层之后对数据进行归一化处理,即对每个小批量(mini-batch)的数据进行归一化,使其具有固定的均值和方差。具体来说,对于每个神经元的输出,批量归一化会计算该神经元在当前小批量中的均值和方差,然后将输出数据转换为标准化形式,<strong>最后通过可学习的参数(缩放因子γ和偏移量β)来恢复网络的表达能力</strong>。 &amp;emsp;&amp;emsp;通过批量归一化,网络的每一层不再需要单独学习输入数据的分布,因为输入数据已经被规范化了。这样可以使网络训练过程更快,更容易收敛,同时也有助于减少对初始化权重的敏感性,并可以在一定程度上防止过拟合。</li> <li>(2)介绍一下批量归一化的步骤 &amp;emsp;&amp;emsp;<strong> 计算均值:</strong>对于当前层的输入,计算每个特征在小批量中的平均值。 &amp;emsp;&amp;emsp;<strong> 计算方差:</strong>计算每个特征在小批量中的方差。 &amp;emsp;&amp;emsp;<strong> 归一化:</strong>使用均值和方差将每个特征的输入值进行归一化,即减去均值后除以方差的平方根。 &amp;emsp;&amp;emsp;<strong> 缩放和平移:</strong>归一化后的值会通过两个可学习的参数(通常称为γ和β)进行缩放和平移,以恢复网络的表达能力。</li> </ul> <h3>High Resolution—高分辨率</h3> <h6><strong>目的</strong></h6> <p>解决图像分辨率变化所带来的问题</p> <h6>v1</h6> <ol> <li>预训练的时候用的是224x224的输入,一般预训练的分类模型都是在ImageNet数据集上进行的</li> <li>检测的时候采用448x48的输入。</li> </ol> <p><strong>这样做意味着从分类模型切换到检测模型的时候,模型需要辨率的不同。</strong></p> <h6>v2</h6> <ol> <li>v2比V1多了一个“二次微调(fine-tune)”。</li> <li>预训练先用224x224的输入对模型进行了常规的预训练,大概训练160个epoch。</li> <li>然后再将输入调整到448x48,再训练10个epoch。<strong>注意这两步都是在ImageNet数据集上操作。</strong>这个过程使得模型在检测数据集上微调之前已经适用高分辨率输入。</li> <li>检测的时候用448x48的图像作为输入就可以顺利过渡了。</li> </ol> <p><strong>在训练中添加了这十次大分辨率的微调使得mAP提升了4%。</strong></p> <h3>K-means聚类确定Anchor初始值</h3> <h6><strong>目的</strong></h6> <p>给定一组anchor的初始值,使模型更容易生成相对精准的预测框。</p> <h6>anchor-先验框</h6> <p>Anchor(先验框):就是一组预设设定好的边框,在训练时,以真实的边框位置相对于预设边框的偏移来构建训练样本。如果用一句话概括就是在图像上<strong>预设好的不同大小,不同长宽比的参照框</strong>。</p> <pre><code class="language-c">在目标检测中有两类: anchor_based:使用先验框的目标检测网络 anchor_free:不使用先验框的目标检测网络,比如yolo v1。因为v1是随机生成两个bounding box,不是预先设置好的参照框。</code></pre> <h6>v1</h6> <p>&amp;emsp;&amp;emsp;V1并没有预先设置2个bounding box的大小和形状。仅仅是对一个对象预测出2个bounding box,选择预测得相对比较准的那个。并且V1的2个bounding box事先并不知道会在什么位置,只有经过前向计算,网络会输出2个bounding box,这两个bounding box与样本中对象实际的ground truth计算IoU。这时才能确定,IOU值大的那个bounding box,作为负责预测该对象的bounding box。 &amp;emsp;&amp;emsp;训练开始阶段,网络预测的bounding box可能都是乱来的,但总是选择IOU相对好一些的那个,随着训练的进行,每个bounding box会逐渐擅长对某些情况的预测(可能是对象大小、宽高比、不同类型的对象等)。 &amp;emsp;&amp;emsp;<strong>总结一句话那就是v1最开始随机生成两个bounding box,在经过不断迭代,不断计算损失,最后生成两个最好的bounding box</strong>。</p> <h6>Faster R-CNN</h6> <p>&amp;emsp;&amp;emsp;比起yolo v1随机生成两个预测框,在Faster R-CNN中是根据经验手动设定anchor的维度(长和宽),带有一定的主观性。也就是说如果选取的anchor维度比较合适,那么模型更容易学习;如果不根据实际情况预选anchor,模型也不容易很快的学习。</p> <h6>v2</h6> <p><strong>简单的说选取一个尺寸比较适当的anchor非常重要,那么网络就更容易去学习得到好的检测器。</strong> 因此,YOLOv2采用k-means聚类方法对训练集中的边界框(ground truth也就是物体真实的边框)做了聚类分析。</p> <ol> <li>确定聚类的个数。在论文中也提到了选取不同的k值(聚类的个数)在不同的数据集上运行K-means算法,并画出平均IOU和K值的曲线图。当k = 5时,可以很好的权衡模型复杂性和高召回率。所以v2中的的anchor个数就被设成了5。</li> <li>设置距离指标。作者通过计算Avg IOU(所有目标的ground truth框与anchors(初始的五个anchor尺寸)最大IOU的均值)作为指标,Avg IOU越大代表得到的anchors越好。距离指标的公式是:距离指标:d(ground truth框, centroid) = 1 − IOU(ground truth框, centroid)。</li> <li>具体流程: 1 在所有的ground truth框中<strong>随机挑选k个作为簇的中心</strong>。 2 <strong>计算</strong>每个ground truth框离每个簇的<strong>距离</strong>1-IOU(ground truth框, anchors) 3 计算每个ground truth框距离最近的簇中心,并<strong>分配</strong>到离它最近的簇中 4 根据每个簇中的ground truth框<strong>重新计算簇中心</strong>; 5 重复3到4直到每个簇中元素不在发生变化</li> </ol> <p>&lt;center&gt;&lt;img src=&quot;<a href="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=b846f121c4838d8512b8e1652faa2d78&amp;file=file.png&quot">https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=b846f121c4838d8512b8e1652faa2d78&amp;file=file.png&quot</a>; width=&quot;50%&quot; height=&quot;auto&quot;&gt;&lt;/center&gt;</p> <pre><code class="language-c">1. 为什么不选取更大的K值? **因为K越大就生成越多的Anchor(先验框),越多的框自然准确率就能上去了,但同时也成倍的增加了模型的复杂度。** 1. 什么是K-means? 请看k-means这一小节。</code></pre> <h3>带有Anchor的卷积</h3> <h6><strong>目的</strong></h6> <p>实现精确定位</p> <h6>v1</h6> <p>输入图片被划分为7x7网格,每个单元格预测2个边界框。<strong>YOLOv1采用的是全连接层直接对边界框进行预测</strong>,导致丢失较多的空间信息,定位不准。将输入图像分成7x7的网格,每个网格预测2个bounding box,一共只有7x7x2=98个box。</p> <h6>v2</h6> <p>YOLOv2: 在 V2移除了V1的全连接层而<strong>采用了卷积和固定的anchor尺寸来预测边界框</strong>。输出feature map大小为13x13,每个网格有5个anchor box预测得到5个预测框,所以一共有13x13x5=845个预测框。增加预测框数量是为了提高目标的定位准确率。 做法:</p> <ol> <li>删掉全连接层和最后一个pooling层,使得最后的卷积层可以有更高分辨率的特征。</li> <li>缩减网络,用416x416大小的输入代替原来448x448。这样做是希望希望得到的特征图都有奇数大小的宽和高,奇数大小的宽和高会使得每个特征图在划分cell的时候就只有一个中心cell。因为大的目标一般会占据图像的中心,所以希望用一个中心cell去预测,而不是4个中心cell。网络最终将416*416的输入下采样32倍变为13x13大小的feature map输出,查看.cfg文件可以看到有8个pooling层。</li> </ol> <h3>2.1.5 Direct location prediction—直接预测位置</h3> <p><a href="https://blog.csdn.net/qq_40755643/article/details/90295824">https://blog.csdn.net/qq_40755643/article/details/90295824</a> YOLO V1: YOLO V2:预测边界框中心点相对于对应cell左上角位置的相对偏移值。将网格归一化为1×1,坐标控制在每个网格内,同时配合sigmod激活函数将预测值转换到0~1之间的办法,做到每一个Anchor只负责检测周围正负一个单位以内的目标box。 下面给出一张图来介绍一下改进后的位置预测,首先一个网格相对于图片左上角的偏移量是cx,cy。先验框的宽度和高度分别是pw和ph,则预测的边界框相对于特征图的中心坐标(bx,by)和宽高bw、bh。 &lt;center&gt;&lt;img src=&quot;<a href="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=2bdd2cf926955d4ea55e89c8aed41f6e&amp;file=file.png&quot">https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=2bdd2cf926955d4ea55e89c8aed41f6e&amp;file=file.png&quot</a>; width=&quot;50%&quot; height=&quot;auto&quot;&gt;&lt;/center&gt;</p> <h3>Fine-Grained Features—细粒度的特征</h3> <h6><strong>目的</strong></h6> <p>&amp;emsp;&amp;emsp;融合高分辨率的特征图,提取细粒度的特征。在13x13的特征图上做预测,虽然对于大目标已经足够了,但对小目标不一定足够好,这里合并前面大一点的特征图可以有效的检测小目标。</p> <h6>v1</h6> <p>&amp;emsp;&amp;emsp;YOLOv2的输入图片大小为416x416,经过5次降采样之后得到13x13大小的特征图,并以此特征图采用卷积做预测。13x13大小的特征图对检测大物体是足够了,但是对于小物体来说降采样丢失了很多信息,所以还需要更精细的特征图。</p> <h6>v2</h6> <p>&amp;emsp;&amp;emsp;YOLO V2新增了一个直通层( passthrough layer):(1)将相邻的特征叠加到不同的通道来,将高分辨率的特征与低分辨率的特征连接起来;(2)将前层26×26×512的特征图转换为13×13×2048的特征图,并与原最后层特征图进行拼接。具体来说就是特征重排(不涉及到参数学习),前面26 x26x512的特征图使用<strong>按行和按列隔行采样</strong>的方法,就可以得到4个新的特征图,维度都是13x13x512,然后做在空间维度上做concat操作,得到13x13 x2048的特征图。 &amp;emsp;&amp;emsp;具体来说:对于26x26x512的特征图,经passthrough层处理之后就变成了13x13x2048的新特征图(特征图大小变为1/4,而通道数变为以前的4倍),然后与后面的13x13x1024特征图连接在一起形成13x13x3072的特征图,最后在该特征图上卷积做预测。 为了节省时间,下面举了一个6x6x256大小的特征图如何切分成3x3,并且通道数增加4倍的例子: &lt;center&gt;&lt;img src=&quot;<a href="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=1384d7d5b41fda9c18e3998b3da11c5a&amp;file=file.jpg&quot">https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=1384d7d5b41fda9c18e3998b3da11c5a&amp;file=file.jpg&quot</a>; width=&quot;65%&quot; height=&quot;auto&quot;&gt;&lt;/center&gt;</p> <h3>Multi-Scale Training—多尺度的训练</h3> <h6>目的</h6> <p>让模型更健壮,适应不同大小的图片(更快学习?)。</p> <h6>v1</h6> <p>固定使用448x448的固定分辨率输入。</p> <h6>v2</h6> <p>每隔10个批次就随机挑选不同批次的分辨率作为输入。因为V2模型只使用了卷积和池化层,所以可以动态调整输入大小。 网络每10批训练后随机选择一个新的图像尺寸大小。由于模型下采样了32倍,所以一定要从32的倍数{320,352,…,608}中选择作为图像维度。将网络输入调整到那个维度,并继续训练。这种机制使得网络可以更好地预测不同尺寸的图片。 这样同一个网络可以进行不同分辨率的检测任务,在输入size较大时,训练速度较慢,在输入size较小时,训练速度较快,而multi-scale training又可以提高准确率,因此算是准确率和速度都取得一个不错的平衡。</p> <h2>3. <strong>参考文献</strong>:</h2> <p>(1)YOLO V2论文:<a href="https://arxiv.org/pdf/1612.08242.pdf#page=4.24">https://arxiv.org/pdf/1612.08242.pdf#page=4.24</a> (2)csdn参考博客:<a href="https://blog.csdn.net/weixin_43334693/article/details/129087464">https://blog.csdn.net/weixin_43334693/article/details/129087464</a> <a href="https://blog.csdn.net/qq_40755643/article/details/90295824">https://blog.csdn.net/qq_40755643/article/details/90295824</a> (3)腾讯云开发者社区:<a href="https://cloud.tencent.com/developer/article/2406045">https://cloud.tencent.com/developer/article/2406045</a> (4)bilibili:<a href="https://www.bilibili.com/video/BV13g4y197Nf?p=30&amp;vd_source=48258d61722fcea384d1c05707db8963">https://www.bilibili.com/video/BV13g4y197Nf?p=30&amp;vd_source=48258d61722fcea384d1c05707db8963</a> (5)Github源码地址:<a href="https://pjreddie.com/darknet/yolo/">https://pjreddie.com/darknet/yolo/</a></p>

页面列表

ITEM_HTML