更新:
data:2021.8.25
note:
🕐之前Yolov3的解释有问题,重新学习更改内容
🕐加入了Yolov3的评价指标
一、机器视觉任务
按照上课老师讲的,目前的机器视觉有以下这四大任务,目前我学到了物体检测这一块,之后的语义分割和实例分割还没学,所以以下的笔记都是从0开始的检测任务相关笔记,干货满满
二、分类任务和检测任务的区别
分类任务:简单的对一个对象进行识别
但是对于有多个物体的图像,分类很明显不能够满足我们所需要的识别
检测任务:可以对多个对象进行识别
三、检测任务
1.目标定位
Bounding box
学习检测任务之前,咱们先学习一个小玩意儿,叫BBOX,也就是Bounding box
首先在检测任务里面有一个非常重要的概念——Bounding box
检测任务之所以叫检测任务,是因为我们要检测出图像中的物体的类别和位置,而为了标出这个位置,我们就需要用上这个Bounding box,其作用是为了能够圈出图像的位置。
一般有三种定义Bounding box
- 左上角和右下角的坐标画出一个Bounding box
- 中心坐标、图像长、宽画出一个Bounding box
- 中心坐标、图像长、宽再加上一个旋转角度alpha画出一个Bounding box
这个概念是不是超级简单,但是这个简单的概念也是检测任务的基础
单个物体进行目标定位
了解了最基础的什么是bounding box之后,我们继续往后走。
按照我们之前分类任务的思维,我们如果要在一张图片里面找到一个物体,识别出这一个物体,并且对他进行定位,我们可以怎么来实现呢?
分类图片很简单,我们只需要将这一个图片经过卷积神经网络,最终让全连接层(或者其他)输出一个类别里面最可能的那一种类别,我们可能用softmax进行判断,亦或者是其他方法进行判断,但无论如何,这个是简单可以能够实现的。
那我们怎么把这一个物体进行定位呢,其实道理也很简单,我们只需要让图片经过网络,让这个网络还能输出我们需要寻找的那一个物体的中心点座标(X,Y),以及图片的长度和高度,那么这样我们就可以实现一张图片中一个物体的检测了。用所学的一张PPT来举例子如下:
可以看到,最后的神经元节点,也就是我们的分类个数是14个,其中10个是10种物体的类别,剩下的4个就是该物体的座标。我们的卷积神经网络的Loss只需要定义成Multitask Loss即可,至于这个混合损失要怎么具体用数学形式来表达,你可以用图上的单纯相加,也可以使用其他的数学方法来定义。
多个相同种类物体进行目标定位
解决了如何对一个单个物体进行定位,那么如果一张图片上有多个物体,我们需要如何进行定位呢?
方法其实很简单,我们要做的其实就是简单的增加一下最后输出的神经元个数,让其输出的类更多,这样就解决了多个相同种类物体的定位。
但是,这样的方法有很明显的缺点
- 多个物体的时候,你的多个物体在图片中的长度和宽度是不固定的,这样的训练如何进行呢?
- 多个物体,这个多个两个字要怎么体现在你的输出上面呢?你并不知道你一张图片具体有多少个对象,如何规整化呢?
- 对待多类别物体的时候你就没法了
不太一样的bounding box
为了解决这些问题,我们其实是用这样的输出信息来放在我们圈出一个物体的bounding box里面
[Pc,bx,by,bh,bw,c1,c2,c3…]…
或者能把很多物体放到一起
[Pc,bx,by,bh,bw,c1,c2,c3…,Pc2,bx2,by2,bh2,bw2,c1,c2,c3…,…]
注意:这里需要先行说一个概念,我们后续的识别,就相当于是在整个图片里面取出了一个小图片,然后用这个小图片来进行我们的目标检测和识别,从而组成整张图片,而这一个小图片,我们就可以看成是我们现在进行的这些步骤处理图片。
解释
- Pc代表了你这个图片里面含有你需要检测物体的概率,你可以设置一个阈值,当Pc小于一个值的时候,后面的数据我都不关心了。
- bx,by,bh,bw是你图像里面识别出来的物体的位置信息
- c1,c2,c3…代表了你有多少类物体需要去识别
以上所有的方法就是对物体的一个定位了,当然也包含了一些对最终目标图片的检测
目标检测
因为我们的目的是要实现对一张图片里面的多个物体,多种物体进行识别,并且标注其位置
所以我们如果只把一张图片输出去,就会出现在目录<多个相同种类物体进行目标定位>里面出现的各种缺点。
针对这种情况,我们的目的就是需要尽可能把图片中含有我们物体的那一小块图片给拿出来,放到卷积神经网络里面,输出[Pc,bx,by,bh,bw,c1,c2,c3…],从而实现物体的识别和定位。
先从最开始,也是最简单的方法开始说起。
Sliding window(滑窗法——简单粗暴进行检测任务)
在以前那个分类任务到检测任务的过渡时期,我们使用的是滑动窗口模式进行检测任务
设计一个窗口,从图像的左上角开始,设计步长以及窗口大小,进行滑动,最终滑动到图像的右下角,这样我们只需要将每一个窗口进行分类任务,不识别他的位置信息,因为位置信息已经蕴含在了每一个滑动的窗口中,我们只需要将滑动窗口的位置信息放进去输出的信息即可。
Selective Search(选择性搜索)
因为有以上的缺点,所以早期研究人员研究出了Selective Search(选择性搜索)——可以较为高效的查找可能存在的物体的region。这一种方法按照一位博主的说法就是
是通过简单的区域划分算法,将图片划分成很多小区域,再通过相似度和区域大小(小的区域先聚合,这样是防止大的区域不断的聚合小区域,导致层次关系不完全)不断的聚合相邻小区域,类似于聚类的思路。这样就能解决object层次问题。
因为博主的实力有限,没有去仔细了解这一部分的知识,并且当前深度学习用的是另外一种方法来找含有我们物体的候选窗口,也就是利用神经网络来实现滑动窗口来找到物体,具体请往后面慢慢看,需要了解选择性搜素的朋友们,可以移步去看看上面引用里面给出的博主的博客。
卷积网络上实现滑动窗口
但是之前的算法都有缺点,计算速度和算出来的窗口的准确度都是问题
于是就有了,利用卷积网络来实现滑动窗口的方法。
先提前将吴恩达老师的教深度学习的视频链接放出来,真的教的很好,大伙可以结合学习
吴恩达深度学习_deeplearning
接下来就来说说如何用卷积网络实现滑动窗口
首先,我们得先知道,如何用卷积来代替全连接层,答案其实很简单,全连接的输出有多少类(神经节点),那么我们只需要使用同样多的个数的卷积核就可以实现这一种功能。
吴老师在视频里面介绍,由第一行的5516到全连接层的400个神经节点,我们只需要5 * 5的400个卷积核即可以实现这一个功能。
然后就是卷积实现神经网络的重点
先放上吴老师的图,可以看到,整个过程用三行就可以来表达。按照博主我的理解,在第一行里面,14* 14* 3的图片,通过卷积,池化,全连接(或者卷积代替)最终变成了1* 1* 4的一个图片
当我们抛开通道数,即单论一个1 * 1的时候,我们就可以认为这一张14 * 14的图片信息被映射到了那个1 * 1的小格子上面,包括他的类别,bx,by,bw,bh或者其他更多的信息。
那么如果填充成一个16 * 16,或者是直接用一张16*16的图片,我们经过同样的卷积,池化,全连接(或者卷积)之后,我们得到的就是一个2 * 2 * 4的一个结果,那么根据计算的过程其实我们可以得到,其实这一个2 * 2的结果就是对应了我们用14 * 14 * 3 的一个window,步长为2(步长其由池化层的步长来决定,池化层步长为2 * 2,故Slind window的步长为2),进行滑动,左上角的蓝框其实就是代表了原图象中的蓝框区域,这样,移动了两个步长之后的图片结果信息就被放到了2 * 2的右上角的里面,以此类推。
再转换到28 * 28 * 3的图片中来,不难可以推理得到,只要使用的是同样的卷积网络,那么都到的结果,都可以理解成一个14 * 14 * 3的一个滑块对图象进行滑动从而得到的结果。
优点
- 这一种方法显著提高了运算速度,因为通过卷积网络只需要一套参数,不需要多套
- 显著提高运算速度的原因是——观察卷积过程,你可以很明显的发现,不同的window(或者说是bounding box)之间是共享了彼此共同拥有的那部分数据的计算结果的,这是最重要的原因
- 利用卷积神经网络的监督学习特性,可以得到较好结果的信息特征,对后续有明显帮助(这一个优点其实就是yolov3的特点,即one stage,只需要通过这一个神经网络即可以输出结果)
2.边界框预测
在上一步里面,我们已经可以利用卷积网络实现滑动窗口了,但是只用sliding window是没有办法把物体有效的筛选出来的,这就需要下我们在每一个滑动的窗口里面找到我们需要的那一个物体,这个找的过程,就是我们的边界框预测。
大致的过程其实就是利用我们之前的卷积层,让滑动窗口的每一个经过卷积网络,最终输出物体的分类信息,位置信息。
因为我们是用卷积输出我们的结果,所以我们在训练的时候,就需要人为给定数据集,其中数据集的信息就需要有这个图片的分类信息和位置信息,即前面所说的[Pc,bx,by,bw,bh,c1,c2…],也就是前面那一章对多个物体进行定位的那里面的内容。
但是这一种方法有一种情况是没办法解决的
我们没有办法预测横跨了多个窗口的一个物体,这个在yolov3的anchor boxes里面得到了解决,请大伙继续往后看。
3.交并比(Intersection Of Union or IOU)
在训练一个模型的过程中,我们需要观察我们预测的这一个物体的边框和实际训练集中的真实值之间是否一致,即你想要让你的模型定位出来的边框就是真实的物体边框。但计算机是不能去肉眼观察到底是否一致,所以就需要这么一个IOU的概念来进行说明。
从名字交并比其实就已经很清晰的说出来了这个概念是什么,即交集在并集中的占比,结合图形来说就是你预测出来的值,和实际真实值之间有多少部分是重合在一起的。
在上面的图中,就是IOU = 黄颜色(交集)/绿颜色(并集)
在现在运用中,当IOU>=0.5的时候,它就基本上是把物体给框出来了,而这一个0.5并没有数学依据,就是说0.5是人为的主观约定俗成的东西说IOU>=0.5,就可以认为两者几乎重合了,也就是训练结果不错了。当然,你想要更加准确的框的话,可以把0.5改大到0.6,0.7…等等。
4.非极大值抑制(Non-max Suppression or NMS)
在你的输出结果中,可能对同一个物体有许多个框框出来,但是每一个框的准确率都不一样,或者说是IOU不一样,为了让我们对一个物体只有一个框,把其他多的BBOX的去掉,这就需要我们用到NMS算法来进行,它的含义就是能够把预测效果最好的那个值给输出,而其他预测效果不佳的那些Bbox就抑制下去,消除掉。
大致的过程如下:
我们先输出了很多个Bbox,然后我们按照Bbox的大小顺序进行排序。
我们可以发现,我们是利用IOU进行比对,其目的就是为了确定两个BBOX识别出来的物体到底是不是同一个物体,从而能得到更加准确的分辨结果。也可以抑制对同一个物体的反复识别,标框。
5.锚框(anchor box)
在前面我们提到了,如果一个物体横跨了多个框,那么我们对该类物体的寻找的效果就会极差,在yolov里面提出的anchor box这个概念,就较为有效的解决了这一个问题。其实其中的思想和Slinding window的思想是一致的。
锚框是什么
在一张图里面,我们对一个小方格里面设置N个不同长宽比的框,这N个框就是我们所定义的锚框。
当然,还有一个概念是锚点,即我们在这些小方格中设置的不同长宽比的框是需要一个中心点的,而这个中心点就是我们所说的锚点,在yolov3中,这个锚点是我们可以用k-means聚类进行计算出来的
k-means聚类算法我没有具体深挖,大伙可以看下面这篇博客继续学习一下
YOLOV3中k-means聚类获得anchor boxes过程详解
四、Yolov3(You only look once)
有了上面的基本知识,我们就可以开始把学习Yolov3了
先解释一下什么是Feature Map,其实跟着前面的学习,Feature Map就是把图片通过神经网络映射成n * n的这一个过程,然后在每一个小的Feature Map上(其实就是滑动窗口的思想)进行后续操作。
Yolov3其实分成了三种Feature Map,也就是将图象分割成了三种类型,分割的每一个Feature Map越小,那么上面可以蕴含的物体特征也就可以越大,在每一种Feature Map上都使用锚框的思想,这样就可以避免一个物体被切割的情况。
再解释一下如何锚框、锚点
我们说了这么久的锚框,但是一个框总有一个中心点把,那这个中心点是什么呢?怎么选取呢?
其实这个中心点就叫做锚点,也就是以该点为中心,选取不同长宽比的框作为锚框。
那选取的锚点是什么呢?锚点其实就是我们Feature Map上的每一个点。即你的图片经过神经网络之后得到的3种不同尺寸的图片中的每一个点。
整个算法的大致过程如下:
首先将一个图片变成416 416 3,经过卷积神经网络
也就是前面这几层。会经过多次卷积、池化最终来到输出第一次Feature Map这一个地方,输出一次Feature Map之后继续卷积、池化,输出第二次Feature Map,然后同理第三次输出Feature Map。
在输出了Feature Map之后,每一个Feature Map上的每一个点都是锚点,然后根据我们在yolov3的参数文件配置里面设定的锚框长宽比,对每一个锚点的锚框进行后续计算。
后续的计算简单的理解就是把锚框经过神经网络,最终预测得到每个锚框中物体的数据,即输出的类型就是每个锚框的[Pc,bx,by,bh,bw,c1,c2,c3…]…**,输出的结果的含义见上面的说明。
然后经过IOU,NMS这些算法,将一些重复的框给取出掉。
结合一些其他算法向后降低损失,使得我们的衡量标准的准确率上升,最终得到一个理想的模型。
其实yolov3就是上面一个一个知识点结合起来最终形成的。
大伙也可以多看看其他博客的介绍,看看具体的网络是怎么定义的等等。
评价指标
针对一个模型,我们需要用各种评价指标来评定这一个模型是好还是坏。或者是训练的效果是否可以使用,在yolov3里面就有一些用来定义的各类指标
TP,TN,FP,FN
用来考察分类器的分类效果的指标
我们用GT Box表示Ground-Truth(GT)Box即实际标注的真实区域框,用Predicted Box表示你预测出来的物体区域
那么我们这么定义TP,TN,FP,FN
当符合以下标准可以
TP:predicted box中分类到该类别,并且正确的物体数量
FP:predicted box中分类到该类别,但是错误的物体数量
FN:数据集中该类别中还剩下的没有被识别出来的物体的数量
TN:不属于该类别,并且没有被分到该类别的物体的数量
Precision(精度)
Recall(召回率)
用例子来理解一下
当第一个物体被识别出来的时候,此时分类正确,TP为1,数据集中还有4个待检测物体,即真实物体未被分类,故FN=4,可以算出Precision 和 Recall
PR曲线
当我们算完了这一个表格的时候,为了更加直观,我们将这个图象给画出来,横坐标召回率Recall,纵坐标为准确率Precision。
AP(Average Precision)
为了更进一步呈现这一个模型的优劣,我们又有了一个AP的概念,即PR曲线的面积,但我们一般会对PR曲线做一个平滑化的处理,让其更容易计算出面积,操作如下
mAP(Mean Average Precision)
针对我们识别多个物体,我们需要对多个物体求平均值来观察模型是否优秀。
后面是打算后续继续往后写的R-CNN已经Fast R-CNN Faster R-CNN,这都是在目标检测的发展过程中非常重要的一部分。
并且,我们可以看一组计算速度
可以发现YOLOV3的计算速度可以用极快来形容,甚至可以用yolov3来实现实时检测视频。但是相应的正确率也下降了,在现在的实际应用中,RCNN也有使用的情况。虽然RCNN的运算速度不如yolov3,但是其准确率很高。
剩下的这一个部分,留到后面继续写了
由Sliding window–>R-CNN
R-CNN --> Fast R-CNN
Fast R-CNN --> Faster R-CNN
RPN工作机理
结语
如果文章中有错误,或者不合理的地方,欢迎大家提出,小白新手上路,希望和大家一起学习一起进步
参考资料
学习的Pytorch-YOLOV3代码 ——https://github.com/eriklindernoren/PyTorch-YOLOv3
吴恩达老师的深度学习网站——https://blog.csdn.net/qq_42109740/article/details/105740704