【YOLO学习】从YOLOv1到YOLOv2的YOLO学习

从YOLOv1到YOLOv2的YOLO学习

文章目录

  • 从YOLOv1到YOLOv2的YOLO学习
    • YOLOv2与v1的区别
    • YOLOv2网络结构
    • YOLOv2聚类提取先验
    • YOLOv2-Anchor Box
    • YOLOv2-Directed Location Prediction(偏移量)
      • 计算方式
      • 总结
    • YOLOv2-Fine-Grained Feature
      • 感受野
      • 感受野的卷积核大小
      • 特征层处理
    • YOLOv2-Multi-Scale(多尺度识别)

YOLOv2与v1的区别

  • v1训练是用 224 × 224 224\times224 224×224,测试时用的是 448 × 448 448\times448 448×448
  • 可能会导致模型与图像大小不同,v2的时候训练又额外进行了10次 448 × 448 448\times448 448×448的微调
  • 使用了高分辨率分类器,map提升了4%

YOLOv2网络结构

  • Darknet,实际输入为 416 × 416 416\times416 416×416,借鉴了vggresnet
  • 没有FC层,进行5次下采样 13 × 13 13\times13 13×13)(5次最大池化层)
    全连接层容易过拟合,且需要的参数量很大。 x x x y y y都变成了原来的 1 32 \frac{1}{32} 321,也就是 13 × 13 13\times13 13×13(最后的特征图大小)
  • 1 × 1 1\times1 1×1卷积节省了很多参数
    【YOLO学习】从YOLOv1到YOLOv2的YOLO学习_第1张图片
  1. 在神经网络最后输出的特征图大小变成了 13 × 13 13\times13 13×13的,比v1的 7 × 7 7\times7 7×7要大,我们能够有更多的先验框可以去用。就是通过由原本的 416 × 416 416\times416 416×416变成了 13 × 13 13\times13 13×13每次下采样图片大小都变成原来的 1 2 \frac{1}{2} 21

Darknet19表示了有19个卷积层

  1. Darknet中的卷积核是借鉴了vgg的想法,使用一个 3 × 3 3\times3 3×3的卷积核去进行运算。

  2. 每次经过maxpooling卷积层的filter数(特征图的个数)都会翻倍,但因为经过了一个 1 × 1 1\times1 1×1的一个卷积核进行卷积又让特征图的个数少了2倍,省了几个参数的同时保持整体网络结构没有太大的影响。

YOLOv2聚类提取先验

  • 通常faster-rcnn系列选择的是先验比例都是常规的(定死的),但不一定完全合适其他的数据集
    所以在yolov2当中使用的就是K-means聚类算法进行先验框的提取

yolov1中我们选两个先验框(就是之前说的候选框),也就是 B = 2 B=2 B=2,相当于就是在 7 × 7 7\times7 7×7的网格中的每一个网格里都会有两个先验框,然后根据先验框进行回归微调先验框。在fast-rcnn中是按照一定比例给出了9种比例的先验框,但因为这个先验框是固定的,所以对于某些物体来说是不适用的。所以,在yolov2上就使用了k-means的聚类算法来对先验框进行选择

那么什么是聚类提取先验框呢?为什么呢?

聚类的问题其实就是一个分类的问题

为了能够提取出更加符合实际情况比例的先验框,我们就可以利用聚类进行一个分类,通过给定 k k k的值去得到聚出 k l kl kl堆,在每一个堆里选择一个样本中心,每一堆的中心点和w和h都是实际的值,每个堆都能选出一个样本中心,然后只要我们拿这 k k k堆里面的比例作为先验框就更加能够符合我们目前所使用的数据集,因为是直接在我们目前的数据集的基础上进行分类的。

【YOLO学习】从YOLOv1到YOLOv2的YOLO学习_第2张图片

