文章目录
一、目标定位
什么是目标定位和目标检测?通常我们遇到的三类问题:
- 图像分类
- 目标定位
- 目标检测
图像分类和目标定位是单物体的检测,而目标检测是多物体的检测。
通过卷积神经网络处理图像后,Softmax输出分类的类别,同时还需要输出bounding box的位置,框出目标物体。
- b x b y b_xb_y bxby是中心点坐标
- b h b w b_hb_w bhbw是框的高和宽
现在来定义标签y:
y
=
[
P
c
b
x
b
y
b
h
b
w
c
1
c
2
c
3
]
y=\left[ \begin{matrix} P_c \\ b_x \\ b_y \\ b_h\\b_w\\c_1\\c_2\\c_3 \end{matrix} \right]
y=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡Pcbxbybhbwc1c2c3⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤
- P c P_c Pc是出现目标物体的概率,如果出现则1,未出现则0
- c i c_i ci是物品种类,在目标定位中只能出现一个1
举个例子来说明标签是怎样的
在第一幅图中,出现了检测目标,那么这幅图对应的标签是:
y
=
[
1
b
x
b
y
b
h
b
w
0
1
0
]
y=\left[ \begin{matrix} 1\\ b_x \\ b_y \\ b_h\\b_w\\0\\1\\0 \end{matrix} \right]
y=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡1bxbybhbw010⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤
第二幅图中,没有出现检测目标,那么这幅图对应的标签是:
y
=
[
0
?
?
?
?
?
?
?
]
y=\left[ \begin{matrix} 0\\ ?\\ ?\\ ?\\?\\? \\?\\? \end{matrix} \right]
y=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡0???????⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤
现在来定义损失函数:
L
(
y
^
,
y
)
=
∑
i
=
0
n
(
y
^
i
−
y
i
)
2
,
y
1
=
1
L(\widehat{y},y)=\sum_{i=0}^n (\widehat{y}_i-y_i)^2,y_1=1
L(y
,y)=i=0∑n(y
i−yi)2,y1=1
L ( y ^ , y ) = ∑ i = 0 n ( y ^ 1 − y 1 ) 2 , y 1 = 0 L(\widehat{y},y)=\sum_{i=0}^n (\widehat{y}_1-y_1)^2,y_1=0 L(y ,y)=i=0∑n(y 1−y1)2,y1=0
二、特征点检测
假设脸上有64个特征点,那么就会存在64个坐标,128个参数:
l
1
x
、
l
1
y
、
l
2
x
、
l
2
y
、
.
.
.
、
l
64
x
、
l
64
y
l_{1x}、l_{1y}、l_{2x}、l_{2y}、...、l_{64x}、l_{64y}
l1x、l1y、l2x、l2y、...、l64x、l64y.再输出一个0/1代表图片中是否是face.一共就是129个输出单元。
通过标注这样一些关键特征点,可以确定人物的姿态动作。
需要明确的一点是:特征点1的特性必须在所有图片中保持一致。比如特征点1就始终是右眼眼角,2始终是肩膀外侧…
人工标记了大量的数据集后,神经网络可以输出上述所有特征点,可以利用他们实现有趣的效果,比如判断人物的姿态动作,人物面部表情等等。
三、目标检测
我们拥有一个训练集,其中包含汽车图片和对应标签0/1,首先用卷积神经网络训练这个模型,使这个模型可以预测图片中有没有出现汽车。
训练完这个卷积网络,可以用它实现滑动窗口目标检测,接下来介绍著名的滑动窗口目标检测。
将红框输入卷积神经网络,判断红框中有没有汽车这一物体,随后滑动红框,直到遍历完整个图像的每个区域。这里滑动的红框就是窗口。
根据需求,可以调整窗口的大小。
思路:以固定的步长滑动窗口,遍历图像中的每一个区域,运行卷积神经网络,判断是否有目标物品。
缺点:滑动窗口目标检测有明显的缺陷,就是需要处理每一个裁剪出的小方块,计算成本太高!(为了解决这个问题,人们用简单的分类器如线性分类器替代卷积网络,由于分类器计成本很低,所以滑动窗口目标检测效果很好,然而卷积网络运行单个分类任务的成本就很高了)
幸运的是,现在已经有了很好的方法降低计算成本,大大提高在卷积层上应用滑动窗口目标检测器的效率。
四、卷积的滑动窗口实现
将全连接层转换为卷积层
滑动窗口如何在卷积上实现呢?
下图是将全连接层转换为卷积层后的图
在真实的图片中,存在与目标之外的的部分,我们用黄色填充上去,同样执行卷积过程,最后输出的结果是三维的四个方块。代表四个位置上检测出来是否存在目标物体。
这样做有什么好处?可能刚看完课程的小伙伴不能很快理解到【全连接层转卷积层】的妙处。这样做的妙处是利用了卷积过程的一致性,不需要分别划分四次图像,然后执行四次卷积网络,而仅仅只需要输入图片,一次性输出四个分割部分的预测结果。
五、Bounding Box预测(YOLO)
在目标检测的时候,会出现这样一个问题,预测到最好的框和真实框(ground true)之间仍然存在较大的差距,如下图。
有一种能得到精准边界框的算法是YOLO(you only look once),参考论文如下:
YOLO算法
用到图像分类和目标定位。
把如下的图片划分成9块,对每一块都做一次预测,能够得到目标物体在哪个小区域中。
每一个框都有一个标签y,标签的形式和目标定位中一致,含有八个参数(目标出现的概率0/1,框的位置,3个类别)
输出结果是
3
×
3
×
8
3\times3\times8
3×3×8,从正面看过去,每一条相当于上述中的标签y(8维),一共有9条,代表一共有9个标签。当然就能看出哪个区域包含目标物体咯!
训练过程其实就是从
100
×
100
×
3
100\times\ 100\times3
100× 100×3的图像映射到
3
×
3
×
8
3\times3\times8
3×3×8的标签。
注意一下,打标签的时候怎么判断物体是否在哪个格子中?看物体的中心点!也就是下图中的蓝色点。如果!一个物体存在于多个格子中,它也只能够属于一个格子!
YOLO好处:只需要执行一次卷积网络,效率很高,可以达到实时检测。相比滑窗,YOLO划分格子而避免了重复部分的运算。
现在考虑一个问题,如何编码指定框的位置?
y
=
[
P
c
b
x
b
y
b
h
b
w
c
1
c
2
c
3
]
y=\left[ \begin{matrix} P_c \\ b_x \\ b_y \\ b_h\\b_w\\c_1\\c_2\\c_3 \end{matrix} \right]
y=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡Pcbxbybhbwc1c2c3⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤
通常指定左上角(0,0),右下角(1,1)
b
x
=
0.4
,
b
y
=
0.3
,
b
h
=
0.5
m
b
w
=
0.9
b_x=0.4,b_y=0.3,b_h=0.5mb_w=0.9
bx=0.4,by=0.3,bh=0.5mbw=0.9
约定:
b
x
、
b
y
∈
(
0
,
1
)
,
b
h
,
b
w
∈
(
0
,
+
∞
)
b_x、b_y\in(0,1),b_h,b_w\in(0,+\infty)
bx、by∈(0,1),bh,bw∈(0,+∞)
六、交并比(IoU)
怎样评估目标检测的优劣呢?这里介绍并交比这样一个概念。
IoU:Intersection over Union
在这个图中,红色框是实际边界框,紫色框是预测边界框,并交比就是用 两个框的交集面积 比上 两个框的并集面积。
- 预测框和实际框重合,IoU = 1
- IoU >= 0.5,可以认为预测正确
(滑稽)不要把IoU理解成了I owe you(money).
七、非极大值抑制NMS
NMS: Non-Maximum Suppression
你的算法可能对同一物体做出多次检测,非极大值抑制可以确保你的算法对每个对象只检测一次。实质上就是输出概率最大的框,抑制概率大但是不是最大的框。
NMS算法
八、Anchor Boxes
在之前的算法中,都只能在一个框中检测一个物体,如果一个框中存在多个物体应该怎么做?
用两个不同形状的矩形框出物体的位置,这两个框称作Anchor
标签y发生了改变,如下所示
有两种情况Anchor Boxes处理不好:
- 一个格子中出现三个及以上的物体
- 一个格子中两种物体的Anchor Boxes形状相似
总结一下,Anchor Boxes就是为了处理一个格子中有多个物体的问题,但是实际上很少遇到,因为将图像划分为19x19时已经很难遇到这种情况了。通常遇到有高有宽的物体时会选择用Anchor Boxes,设置多个不同形状的Anchor Boxes。在YOLO后期有了更好的做法——k-means算法,将两类对象形状聚类,用它选择一组Anchor Box,这就是自动选择Anchor Box的高级方法。
在目标检测这一章中,我们学到了什么有关目标检测的构件?来总结一下。
目标定位、特征点检测、目标检测、卷积的滑动窗口实现、Bounding Box预测、交并比IoU、非极大值抑制NMS、Anchor Boxes
现在将目标检测的构件组合在一起,学习当前主流的目标检测算法——YOLO
九、YOLO算法
(一)构建训练集
给出一副图片如下所示
有三种类别的物品需要我们去检测
标签y的维度是3x3x16,因为用到了两种不同形状的anchor,如下所示:
y
=
[
P
c
b
x
b
y
b
h
b
w
c
1
c
2
c
3
P
c
b
x
b
y
b
h
b
w
c
1
c
2
c
3
]
y=\left[ \begin{matrix} P_c \\ b_x \\ b_y \\ b_h\\b_w\\c_1\\c_2\\c_3\\P_c \\ b_x \\ b_y \\ b_h\\b_w\\c_1\\c_2\\c_3 \end{matrix} \right]
y=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡Pcbxbybhbwc1c2c3Pcbxbybhbwc1c2c3⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤
对于蓝色的格子,没有出现目标物体,所以它的标签是:
y
=
[
0
?
?
?
?
?
?
?
0
?
?
?
?
?
?
?
]
y=\left[ \begin{matrix} 0 \\ ? \\ ? \\ ?\\?\\?\\?\\?\\0 \\ ? \\ ? \\ ?\\?\\?\\?\\? \end{matrix} \right]
y=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡0???????0???????⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤
对于绿色的格子,存在目标物体汽车,所以标签是:
y
=
[
0
?
?
?
?
?
?
?
1
b
x
b
y
b
h
b
w
0
1
0
]
y=\left[ \begin{matrix} 0 \\ ? \\ ? \\ ?\\?\\?\\?\\?\\1 \\ b_x \\ b_y \\ b_h\\b_w\\0\\1\\0 \end{matrix} \right]
y=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡0???????1bxbybhbw010⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤
最终得到的输出维度是3x3x16的。
(二)模型预测
最后跑一次NMS
(三)输出NMS
划分格子
-
如果用的anchor是两个,那么每个格子中会出现两个预测的边界框
-
抛弃低概率的框
-
对每个类别单独执行NMS算法处理预测结果是哪个类别的边界框
这就是YOLO目标检测算法,事实上是最有效的目标检测算法之一,包含了非常多精妙的设计。
十、候选区域(R-CNN)
R-CNN:Regions with CNN 带区域的卷积网络
这个知识点在吴恩达教程中是选学部分,因为使用频率不高,但是可以为以后的研究提供帮助。
我们可以用滑动窗口的方法遍历图像,看看图像中有哪些物品;我们也可以跑卷积网络,但缺点是很多没用的区域会浪费计算资源,降低效率。
R-CNN选出一部分窗口跑卷积网络,而不是全部遍历一遍。实现这个过程用到的是图像分割算法。图像分割的结果如下图所示。
R-CNN的缺点就是太慢了(得到候选框的聚类步骤仍然很慢),当然有相关工作改进这个算法,于是有了Fast R-CNN算法。
R-CNN算法逐一对区域进行分类,Fast R-CNN算法用到了【卷积的滑动窗口实现】(本文的第四大点)。参考论文如下:
还有研究人员继续改进算法,得到了Faster R-CNN算法,运用卷积神经网络而不是图像分割来获取候选框的色块。在速度上超越了前两个算法。
不过!Faster R-CNN再快,也比不上YOLO算法
R-CNN毕竟需要先选取候选区域,再分类,而YOLO可以一步到位,you only look once!
十一、题外话,总结!
- 那么,做个小小的总结吧!深度学习学到这里已经是2021年寒假的末尾啦,也就是2021.2.21,我从2020.11.30开始学习第一课,写下我的第一篇深度学习笔记。到这篇笔记的时候,已经结束了目标检测,也就是我本科阶段目前需要用到的知识,大概就是到计算机视觉这部分。这不代表我学习深度学习止步于此,我会继续学习深度学习体系的知识,包括之后的做NLP可能用到的循环神经网络RNN。按照目前的进度规划,我应该会带着这些理论知识,去大量应用和实践,其中包括:吴恩达老师准备的demo以及综合设计(儿童监护系统)中的深度学习作目标检测。
- 其实我知道要完成综合设计项目,能够好好读懂模型代码,查阅资料调试就能实现,但是我把实践这一板块放置在了后面,对我来说,更高优先级的工作应该是系统地去学习深度学习这套理论(也因为真正对这个领域好奇),包括看起来似乎最枯燥无味的第二三课(神经网络改进策略和机器学习策略),但事实上非常能培养我在深度学习方向的思考方式。
- 还是那句话,按照我自己的进度规划,我目前会带着我学到的理论知识去大量实践,实现这些理论的东西,可能不久后再回过头来看,我对这些理论知识又有了更深的洞察。我对机器学习的热爱不止于此,我期待未来可以真正对这个领域有一定的理解!
- 最后,感谢吴恩达老师和一直坚持的自己 ~ Never stop