吴恩达《卷积神经网络》(第三周上半部分)

本文探讨了卷积神经网络在目标定位、特征点检测和目标检测中的应用,介绍了滑动窗口法、YOLO算法及其高效实现,以及如何预测更精准的边界框。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

卷积神经网络(第三周上半部分)


3.1 目标定位


在构建对象检测之前,我们先了解一下对象定位,先看下它的定义,图片分类任务我们已经熟悉就是算法遍历图片,判断其中的对象是不是汽车。这部分内容是要构建神经网络的另一个问题即定位分类问题,这意味着我们不仅要判断图片中是不是一辆汽车,还要在图片中标记出它的位置,用边框或者红色方框把汽车圈起来,这就是定位分类问题。其中“定位“的意思是判断汽车在图片中的具体位置,后面会再细讲当图片中有多个对象时应该如何检测它们,并确定出位置。比如正在做一个自动驾驶程序,程序不但要检测其他车辆还要检测其他对象如行人、摩托车等。本周要说的就是分类定位问题,通常只有一个较大的对象位于图片的中间位置,我们要对它进行识别和定位,而在对象检测问题中,图片可以含有多个对象,甚至单张图片中会有多个不同的分类对象,因此图片分类的思路可以帮助学习分类定位,而对象定位的思路又有助于学习对象检测。

在这里插入图片描述
关于图片分类之前已经有说过,例如输入一张图片到多层卷积神经网络,它会输出一个特征向量,并反馈给softmax单元来预测图片类型。如果你正在构建汽车自动驾驶系统,那么对象可能包括以下几类:行人、汽车、摩托车和背景(如果某个图片中没有行人、汽车、摩托车、那么输出结果是背景对象),这四个分类就是softmax函数可能输出的结果。
如果想要定位图片中汽车的位置,该怎么做?我们可以让神经网络多输出几个单元,输出一个边界框,具体说就是让神经网络再多输出4个数字,标记为bx、by、bh、bw,这四个数字是被检测对象的边界框的参数化表示,我们先来约定本周课将使用的符号表示,图片左上角标记为(0 , 0),右下角标记为(1 , 1),要想确定边界框的具体位置,需要指定红色方框的中心点,这个点表示为(bx,by),边界框的高度为bh,宽度为bw。因此训练集不仅包含神经网络的对象分类标签,还包含表示边界框的这四个数字。接着采用监督学习算法输出一个分类标签,还有这四个参数值,从而给出被检测对象的边界框位置。此例中bx的理想值是0.5因为它表示汽车位于图片水平方向的中间位置,by大约是0.7表示汽车位于距离图片底部3/10的位置,bh=0.3,因为红色方框的高度是图片高度的0.3倍,bw约是0.4因为红色方框的宽度是图片宽度的0.4倍。
在这里插入图片描述

下面我们再看看如何为监督学习任务定义目标标签y,请注意这里是四个分类,神经网络输出的是这四个数字和一个分类标签或分类标签出现的概率。目标标签Y的定义如下它是一个向量,第一个组件Pc表示是否含有对象,如果对象属于前三类则Pc = 1,如果是属于背景则图片中没有要检测的对象Pc = 0,我们可以这样理解Pc,它表示被检测对象属于某一分类的概率,背景分类除外,如果检测到对象,就输出被检测对象的边界框参数bx 、by 、bh 、bw,如果存在某个对象,那么Pc输出为1,同时输出c1 、c2 、c3 ,表示该对象属于1 - 3中的哪一类别是行人、汽车、还是摩托车。

鉴于我们所要处理的问题,我们假设图片中只含有一个对象,所以针对这个分类定位问题,图片最多只会出现其中一个对象。
在这里插入图片描述
我们来看几个例子,加入这是一张训练集图片,标记为X。Y当中第一个元素Pc = 1因为图中有一辆车,bx 、by 、bh 、bw会指明边界框的位置,所以标签训练集需要标签的边界框,图片中是一辆车所以结果属于分类2 , 因为定位目标不是行人 、 摩托车而是汽车,所以c1 = 0 , c2 = 1 ,c3 = 0 ,c1、c2、c3中最多只有一个等于1 , 这是图片中只有一个检测对象的情况,如果图片中没有检测对象呢?如果训练样本是下图中右面的图片呢?这种情况下Pc = 0 ,Y的其他参数将变得毫无意义,因为图片中不存在检测对象所以不用考虑网络输出中边界框的大小。也不用考虑图片中的对象是属于c1 c2和c3中的哪一类,针对给定的被标记的训练样本不论图片中是否含有定位对象构建输入图片X和分类标签Y的具体过程都是如此,这些数据定义了训练集。