而k-means聚类中的距离不是我们平时的欧氏距离,不太合适,因为框的大小不一,数值比较大,产生的差异也会比较大。结果导致我们分类出来的结果是跟框的大小有关误差也跟误差有关。所以就提出了一种新的计算距离的方式。
d ( b o x , c e n t r o i d s ) = 1 − I o U ( b o x , c e n t r o i d s ) d(box,centroids)=1-IoU(box,centroids) d(box,centroids)=1IoU(box,centroids)
只要 d d d的值越大,说明 I o U IoU IoU越小,就说明两个框的重合程度比较大,那么他们之间的距离就比较小了。这样就跟物体的大小无关了,也就是误差就不会因为框的大小而产生,从而能够得到更加精确的分类结果。通过聚类去选择先验框就能够获得更加准确的数据。
从图像上我们也可以看到,当 k = 5 k=5 k=5的时候是一个比较合适的取值,因为再往后平均的 I o U IoU IoU增加就不明显了,所以我们选一个最合适的即可。(如果k太大,导致我们会产生很多候选框,虽然可以提高准确率,但同时也会花费更多的时间去计算,导致速度变慢)

YOLOv2-Anchor Box

分清两个概念,识别准确和识别到了。识别准确是指框能够跟实际框有很好的重合。而识别到了是指预测框已经框到了物体,但不一定够准确,可能只是框到了一部分

  • 通过引入anchor boxes,使得预测的box数量更多( 13 × 13 × n 13\times13\times n 13×13×n)
  • 先验框不采用固定的比例

虽然先验框多了,但不是每一个先验框都能识别正确,所以准确率提升不大,但 r e c a l l recall recall高了,因为通过聚类算法进行先验框的选择之后,能够识别到原来识别不到的物体了,虽然能够识别到了,但重合程度不够高,有偏差用多个anchor作为先验框。

YOLOv2-Directed Location Prediction(偏移量)

之前去预测的时候,我们会预测 x , y , w , h x,y,w,h x,y,w,h x x x y y y表示中心点 w w w h h h表示长和宽。通过预测得到了 t x , t y , t w , t h t_x,t_y,t_w,t_h tx,ty,tw,th,这四个量表示中心点和长宽的偏移量,通过这些偏移量去修正框的位置,使预测框更好地和真实框重合。但这个时候又会产生一个问题,如果 t x , t y , t w , t h t_x,t_y,t_w,t_h tx,ty,tw,th过大,会导致偏移量很大,就更难去修正了。直接预测偏移量会导致框导致飘来飘去,网络就很难学到准确的位置,因为网络一开始什么都不会,是一些随机数,每一次都是随机的,导致模型很难收敛,模型不够稳定,特别是刚开始训练的时候。

所以在yolov2中,我们是通过直接预测他的相对位置就是不直接使用偏移量,而是选择相对grid cell的偏移量。

计算方式

