本篇博客是我学习某位up在b站讲的pytorch版的yolov3后写的,
那位up主的b站的传送门:
https://www.bilibili.com/video/BV1A7411976Z
他的博客的传送门:
https://blog.csdn.net/weixin_44791964/article/details/105310627
他的源码的传送门:
https://github.com/bubbliiiing/yolo3-pytorch
侵删
本片博客主要是理清楚yolov3的一个整体框架
从下面这幅图说起
图片来源于b站某位up主的博客:https://blog.csdn.net/weixin_44791964/article/details/105310627
这幅图主要是可以划分为左边虚线框的部分和右边虚线框以外的部分,左边虚线框的部分是yolov3的主干提取网络,名为darknet-53,主要目的是通过下采样来进行特征提取。
过程如下:
首先我们输入一张416x416的图片,也就是虚线框内的inputs框,如果输入的图片不是416x416的,那么首先我们需要将图片调整为416x416的大小,此时调图片大小不是简单的对图片进行拉长或者收缩,而是在图片边缘加上灰条,如下:
图片来源于b站某位up主的视频截图:https://www.bilibili.com/video/BV1A7411976Z
调整完图片的大小之后,就顺着箭头的顺序对图片进行特征提取,这个特征提取的方式就是一系列卷积的过程,图片变化顺序为416x416x3–>416x416x32–>208x208x64–>104x104x128–>52x52x256–>26x26x512–>13x13x1024,从这个变化顺序可以看出来,图片的宽和高是一直在减小的,通道数在不断的增加,这样一个过程就是下采样的过程。获取的这些层就是特征层,这些特征层就可以反应输入进来的图片的特征
下一步操作就是需要将最后三层提取出来传入到虚线框的右边。
至于为什么是最后三层呢?
这个就需要科普一下yolo的知识了,如下:
对于我们的电脑而言,要识别出下面图片中的猫,首先需要知道猫的位置,那就需要知道四个参数:中心点的x轴坐标、中心点的y轴坐标、框的宽、框的高
图片来源于b站某位up主的视频截图:https://www.bilibili.com/video/BV1A7411976Z
那么如何确定上面四个参数呢?首先我们输入一张图片,然后将图片调整为416x416的大小,然后将图片划分为13x13、26x26、52x52的网格,13x13用于检测大物体,26x26用于检测中等大小的物体,52x52用于检测小物体,由于猫是一个比较大的物体,所以我们就使用13x13的网格来检测,如下图:
图片来源于b站某位up主的视频截图:https://www.bilibili.com/video/BV1A7411976Z
每个网格点获得其右下角的检测区域,如果物体的中心点落在这个区域,那么这个物体的位置就由这个网格点来确定。
比较敏感的小伙伴可能已经看出来了,我们划分的网格大小不就是最后三层特征层的图片的大小吗?讲到这里可能部分小伙伴已经明白了,我们就是将最后三层特征层,按照其图片大小,将图片画上和其图片大小相对应的对应的网格。然后通过网格(就是上面说的方法)来确定物体的位置。
然后接着讲,我们将最后三层传到虚线框右边的过程。
首先从最下面的13x13x1024讲起
顺着箭头,这个13x13x1024的特征层被传到了右边的框,进行了5次卷积,然后再次顺着箭头,就有两个方向。
其中指向红色框框的那边表示进行分类和回归预测。如何来理解这个分类和回归预测呢?
这个分类和回归预测其实就是进行了两次卷积,将图片化为了13x13x75的大小,这个13x13x75就可以分解为:13x13x3x25。13x13x3x25又可以分解为:13x13x3x(20+1+4)。
13x13表示:将我们的图片划分为了13x13的网格。
3表示:每个网格都存在着三个先验框,这个先验框就是我们预先标注在图片上的,我们的预测结果就可以预测我们的先验框内部是否真实的包含物体。如果真的包含有物体的话,就会判断这个物体的种类,然后还会调整这个先验框的中心和宽高,把他们调整到正确的位置上。其实我们的yolov3的预测结果,其实就是对我们的先验框进行一个判断,判断其内部是否真实包含有物体,判断其内部包含的物体的种类,判断这个先验框需要怎样进行调整。所以,如果我们认为的某个先验框内部是真实包含物体的,经过上面的一系列判断,就可以找到预测框的位置以及判断出物体的类别,然后就可以把预测框画出来了。
20+1+4表示:首先是20,因为这个yolo在测试的时候用的是voc的数据集,这个数据集有20个种类,这里的20其实代表的是20个种类的概率。1表示这个先验框是否包含有物体。4表示我们要调整这个先验框,需要有4个参数。
所以嗷,这个红色框框里面进行的两次卷积,实际上就是判断我们的先验框内部是否包含有物体,判断这个物体的类别,然后判断调整先验框需要用到的参数。
另外一个方向就是图中的向上传了。wdnm傻逼实验室,叫老子写博客,检查nm。另外一条路径就是将我们5次卷积之后的结果进行一次卷积+上采样,其得到的结果是:26x26x256。然后这个结果会顺着箭头继续往上传,此时的26x26x512的特征层也会向右传递,两者相遇,进行堆叠,得到一个26x26x768的结果。这个过程其实就是一个构建特征金字塔的过程(特征金字塔可以进行多尺度特征融合,提取出更有效的特征,更好的的特征,可以进行更好的预测),其实就是进行连接。堆叠后的结果顺着箭头向右传递,进行了五次卷积(和上面提到的五次卷积作用是一样的)。卷积完毕之后,又是两条路可以走。
其中一条走向了红色框框,进行一个3x3的卷积和一个1x1的卷积,进行分类和回归预测。这里卷积之后的结果是26x26x75,和上面的分解类似,这里分解之后就是26x26x3x(20+1+4),这些数字所代表的意思和上面的一样。判断先验框内部是否包含有物体,判断物体的类别,调整先验框的位置。
另一条走向了上方,进行了卷积+上采样,得到52x52x128的结果,然后顺着箭头向左传递,此时52x52x256的特征层也会向有传递,两者相遇,进行堆叠,和上面一样,得到52x52x384的结果。然后顺着箭头往上传递,进行卷积,得到52x52x128的结果,然后向右传递至红色框框,进行3x3的卷积和1x1的卷积,得到52x52x75的结果,同理进行分解得到52x52x3x(20+1+4),这些数字所代表的意思和上面的一样。判断先验框内部是否包含有物体,判断物体的类别,调整先验框的位置。
总结一下,其实这个就是将我们输入进来的图片划分为了不同大小的网格,每个网格含有三个先验框,然后判断先验框内部是否包含有物体,判断物体类别,调整先验框,画出预测框。