在这里插入图片描述
最后说下训练神经网络的损失函数,其参数为类别y和网络输出y^,损失函数可以表示为L( y^,y),如果采用平方误差策略公式如图,这里含有8个元素,损失值等于每个元素相应差值的平方和。如果图片中存在定位对象所以y1 = 1 = Pc,损失值就是不同元素的平方和。另一种情况是y1 = 0 也就是Pc = 0 ,损失值是 (y1^ - y1)的平方,此时表示图片中并没有对象,如上图所示所以其他值均为0 ,这种情况我们不用考虑其他元素,只需关注神经网络输出的Pc的准确度即可

在这里插入图片描述


3.2 特征点检测


上面部分我们提到过用神经网络进行对象定位,即通过输出四个参数值bx , by , bh和bw给出图中对象的边界值。更概括的说,神经网络可以通过输出图片上特征点的(x , y)坐标来实现对目标特征的识别,我们看几个例子。
假设你正在构建一个人脸识别应用,出于某种原因,你希望算法可以给出眼角的具体位置眼角坐标为(x , y),你可以让神经网络的最后一层多输出两个数字lx和ly做为眼角的坐标值。如果你想知道两只眼睛的四个眼角具体位置,那么从左到右,依次用四个特征点来表示这四个眼角对神经网络稍作些修改输出第一个特征点(l1x ,l1y)第二个特征点(l2x ,l2y)依次类推,这四个脸部特征点的位置就可以通过神经网络输出了,也许除了这四个点还想得到更多的特征点输出值,你还可以根据嘴部的关键点输出值来确定嘴的形状,从而判断人物是在微笑还是皱眉。也可以提取鼻子周围的关键特征点。
在这里插入图片描述
为了便于说明,你可以设定特征点的个数假设脸部有64个特征点,有些点甚至可以帮助你定义脸部轮廓或者下颌轮廓。选定特征点个数,并生成包含这些特征点的标签训练集,然后利用神经网络输出脸部关键特征点的位置。具体做法是准备一个卷积网络和一些特征集将人脸图片输入卷积网络输出1或者0,1表示有人脸,0表示没有人脸。然后输出(l1x , l1y)…直到(l64x , l64y),这里我用l代表一个特征,这里有129个输出单元,其中1表示图片中有人脸,因为有64个特征64 * 2 ,所以最终输出128 + 1个单元。由此实现对图片的人脸检测和定位,这只是一个识别脸部表情的基本构造模块。
当然为了构建这样的网络,你需要准备一个标签训练集也就是图片X和标签Y的集合,这些特征点都是人为辛苦标注的。
在这里插入图片描述
在这里插入图片描述
最后一个例子,关于人体姿态检测你还可以定义一些关键特征点如胸部的中点、左肩、左肘、腰等等,然后通过神经网络标注人物姿态的关键特征点再输出这些标注过的特征点,就相当于输出了人物的姿态动作。
在这里插入图片描述

当然,要实现这个功能,需要设定这些关键特征点从胸部中心点(l1x , l1y)一直往下到(l32x , l32y),一旦了解如何用二维坐标系定义人物姿态,操作起来就相当简单了,批量添加输出单元,用以输出要识别的各个特征点的(X , Y)坐标值,要明确一点,特征点1的特性在所有图片中必须保持一致,就好比特征点1始终是右眼的外眼角,特征点2是右眼的内眼角等等,所以标签在所有图片中必须保持一致。以上就是特征点检测的内容。


3.3 目标检测