【YOLO学习】从YOLOv1到YOLOv2的YOLO学习_第3张图片
由上图中, p w p_w pw p h p_h ph表示当前的一个先验框的长宽。现在我们需要进行偏移。 t x , t y , t w , t h t_x,t_y,t_w,t_h tx,ty,tw,th就是我们目前预测出来的偏移量。
目前对于 t x , t y t_x,t_y tx,ty,是以网格线相交的点作为他的相对位置(图上的红点),也就是说,他再怎么飘也飘不出由红点确定出的一个网格里。先给出计算公式:
{ b x = σ ( t x ) + c x b y = σ ( t y ) + c y b w = p w e t w b h = p h e t h \begin{cases}b_x = \sigma(t_x)+c_x \\ b_y = \sigma(t_y)+c_y \\ b_w = p_we^{t_w} \\ b_h = p_he^{t_h}\end{cases} bx=σ(tx)+cxby=σ(ty)+cybw=pwetwbh=pheth

注:网格以左上角为原点

我们对于预测出来的 t x , t y t_x,t_y tx,ty代入一个Sigmoid函数( y = t a n h ( x ) y=tanh(x) y=tanh(x))进行计算 (无论 x x x取多少,最后的 y y y取值会在 [ 0 , 1 ] [0,1] [0,1]之间)所以,最后预测出来中心点的位置就只会在由红点所确定的一个框里。而且,我们把一个格看成一个单位,现在预测出来的就是相对于网格的位置进行偏移

但由于这是相对的位置,我们需要把原来实际的位置给找回来,所以我们要加上 c x , c y c_x,c_y cx,cy c x , c y c_x,c_y cx,cy就是红点在网格中的实际位置(也就是坐标)。相当于就是把计算出来的相对位置映射回原始的图像当中

对于预测的 t w , t h t_w,t_h tw,th来说也是同样的思路,但由于预测出来的是一个对数值(?为什么是对数?),所以我们就用 y = e x y=e^x y=ex对其进行处理,映射回原来的坐标

  • 例:
    预测值向量 ( σ t x , σ t y , t w , t h ) = ( 0.2 , 0.1 , 0.2 , 0.32 ) (\sigma t_x,\sigma t_y, t_w, t_h)=(0.2,0.1,0.2,0.32) (σtx,σty,tw,th)=(0.2,0.1,0.2,0.32),anchor框为 p w = 3.19275 , p h = 4.00944 p_w=3.19275,p_h=4.00944 pw=3.19275,ph=4.00944
    (anchor框通过聚类得到的,属于已知条件)
    那么在特征图上的位置就是 { b x = 0.2 + 1 b y = 0.1 + 1 b w = 3.19275 e 0.2 = 3.89963 b h = 4.00944 e 0.32 = 5.52151 \begin{cases}b_x=0.2+1\\ b_y=0.1+1 \\ b_w = 3.19275e^{0.2} = 3.89963 \\ b_h = 4.00944e^{0.32}=5.52151\end{cases} bx=0.2+1by=0.1+1bw=3.19275e0.2=3.89963bh=4.00944e0.32=5.52151

那么要找到他在原始图片上的位置(因为要检测那要找回原来在图像上的位置,需要进行还原)就只需要乘上放缩的倍数就可以得到框在原来图像上的位置。因为在神经网络里面通过了5次池化,导致图像缩小了原来的32倍。

总结

通过以上方式就可以防止我们预测出来的框的位置会飘来飘去,就是预测出来的可能会超出图像的范围,框的位置飘忽不定,所以我们通过一些函数和公式的处理,可以把绝对位置的量转换成相对位置的量。

YOLOv2-Fine-Grained Feature

感受野

概述来说就是特征图上的点能看到原始图像上多大的区域。也就是感受野是描述特征图上的一个点包含了原图像上的多少信息,多少像素。就是看最终的特征图是相当于原始输入图像多大的部分

感受野就是特征图相当于原始图像的大小。可以理解为是一个浓缩的精华类似的。
感受野越大,特征图相对于原始图像上的大小就越大。


  • 这里的最终得到的一个点就相当于原来图像上的 5 × 5 5\times5 5×5的像素。
    【YOLO学习】从YOLOv1到YOLOv2的YOLO学习_第4张图片
    也就是一个点相当于原来的 5 × 5 5\times5 5×5

也就是如果感受野的范围越大,我们就能获取到图像上更多的信息随着卷积层层数增加,我们最后得到的特征图的感受野就越大,感受野越大,对应到原来图像上的范围越大,包含的信息就越多,就能识别更多、更大的物体。(因为卷 积层越多感受野越大,相当于获取到原始图像上的信息也多了)

感受野的卷积核大小

【YOLO学习】从YOLOv1到YOLOv2的YOLO学习_第5张图片
输入的是 5 × 5 5\times5 5×5那么进行卷积运算之后,用3个 3 × 3 3\times3 3×3,滑动步长为1,那么感受野就是 7 × 7 7\times7 7×7,上图是2个 3 × 3 3\times3 3×3的卷积核,那么感受野就是 5 × 5 5\times5 5×5了。那么此时产生了一个问题,我到底是拿多个小的卷积核(这里是 3 × 3 3\times3 3×3)进行多次运算之后得到特征?还是就直接用一个大的卷积核进行一次运算得到结果?我们可以计算分析一下。

  • 假设输入大小为 h × w × c h\times w\times c h×w×c,并且使用 c c c个卷积核(得到 c c c个特征图),我们可以计算一下各种所需要的参数。
    一个 7 × 7 7\times7 7×7的卷积核所需要的参数= C × ( 7 × 7 × C ) = 49 C 2 C\times(7\times7\times C)=49C^2 C×(7×7×C)=49C2
    三个 3 × 3 3\times3 3×3的卷积核所需要的参数= 3 × C ( 3 × 3 × ) C = 27 C 2 3\times C(3\times3\times) C=27C^2 3×C(3×3×)C=27C2

从上面的计算来看,堆叠小的卷积核所需的参数更少一些卷积过程越多特征提取也会更加细致,加入的非线性变换也随之增多,还不会增大权重参数的个数,这就是vgg网络的出发点,用小的卷积核来完成特征提取的操作。

特征层处理

随着我们神经网络卷积层的数量增加,感受野的范围会越来越大,然后就会导致,到达最后一层之后,感受野的范围就会很大,网络就会很容捕捉到物体比较大的,但就很有可能会导致会丢失掉了小目标。为了解决这个问题,我们可以把之前的一些特征进行融合

一般出现识别的时候对于目标比较大的物体比较准,而目标比较小的物体不准也是因为这个原因,所以一般都要进行特征融合。

  • 比如我们经过 c o n v 1 − > c o n v 2 − > ⋅ ⋅ ⋅ − > c o n v n − − > F e a t u r e d M a p conv_1->conv_2->···->conv_n-->Featured Map conv1>conv2>>convn>FeaturedMap 比如经过conv1之后得到的是 17 × 17 17\times17 17×17的感受野,而经过conv19之后的感受野是 26 × 26 26\times26 26×26,也就是说每次经过卷积层都会不一样的特征,那么,我们只要把每个层中得到的特征进行一个融合,就可以得到一个能够对各种大小物体都能够识别的网络。
    【YOLO学习】从YOLOv1到YOLOv2的YOLO学习_第6张图片
    大概的流程示意图如上
    流程:比如最后拿到的是 13 × 13 × 1024 13\times13\times1024 13×13×1024的一个特征图,然后把他前面的特征图,比如他的前一层的特征图大小是 26 × 26 × 512 26\times26\times512 26×26×512,然后我们对这一层特征图进行一个拆分,拆成 4 4 4 13 × 13 × 512 13\times13\times512 13×13×512的passthrough层,然后把这个跟原来最后得到的特征图进行一个拼接,得到的最后大小为 13 × 13 × 3072 13\times13\times3072 13×13×3072
    3072 = 4 × 512 + 1024 3072=4\times512+1024 3072=4×512+1024
    (这个部分相当于是对每次卷积之后进行一个下采样,然后把他们的特征进行一个融合)

这些步骤完成之后我们就可以得到一个既能够检测大物体也能够检测小物体的一个网络了

YOLOv2-Multi-Scale(多尺度识别)

我们实际的检测任务中可能会遇到许多不同大小的图片。所以,为了解决这个问题我们需要resize成不同大小的图片。因为在yolo网络中已经没有了全连接层,所以输入网络的图片大小不受限制,我们可以通过训练不同大小图片来提高模型的泛化能力。能够提高对于各种大小的物体的识别准确率。

也就是我们每经过一定的迭代次数之后改变输入图片的大小,因为是经过5次的池化,每次池化图片大小减少 1 2 \frac{1}{2} 21,所以图片改变的倍数要是 32 32 32的倍数。
【YOLO学习】从YOLOv1到YOLOv2的YOLO学习_第7张图片
神经网络就是把图像上的信息进行一个浓缩,提取特征,也就是特征图中的一个点对应原始图像多大的区域。

以上就是yolov2中的改良和优化。

你可能感兴趣的:(YOLO学习,神经网络,python,卷积,网络,算法)