深度学习第四课——目标检测(week 3)
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
目录
三、目标检测
图像分类遍历所有图片判断是不是汽车
定位分类不仅要判断是不是汽车还要判断出他的位置
多个对象多个对象时如何检测并判断位置如不仅要检测汽车还要检测人和障碍物
所以图片分类的思路可以帮助学习分类定位而对象定位的思路又有助于学习对象检测
3.1 目标定位
例如输入一张图片到多层卷积网络他会输出一个特征向量并反馈给softmax单元来预测图片类型。如果在构建一个自动驾驶系统那么对象可能会包括行人、汽车、摩托车、背景
如果还想定位汽车的位置我们可以让神经网络多输出几个单元输出一个边界框也就是多输出四个数字标记为 bxbybhbw这四个数字是被检测对象边界框的参数化表示。
先约定图片左上角为0 0右下为1 1边界框中心点坐标为bx by高度为 bh宽度为bw
本例中bx=0.5 by=0.7bh=0.3 bw=0.4
目标标签Y 的定义如下
他是一个向量第一个组件Pc表示是否含有对象即如果对象属于前三类则Pc=1如果是背景则Pc=0。可以这样理解Pc他表示被检测对象属于某一分类的概率背景分类除外如果检测到对象就输边界框参数bxbybhbw 如果Pc=1则输出c1c2c3表示该对象属于1-3的哪一类
训练神经网络的损失函数其参数为类别Y 和网络输出Y^ 损失函数可以表示为LY^ Y
这里假设平方误差的损失函数Y=0时就不需考虑除Pc之外其他的了只有Y1。而实际中可以不用对c1、c2、c3 和 softmax 激活函数应用对数损失函数并输出其中一个元素值通常做法是对边界框坐标应用平方误差或类似方法对Pc应用逻辑回归函数甚至采用平方预测误差也是可以的
结果证明利用神经网络输出批量实数来识别图片中的对象是个非常有用的算法。
3.2 特征点检测
概括的说神经网络可以通过输出图片上特征点的x y坐标来实现对目标特征的识别。
假设正在构建一个人脸识别应用希望算法可以给出眼角的具体位置可以让神经网路最后一层多输出两个数字 lx 和 ly作为眼角的坐标值如果想知道两只眼睛的四个眼角的位置那么从左到右依次用四个特征点来表示这四个眼角对神经网络稍做修改输出第一个特征点l1x l1y第二个特征点l2x l2y依此类推。这四个脸部特征点的位置就可以通过神经网络输出了。
还可以根据嘴部的关键点输出值来确定嘴的形状从而判断人物实在微笑还是皱眉也可以i提取鼻子周围的关键特征点
为了便于说明可以设定特征点的个数假设脸部有64个特征点有些点甚至可以帮助你定义脸部轮廓或下颌轮廓。选定特征点个数并生成包含这些特征点的标签训练集然后利用神经网络输出脸部关键特征点的位置。
具体做法是准备一个卷积神经网络和一些特征集将人脸图片输入卷积网络输出1或01表示有人脸0表示没有人脸然后输出l1x l1y。。。直到l64x l64y。这只是一个识别脸部表情的基本构造模块。
AR增强现实帮助解决其他如脸部扭曲头戴皇冠等问题当然为了解决这些问题需要一个标签训练集即X 和 Y的集合这些特征点都是认为辛苦标注的
最后还可以标注胸部、肩部等部位的中点来确定人体姿态。然后通过神经网络标注任务姿态的关键特征点再输出这些标注过的特征点就相当于输出了人物的姿态动作 当然要实现这些需要设定这些关键特征点从胸部中心点l1x l1y一直往下直到l32x l32y。
而标签在所有图片中必须保持一致比如特征点1始终是右眼的外眼角特征点2是右眼的内眼角等等这就是特征点检测。
3.3 目标检测
采用基于滑动窗口的目标检测算法通过卷积网络进行对象检测
假设想构建一个汽车检测算法步骤是首先创建一个标签训练集也就是X和Y表示适当剪切的汽车图片样本出于我们对这个训练集的期望一开始就可以使用适当剪切的图片就是整张图片X几乎都被汽车占据。可以照张照片然后剪切剪掉汽车以外的部分使汽车居于中心位置并基本占据整张图片有了这个标签训练集就可以开始训练卷积网络了。
输入这些适当剪切过的图像卷积网络输出Y 0或1 表示有没有汽车训练完这个卷积网络就可以用它来实现滑动窗口目标检测。
具体做法假设这是一张测试图片首先选定一个特定大小的窗口比如图片下方这个窗口红色小方块将这个小方块输入卷积网络卷积网络开始预测即判断红色方框内有没有汽车
滑动窗口目标检测算法接下来会继续处理第二个图像继续输入给卷积网络然后处理第三个图像依次重复
直到这个窗口滑过图像的每一个角落为了滑动的更快这里选用的步幅比较大思路是以固定步幅滑动窗口遍历图像的每个区域把剪切后的小图像输入卷积网络对每个位置按0或1进行分类这就是所谓的图像滑动窗口操作
重复上述操作不过这次选择一个更大的窗口截取更大的区域并输入给卷积网络处理可以根据卷积网络对输入大小的要求调整这个区域再以某个固定步幅滑动窗口重复以上操作遍历整个图像输出结果
第三次也选用一个更大的这样一来无论汽车在哪个位置总有一个窗口可以检测它希望卷积网络对该输入区域的输出结果为1说明网络检测到图上有辆车这种算法叫做 滑动窗口目标检测
因为我们以某个步幅滑动这些方框窗口遍历整张图片对这些方形区域进行分类判断里面有没有汽车滑动窗口目标检测算法也有很明显的缺点就是计算成本因为图片中剪切除太多的小方块了卷积网络要一个个处理如果选用的步幅很大显然会减少输入卷积网络的窗口个数但是粗粒度可能会影响性能反之如果采用小粒度或小步幅传递的小窗口会特别多意味着超高的计算成本
所以在神经网络兴起之前人们通常采用更简单的分类器进行对象检测比如简单的线性分类器至于误差因为每个分类器的计算成本都很低他只是一个线性函数所以滑动窗口目标检测算法表现良好是个不错的算法。然而 卷积网络运行单个分类任务的成本却高很多像这样滑动窗口太慢了除非采用超细粒度或极小步幅否则无法准确定位图片中的对象
不过现在已经有了解决方案
3.4 卷积的滑动窗口实现
如何在卷积层上应用这个算法
为了构建滑动窗口的卷积应用首先要知道如何把神经网络的全连接层转化成卷积层
假设对象检测算法输入一个14×14×3 的图像过滤器是 5×5 16个输出 10×10×16 然后通过参数为2×2 的最大池化操作图像减小到 5×5×16然后添加一个连接400个单元的全连接层接着再添加一个全连接层最终通过softmax单元输出Y有4个数字表示Y分别对应softmax单元所输出的4个分类出现的概率
下面要演示的就是如何把这些全连接层转化成卷积层
到第一个全连接层我们可以用5×5×16的过滤器来实现数量是400个输出结果为1×1×400我们不再把它看作一个含有400个节点的集合而是一个1×1×400的输出层从数学角度看它和全连接层是一样的因为这400个节点中每个节点都有一个5×5×16的过滤器所以每个值都是上一层上这些5×5×16激活值经过某个任意线性函数的输出结果。我们再添加另外一个卷积层这里用1×1卷积有400个所以下一层的维度是1×1×400它其实就是上个网络中的这一全连接层最后经由1×1过滤器的处理得到一个softmax激活值最终得到这个1×1×4的输出层而不是4个数字。
掌握了卷积知识再看看如何通过卷积实现滑动窗口对象检测算法。
假设向滑动窗口卷积网络输入14×14×3的图片神经网络最后的输出层即softmax单元的输出是1×1×4
现在给这个输入图片加上黄色条块在最初的滑动窗口算法中你会把这片蓝色区域输入卷积网络生成0或1分类接着滑动窗口步幅为2个像素将这个绿色区域输入卷积网络得到另一个标签0或1继续将橘色区域输入卷积网络得到另一个标签最后对右下的紫色区域及逆行最后一次卷积
我们在这个16×16×3小图像上滑动窗口卷积网络运行了4次于是输出了4个标签结果发现这4次卷积操作中的很多操作都是重复的。
这时得到的输出层为2×2×400然后应用1×1过滤器得到2×2×400再一次全连接操作最终得到一个2×2×4的输出层。最终输出层的4个子方块中蓝色的是图像左上部分14×14的输出右上角方块是图像右上部分的对应输出依次都是。具体计算以绿色为例如下所示
也就是说用四个小的计算代表大区域的计算其中共有区域还可以共享很多计算这就是全连接层转化为卷积层的好处
更大的例子输入一个28×28×3的图像最后得到8×8×4的输出首先在左上角14×14区域应用滑动窗口对应输出层左上角 接着以步幅为2不断向右移动然后向下移动。因为最大池化为2×2相当于以大小为2的步幅在原始图片上应用神经网络
MAXPOOLING之后滑窗每移动一格相当于MAXPOOLING之前滑窗移动两格因为MAXPOOLING可以看成把四个小方块合成一个了
总结一下滑动窗口的实现过程在图片上剪切出一块区域假设大小是14×14把他输入到卷积网络继续下一块重复操作直到某个区域识别到汽车正如上面看到的我们不用依靠连续的卷积操作来识别图片中的汽车。
比如我们可以对28×28的整张图片进行卷积操作一次得到所有预测值如果足够幸运神经网络便可以识别出汽车的位置
以上就是在卷积层上应用滑动窗口算法的内容它提高了整个算法的效率不过仍有一个缺点就是边界框可能不够准确
这个算法将原本需要一个个输入的现在通过卷积计算将一张图片每次的window同时进行卷积最终得到的就是结果
3.5 Bounding Box预测
下面来看看如何得到更精准的边界框
如果跑的框没有一个可以完美匹配汽车位置最适合的也是歪的甚至最适合的框不是正方形而是稍微有点长方形长宽比有点向水平方向延伸
其中一个能得到更精准的边界框的算法是 YOLO 算法YOLO的意思你只看一次YOLO = You Only Look Once
比如你的输入图像是100×100的然后再图像上放一个网格为了介绍起来简单一些这里用3×3的网格实际实现时会用更精细的网络可能19×19
基本思路是使用图像分类和定位算法然后将算法应用到9个格子上
更具体一些你需要这样定义训练标签所以对于9个格子中的每一个指定一个标签yy是8维向量第一个是Pc0或1取决于是否有图像对于每个格子都有这么一个向量
我们看左上角格子啥也没有所以它的y是
这张图中有两个对象YOLO算法做的就是 取两个对象的中点然后将这个对象分配给包含对象中点的格子所以这张图的两个对象分在中间行左右两个格子即使中心格子同时有两辆车的一部分我们就假装中心格子没有任何我们感兴趣的对象所以中心格子的y也和左上角的一样。
而对于左边绿色框起来的和右边黄色的y就是
因为是3×3的网格有9个格子所以总的输出尺寸是3×3×8然后对于每个格子都有一个8维向量
而如果要训练一个输入100×100×3的神经网络选择卷积层和最大池化层这样最后映射到一个3×3×8的输出尺寸所以要做的就是有一个输入x 就是这样的输入图像然后有这些3×3×8的目标标签y
当用反向传播训练神经网络时将任意输入x映射到这类输出向量y所以这个算法的优点在于神经网络可以输出精确的边界框。因为每一格对应的输出向量中都有边界框参数bx、by......因为别的格子中的边界属于卷积时的公有区域、卷积运算后会将此部分的坐标权重加给Pc等于1那块对应的坐标训练时手动标
所以测试的时候做的就是输入图像x跑正向传播直到得到输出y然后对于这里的3×3位置对应的9个输出就可以读出0或1你就知道9个位置之一有个对象且这个对象的边界框是什么只要格子中对象的数目没有超过1个这个算法就应该没有问题
这里用的是3×3的网格实践中可能会用更精细的19×19的网格所以就是19×19×8的这样的网格精细很多分配到同一格子的概率就小很多。
把对象分配到一个格子的过程是你观察对象的中点然后将这个对象分配到其中点所在的格子所以即使对象横跨多个格子也只会被分配到9个格子其中之一
所以要注意首先这和图像分类和定位算法非常想它显式地输出边界框坐标所以这能让神经网络输出边界框可以具有任意宽高比并且能输出更精确的坐标不会受到滑动窗法分类器的步长大小限制其次这是一个卷积实现并没有在3×3网格上跑9次算法这是单次卷积实现你使用了一个卷积网络有很多共享计算步骤所以该算法效率很高
事实上YOLO算法有一个好处也是它受欢迎的原因因为这是一个卷积实现它的运行速度非常快可以达到实时识别
还有一个小细节就是如何编码边界框 bxbybhbw
如右边网格的对象以这个网格左上角为00右下角为11即bxbybhbw是相对网格尺度的比例bxby在0和1之间bhbw可能大于1
不过还有其他更复杂的参数化方式如sigmoid确保在0和1之间然后使用指数参数化确保都是非负数还有其他更高级的参数化方式
也可以看看YOLO论文但较难
3.6 交并比IoU
如何判断对象检测算法运作良好呢
运用交并比函数可以用来评价对象检测算法
在对象检测任务中实际边界框是红框而算法给出的是紫框那么这个是好是坏呢?
所以交并比IoU函数做的是 计算两个边界框交集和并集之比一般认为IoU大于或等于0.5就说检测正确完美重叠时IoU=1IoU越高边界框越精确阈值也可以人为定的更严格比如0.6甚至0.7
3.7 非极大值抑制
迄今为止我们学到的对象检测中的一个问题是 算法可能对同一对象做出多次预测所以算法不是对某个对象检测出一次而是检测出多次非极大值抑制可以确保你的算法对每个对象只检测一次
假设需要在这张图里检测行人和汽车可能会放个19×19的网格
理论上车只有一个中点只有一个格子可以做出有车的预测实践中跑对象分类和定位算法时可能周围的格子都认为里面有车周围的格子在分类的时候有车的特征但它并不知道中心点在不在自己格子里
那么非极大值抑制是如何生效的呢
因为要在19×19=361个格子上都跑一遍图像检测和定位算法那么很多格子都会说我这里有车的概率很高而不是仅有两个格子会报告他们检测出一个对象所以跑算法时最后可能会对同一个对象做出多次检测
所以非极大值抑制做的就是清理这些检测结果所以具体上这算法做的就是首先看看每次报告每个检测结果相关的概率Pc首先看概率最大的哪个这个例子中是0.9所以高亮标记其次非极大值抑制逐一深时剩下的矩形所有和这个最大的边界框有很高交并比高度重叠的其他边界框那么这些输出就会被抑制所以右边两个0.6和0.7的框将被抑制变暗
接下来再逐一审视剩下的矩形找出概率Pc最高的一个即左边的0.8此时非极大值抑制就会去掉其他IoU值很高的矩形所以现在每个矩形都是高亮或者变暗的抛去变暗的剩下的高亮就是结果。
非最大值意味着只输出概率最大的分类结果抑制很接近但不是最大的其他预测结果所以叫非极大值抑制
算法细节首先在19×19的网格上跑算法会得到19×19×8的输出简化一下只检测汽车可以去除c1、c2、c3。现在要实现非极大值抑制第一就是去掉所有边界框去掉Pc小于0.6的然后选择Pc最高的输出为预测结果再去掉有很高交并比的边界框直到所有边界框都判断一遍
这里只检测的单个对象如果要同时检测三个对象如行人、汽车、摩托那么输出向量就会有三个额外的分量事实证明正确的做法是独立进行三次非极大值抑制对每个输出类别都做一次
3.8 Anchor Boxers
到目前为止对象检测存在的一个问题是每个格子只能检测出一个对象如果想要一个格子检测出多个对象就是使用anchor box概念
对于下列的例子我们采用3×3网格而行人和汽车的中点几乎在一个地方所以落在同一格子。输出y时将无法输出检测结果所以必须从两个结果中选择一个
而anchor box的思路就是预先定义两个不同形状的 anchor box要做的就是把预测结果和这两个 anchor box关联起来一般来说可能会用更多的 anchor box可能要5个甚至更多但对于这个例子我们只用两个
要做的就是定义类别标签用的向量y需要重复两次行人的形状像 anchor box 1所以用上面8个数值用它来编码包住行人的边界框说明对象是个行人汽车像 anchor box 2就用下面的编码
总结一下用anchor box之前做的是对于训练集图像中的每个对象都根据那个对象中点位置分类到对应的格子中所以输出是3×3×8而anchor box是这样的每个对象都和之前一样分配到同一个格子中分配到对象中点所在的格子但是他还分配到一个anchor box分配到一个格子和对象形状交并比最高的anchor box观察哪一个anchor box和实际边界框交并比更高不管选的哪一个这个对象不止分配到一个格子而是一对这就是对象在目标标签中的编码方式所以现在输出就是3×3×16也可以看成是3×3×2×8如果有多个对象那么y的维度会更高如下
来看一个具体的例子对于这个例子我们定义一下y行人类别1汽车类别2只有格子一个对象时如果像anchor box 2那么anchor box 1的Pc就是0其他don‘t care
但如果有2个anchor box而同一格子有3个对象时算法处理不好还有两个对象anchor box的形状一样的情况也处理不好所以需要打破僵局的处理手段
anchor box就是处理两个对象在同一格子的情况但实际很少发生特别是用的19×19的网格情况下而不是3×3的网格一般手动指定anchor box的形状可以选5到10个形状还有更好的做法即k-means算法将两类对象聚类用它选择一组anchor box选择最具代表性的一组可以代表你试图检测的十几个对象的类别其实是自动选择anchor box 的高级方法
3.9 YOLO算法
让我们把所有零件组合在一起构成YOLO对象检测算法
首先如何构造训练集
假设要训练一个算法取检测行人、汽车、摩托还需要显式指定完整的背景类别这里有3个类别标签。如果要用2个anchor box那么输出就是3×3×2×8要构建训练集需要遍历9个格子然后构成对应的目标向量y最终输出尺寸就是3×3×16
训练时一个卷积网络输入是图片可能是100×100×3然后卷积网络最后输出尺寸是3×3×16或3×3×2×8
接下来看看卷积网络是如何预测的
根据输入图片如左上角没有东西就应该Pc为0下方有汽车我们就希望对车子指定一个相当准确的边界框
最后要跑一下非极大值抑制的话我们用一张新的图片
如果使用2个anchor box那么对于9个格子中的任何一个都会有两个预测的边界框其中一个的Pc很低比如得到的边界框是这样的
有一些边界框可以超出所在格子的高度和宽度接下来抛弃概率低的预测
最后如果有三个对象检测类别希望检测到行人、汽车、摩托就对每个类别单独运行非极大值抑制处理预测结果是那个类别的边界框用非极大值抑制分别来处理行人、汽车、摩托类别运行三次得到最终预测结果所以算法输出最好可以检测出图像里所有的汽车还有所有的行人和摩托
3.10 候选区域可选
可选只是因为用到候选区域这一系列算法的概率没那么高但是是很有影响力的
如下图跑算法时会在没有任何对象的区域浪费时间所以提出一种叫做 R-CNN 的算法意思是带区域的卷积网络 或者说 带区域的CNN这个算法尝试选出一些区域在这些区域上运行卷积网络分类器是有意义的所以这里不再针对每个滑动窗跑检测算法而是只选择一些窗口在少数窗口上运行卷积网络分类器
选出候选区域的方法是运行图像分割算法结果是下边的图像
为了找出可能存在对象的区域比如说分割算法在这里得到一个色块所以你可能在这个色块上跑分类器也像上面的绿色框在绿色框再跑分类器所以这个就是所谓的分割算法。找出2000多个色块在这些色块上跑一下分类器这样需要处理的位置可能少很多可以减少卷积网络分类器运行时间
现在看来R-CNN算法还是很慢的所以有一系列研究来改善
所以基本的R-CNN算法是使用某种算法求出候选区域然后对每个区域跑一下分类器每个区域会输出一个标签并输出一个边界框这样就能在确实存在对象的区域得到一个精确的边界框。
R-CNN算法不会直接信任输入的边界框他也会输出一个边界框bx、by、bw、bh这样得到的边界框比较精确比单纯使用图像分割算法给出的色块边界要好所以它可以得到相当精确的边界框
现在R-CNN的一个缺点就是太慢了有一些对R-CNN算法的改进工作即快速R-CNN用的是滑动窗法的一个卷积实现而最初的算法是逐一对区域分类事实证明快速R-CNN算法的其中一个问题就是得到候选区域的聚类步骤仍然非常缓慢所以又提出了另一个更快的
使用的是卷积神经网络 而不是更传统的分割算法来获得候选区域色块结果快得多不过大多数更快R-CNN算法实现还是比YOLO算法慢很多