之前已经介绍过对象定位和特征点检测,下面来构建一个对象检测算法,将要学习如何通过卷积网络进行对象检测,采用的是基于滑动窗口的目标检测算法。
假如你想构建一个汽车检测算法,步骤是首先创建一个标签训练集,也就是X和Y,表示适当剪切的汽车图片样本,这张图片x是一个正样本,因为它是一辆汽车图片,下面几张图片也有汽车,但是再下面两张没有汽车。
在这里插入图片描述
出于我们对这个训练集的期望,一开始可以使用适当剪切的图片,就是整张图片x几乎都被汽车占据,你可以照张照片,然后剪切,剪掉汽车以外的部分,使汽车居于中心位置并基本占据整张图片,有了这个标签训练集就可以开始训练卷积网络了,输入这些适当剪切过的图像,卷积网络输出为Y0或1表示图片中有汽车或没有汽车,训练完这个卷积网络就可以用它来实现滑动窗口目标检测,具体步骤如下,假设这是一张测试图片,首先选定一个特定大小的窗口(比如图片下方像这样的窗口),将这个红色小方块(图中左上角)输入卷积网络,卷积网络开始进行预测即判断红色方框内有没有汽车。
在这里插入图片描述

滑动窗口目标检测算法接下来会继续处理第二个图像即红色方框稍向右滑动之后的区域并输入卷积网络,因此输入给卷积网络的只是红色方框内的区域。再次进行卷积然后处理第三个图像,依次重复操作直到这个窗口滑动过图像的每一个角落,为了滑动的更快,这里选用的步幅比较大,思路是以固定步幅滑动窗口,遍历图像的每个区域,把这些剪切后的小图像输入卷积网络,对每个位置按0或1进行分类,这就是所谓的图像滑动窗口操作。
在这里插入图片描述
重复上述操作,不过这次我们选择一个更大的窗口,截取更大的区域并输入给卷积网络处理,可以根据卷积网络对输入大小的要求调整这个区域,然后输入给卷积网络,输出0或1再以某个固定步幅滑动窗口,重复以上操作遍历整个图像,输出结果。

在这里插入图片描述
第三次,可以选用更大的窗口,如果这样做不论汽车在图片的什么位置,总有一个窗口可以检测它,比如将下面这个窗口输入卷积网络,希望卷积网络对该输入区域的输出结果为1,说明网络检测到图上有辆汽车,这种算法是滑动窗口目标检测。
在这里插入图片描述
我们以某个步幅滑动这些方框窗口遍历整张图片,对这些方形区域进行分类,判断里面有没有汽车,滑动窗口目标检测算法也有很明显的缺点,就是计算成本,因为在图片中剪切出太多小方块,卷积网络要一个个处理,如果选用的步幅大显然会减少输入卷积网络的窗口个数,但是粗粒度可能会影响性能,反之如果采用小粒度或小步幅传递给卷积网络的小窗口会特别多,这就意味着超高的计算成本。


3.4 卷积的滑动窗口实现


上面我们提到了如何通过卷积网络实现滑动窗口对象检测算法,但是效率很低,下面来看下如何在卷积层上应用这个算法,为了构建滑动窗口的卷积应用,首先要知道如何把神经网络的全连接层转化成卷积层。假设对象检测算法输入一个14 * 14 * 3的图像,在这里过滤器的大小为5 * 5数量是16 ,14 * 14 * 3的图像在过滤器处理之后映射为10 * 10 * 16 ,然后通过参数为2 * 2的最大池化操作,图像减小到5 * 5 * 16 然后添加一个连接400单元的全连接层,接着再添加一个全连接层,最终通过softmax单元输出Y。
在这里插入图片描述

为了跟下图区分开,先做一点改动,用4个数字来表示Y,它们分别对应softmax单元所输出的4个分类出现的概率,这四个分类可以是行人 、汽车、摩托车和背景或其他对象。
在这里插入图片描述
现在要做的就是如何把这些全连接层转化成卷积层,下面画一下这样的卷积网络,它的前几层和之前的一样,而对于全连接层,我们可以用5 * 5的过滤器来实现,数量是400个,输入图像大小为5 * 5 * 16 ,用5 * 5的过滤器对它进行卷积操作,过滤器实际上是5 * 5 * 16 ,因为在卷积过程中过滤器会遍历这16个信道,所以两处的信道数量必须保持一致,输出结果为1 * 1,假设应用400个这样的5 * 5 * 16过滤器输出维度就是1 * 1 * 400。我们不再把它看作一个含有400个节点的集合,而是一个1 * 1 * 400的输出层,从数学角度看,它和全连接层是一样的,因为这400个节点中每个节点都有一个5 * 5 * 16维度的过滤器。所以每个值都是上一层这些5 * 5 * 16激活值经过某个任意线性函数的输出结果。我们再添加另外一个卷积层,这里是1 * 1卷积,假设有400个1* 1的过滤器,在这400个过滤器的作用下,下一层的维度是1 * 1 * 400,它其实就是上个网络中的全连接层,最后经由1 * 1过滤器的处理,得到一个softmax激活值,最终得到这个1 * 1 * 4的输出层。
在这里插入图片描述
以上就是用卷积层代替全连接层的过程结果这几个单元集就变成了1 * 1 * 400和1 * 1 * 4的维度,掌握了卷积的知识,再看看如何通过卷积实现滑动窗口对象检测算法,假设向滑动窗口卷积网络输入14 * 14 * 3的图片,和前面一样,神经网络最后的输出层softmax单元的输出是1 * 1 * 4,图中画的较简单,严格来说14 * 14 * 3应该是一个长方体,第二个10 * 10 * 16也是一个长方体,但是为了方便只画了正面,所以对于1 * 1 * 400的这个输出层也只画了它1 * 1的那个面,所以这里显示的都是平面图而不是3D图像。
在这里插入图片描述
假设输入给卷积网络的图片大小是14 * 14 * 3,测试集图片是16 * 16 * 3 ,现在给这个输入图片加上黄色条块,在最初的滑动窗口算法中,会把这片蓝色区域输入卷积网络,生成0或1分类,接着滑动窗口步幅为2个像素,向右滑动2个像素,将这个绿框区域输入给卷积网络,运行整个卷积网络,得到另外一个标签0或1,继续将橘色区域输入给卷积网络,卷积后得到另外一个标签,最后对右下方的紫色区域进行最后一次卷积操作。
在这里插入图片描述
在这个16 * 16 * 3的小图像上滑动窗口,卷积网络运行了4次,于是输出了4个标签,结果发现这4次卷积操作中的很多计算都是重复的,滑动窗口的卷积应用使得卷积网络在这4次操作中很多计算都是重复的,尤其是在第一次卷积步骤中(比较大涉及重复计算比较多?),因为在每个区域进行卷积时使用相同的5 * 5 * 16的过滤器进行卷积操作,得到12 * 12 * 16的输出层,然后执行最大池化操作,输出结果是6 * 6 * 16。照旧应用400个5 * 5的过滤器,得到一个2 * 2 * 400的输出层,现在输出层为2 * 2 * 400,而不是1 * 1 * 400,再应用1 * 1过滤器得到另一个2 * 2 * 400的输出层,再做一次全连接操作最终得到一个2 * 2 * 4的输出层。最终,在输出层这4个子方块中,蓝色的是图像左上部分14 * 14区域的的输出,右上角方块是图像右上部分的对应输出,左下角方块是输入层左下角14 * 14区域经过卷积网络处理后的结果,同样右下角这个方块是卷积网络处理输入层右下角14 * 14区域的结果。

总结一下,滑动窗口的实现过程,在图片上剪切出一块区域,假设它的大小是14 * 14把它输入到卷积网络,再次向右移动大小仍是14 * 14同上操作,重复操作,直到某个区域识别到汽车。
在这里插入图片描述
在这里插入图片描述
但是正如在前面所看到的我们不用依靠连续的卷积操作来识别图片中的汽车,比如我们可以对大小为28 * 28的整张图片进行卷积操作,一次得到各个区域的所有预测值,如果足够幸运,神经网络便可以识别出汽车的位置。


3.5 Bounding Box 预测


上面已经提到滑动窗口的卷积实现,下面这个算法效率更高,但仍然存在问题,不能输出最精准的边界框。在下面,我们看下如何的到更精准的边界框。
在滑动窗口法中,取这些离散的位置集合(方形区域)然后在它们上面跑分类器,在这种情况下,这些边界框没有一个能完美匹配汽车位置的。

在这里插入图片描述
在这里插入图片描述
正好匹配的甚至是稍微有点长方形,长宽比有点向水平方向延伸。有没有办法让这个算法输出更精准的边界框呢?

在这里插入图片描述
其中一个能得到更精准的边界框的算法是YOLO算法,做法为:比如输入图像是100 * 100的,然后在图像上放一个网格(这里用3 * 3的网格,实际实现时会用更精细的网格),基本思路是使用图像分类和定位算法,然后将算法逐一应用到9个格子上。更具体一点,你需要这样定义训练标签,对于9个格子中的每一个指定一个标签y,y是8维向量(和之前一样pc为是否有实体中心点,bx 、by 、bh、 bw 分别是如果那个格子里有对象,就给出边界框的坐标,然后c1、 c2 、c3就是想要识别的三个类别,背景类别不算。),所以这张图里有9个格子对于每个格子都有这么一个向量。
我们看下图像中左上方格子,这里这个什么也没有,所以左上格子的标签向量y是pc = 0,那么此时更不用说实体的b向量了 。其实整张图像中有两个实体对象(图中红色框)那么YOLO算法做的就是取两个对象的中点,然后将这个对象分配给包含对象中点的格子里,所以左边的汽车就分配到了第二排左边的格子里,然后另外一辆汽车的中点就分配给了最右边的格子里。而对于这个用绿色框起来的格子,目标标签y就是这样的这里有一个对象然后你写出bx 、by 、bh、 bw来指定边界框位置,然后还有类别一是行人那么数值就是0,类别二是汽车是1,类别3是摩托车数值是0,右边黄色框的向量也是这样表示的如下图。所以对于9个格子中任何一个,你都会得到一个8维输出向量。因为这里是3 * 3的网格,所以有9个格子总的输出尺寸是3 * 3 * 8。因为这里有3 * 3的格子,对于每个格子都有一个8维向量y,所以目标输出是3 * 3 * 8。

在这里插入图片描述

如果现在要训练一个输入为100 * 100 * 3的神经网络,这是输入图像。然后你有一个普通的卷积网络,卷积层、最大池化层等等。最后你会选择卷积层和最大池化层,最后映射到一个3 * 3 * 8输出尺寸。所以你要做的是有一个输入X,就是这样的输入图像,然后有这些3 * 3 * 8的目标标签y,当你用反向传播训练神经网络时,将任意输入X映射到这类输出向量y,所以这个算法的优点在于神经网络可以输出精确的边界框。所以在测试的时候,你做的是喂入输入图像X,然后跑正向传播直到你得到这个输出y。然后对于这里3 * 3位置对应的9个输出,我们在输出中展示过的,你就可以读出0或者1,就知道9个位置之一有个对象还有这个对象的边界框是什么。
在这里插入图片描述
只要每个格子中对象数目没有超过1个这个算法应该是没有问题的。那么一个格子中存在多个对象的问题稍后再讨论,我们这里用的是比较小的3 * 3的网格,但实践中可能会用到更精细的19 * 19网格,所以就是19 * 19 * 8.这样的网络精细的多,那么多个对象分配到同一个格子的概率就小得多,重申一下把对象分配到一个格子的过程是你观察对象的中点,然后将这个对象分配到其中点所在的格子,所以即使对象可以横跨多个格子,也只会被分配到9个格子其中之一。两个对象的中点处于同一个格子的概率就会很低,所以要注意首先这和图像分类和定位算法非常像,其次这是一个卷积实现,并没有在3 * 3网格上跑9次算法,或者说你用的是19 * 19的网格,19的平方是361次,所以你不需要让同一个算法跑361次,相反,这是单次卷积实现但是使用了一个卷积网络,有很多共享计算步骤,所以这个算法效率更高。
事实上YOLO算法有一个好处也是它受欢迎的原因,因为这是一个卷积实现,实际上它的运行速度非常的快可以达到实时识别。

还有一个细节是如何编码这些bx 、by 、bh、 bw,下图中有两辆车,我们有个3 * 3网络,我们以右边车为例红色格子里有个对象所以目标标签y就是1,也就是pc=1,然后bx 、by 、bh、 bw然后为0 、1、 0,那么怎么指定这个边界框呢?在YOLO算法中对于这个方框我们约定左上这个蓝色原点是(0 , 0),右下方蓝色点为(1 , 1),要指定橙色中点的位置bx可能是0.4 、by可能是0.3 、bh用格子总体宽度比例表示(所以这个红框的宽度可能是蓝线的90%所以可能是0.9)、 bw(红色框的高度也许是小格子总体高度的一半所以值可能是0.5),换句话说,这些值是相对格子尺寸的比例,所以是介于0和1之间的。还有一种情况是大于1的,是红色框框的边界超出了小格子。这种表示是比较常用的,还有其他参数化方式,可能效果会更好。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值