吴恩达深度学习笔记:卷积神经网络(Foundations of Convolutional Neural Networks)3.1-3.2
要明确一点,特征点 1 的特性在所有图片中必须保持一致,就好比,特征点 1 始终是右眼的外眼角,特征点 2 是右眼的内眼角,特征点3 是左眼内眼角,特征点 4 是左眼外眼角等等。也许除了这四个特征点,你还想得到更多的特征点输出值,这些(图中眼眶上的红色特征点)都是眼睛的特征点,你还可以根据嘴部的关键点输出值来确定嘴的形状,从而判断人物是在微笑还是皱眉,也可以提取鼻子周围的关键特征点。最后一个例子,
目录
第四门课 卷积神经网络(Convolutional Neural Networks)
第三周 目标检测(Object detection)
3.1 目标定位(Object localization)
这一周我们学习的主要内容是对象检测,它是计算机视觉领域中一个新兴的应用方向,相比前两年,它的性能越来越好。在构建对象检测之前,我们先了解一下对象定位,首先我们看看它的定义。

图片分类任务我们已经熟悉了,就是算法遍历图片,判断其中的对象是不是汽车,这就是图片分类。这节课我们要学习构建神经网络的另一个问题,即定位分类问题。这意味着,我们不仅要用算法判断图片中是不是一辆汽车,还要在图片中标记出它的位置,用边框或红色方框把汽车圈起来,这就是定位分类问题。其中“定位”的意思是判断汽车在图片中的具体位置。这周后面几天,我们再讲讲当图片中有多个对象时,应该如何检测它们,并确定出位置。比如,你正在做一个自动驾驶程序,程序不但要检测其它车辆,还要检测其它对象,如行人、摩托车等等,稍后我们再详细讲。
本周我们要研究的分类定位问题,通常只有一个较大的对象位于图片中间位置,我们要对它进行识别和定位。而在对象检测问题中,图片可以含有多个对象,甚至单张图片中会有多个不同分类的对象。因此,图片分类的思路可以帮助学习分类定位,而对象定位的思路又有助于学习对象检测,我们先从分类和定位开始讲起。
图片分类问题你已经并不陌生了,例如,输入一张图片到多层卷积神经网络。这就是卷积神经网络,它会输出一个特征向量,并反馈给 softmax 单元来预测图片类型。

如果你正在构建汽车自动驾驶系统,那么对象可能包括以下几类:行人、汽车、摩托车和背景,这意味着图片中不含有前三种对象,也就是说图片中没有行人、汽车和摩托车,输出结果会是背景对象,这四个分类就是 softmax 函数可能输出的结果。
这就是标准的分类过程,如果你还想定位图片中汽车的位置,该怎么做呢?我们可以让神经网络多输出几个单元,输出一个边界框。具体说就是让神经网络再多输出 4 个数字,标记为 b x b_x bx, b y b_y by, b h b_h bh和 b w b_w bw,这四个数字是被检测对象的边界框的参数化表示。
我们先来约定本周课程将使用的符号表示,图片左上角的坐标为(0,0),右下角标记为(1,1)。要确定边界框的具体位置,需要指定红色方框的中心点,这个点表示为( b x b_x bx, b y b_y by),边界框的高度为 b h b_h bh,宽度为 b w b_w bw。因此训练集不仅包含神经网络要预测的对象分类标签,还要包含表示边界框的这四个数字,接着采用监督学习算法,输出一个分类标签,还有四个参数值,从而给出检测对象的边框位置。此例中, b x b_x bx的理想值是 0.5,因为它表示汽车位于图片水平方向的中间位置; b y b_y by大约是 0.7,表示汽车位于距离图片底部 3 10 \frac{3}{10} 103的位置; b h b_h bh约为 0.3,因为红色方框的高度是图片高度的 0.3 倍; b w b_w bw约为 0.4,红色方框的宽度是图片宽度的 0.4 倍。

下面我再具体讲讲如何为监督学习任务定义目标标签 𝑦。

请注意,这有四个分类,神经网络输出的是这四个数字和一个分类标签,或分类标签出现的概率。目标标签𝑦的定义如下:
𝑦 = [ p c b x b y b h b w c 1 c 2 c 3 ] \begin{bmatrix} p_c \\ b_x \\ b_y \\ b_h \\ b_w \\ c_1 \\ c_2 \\ c_3 \\ \end{bmatrix}
pcbxbybhbwc1c2c3
它是一个向量,第一个组件𝑝𝑐表示是否含有对象,如果对象属于前三类(行人、汽车、摩托车),则 p c p_c pc = 1,如果是背景,则图片中没有要检测的对象,则 p c p_c pc= 0。我们可以这样理解𝑝𝑐,它表示被检测对象属于某一分类的概率,背景分类除外。
如果检测到对象,就输出被检测对象的边界框参数 b x b_x bx、 b y b_y by、 b h b_h bh和 b w b_w bw。最后,如果存在某个对象,那么 p c p_c pc = 1,同时输出 c 1 c_1 c1、 c 2 c_2 c2和 c 3 c_3 c3,表示该对象属于 1-3 类中的哪一类,是行人,汽车还是摩托车。鉴于我们所要处理的问题,我们假设图片中只含有一个对象,所以针对这个分类定位问题,图片最多只会出现其中一个对象。

我们再看几个样本,假如这是一张训练集图片,标记为𝑥,即上图的汽车图片。而在𝑦当中,第一个元素 p c p_c pc = 1,因为图中有一辆车, b x b_x bx、 b y b_y by、 b h b_h bh和 b w b_w bw会指明边界框的位置,所以标签训练集需要标签的边界框。图片中是一辆车,所以结果属于分类 2,因为定位目标不是行人或摩托车,而是汽车,所以 c 1 c_1 c1 = 0, c 2 c_2 c2 = 1, c 3 c_3 c3 = 0, c 1 c_1 c1、 c 2 c_2 c2和 c 3 c_3 c3中最多只有一个等于 1。
这是图片中只有一个检测对象的情况,如果图片中没有检测对象呢?如果训练样本是这样一张图片呢?

这种情况下, p c p_c pc = 0,𝑦的其它参数将变得毫无意义,这里我全部写成问号,表示“毫无意义”的参数,因为图片中不存在检测对象,所以不用考虑网络输出中边界框的大小,也不用考虑图片中的对象是属于 c 1 c_1 c1、 c 2 c_2 c2和 c 3 c_3 c3的哪一类。针对给定的被标记的训练样本,不论图片中是否含有定位对象,构建输入图片𝑥和分类标签𝑦的具体过程都是如此。这些数据最终定义了训练集。
最后,我们介绍一下神经网络的损失函数,其参数为类别𝑦和网络输出𝑦^,如果采用平方误差策略,则 L ( y ^ , y ) = ( y ^ 1 − y 1 ) 2 + ( y ^ 2 − y 2 ) 2 + ⋯ ( y ^ 8 − y 8 ) 2 L(\hat{y} ,y) = (\hat{y}_1− y_1)^2+ (\hat{y}_2− y_2)^2+ ⋯ (\hat{y}_8− y_8)^2 L(y^,y)=(y^1−y1)2+(y^2−y2)2+⋯(y^8−y8)2,损失值等于每个元素相应差值的平方和。

如果图片中存在定位对象,那么 y 1 y_1 y1 = 1,所以 y 1 y_1 y1 = p c p_c pc,同样地,如果图片中存在定位对象, p c p_c pc = 1,损失值就是不同元素的平方和。
另一种情况是, y 1 y_1 y1 = 0,也就是 p c p_c pc = 0,损失值是 ( y ^ 1 − y 1 ) 2 (\hat{y}_1− y_1)^2 (y^1−y1)2,因为对于这种情况,我们不用考虑其它元素,只需要关注神经网络输出 p c p_c pc的准确度。
回顾一下,当 y 1 y_1 y1 = 1时,也就是这种情况(编号 1),平方误差策略可以减少这 8 个元素预测值和实际输出结果之间差值的平方。如果 y 1 y_1 y1 = 0,𝑦 矩阵中的后 7 个元素都不用考虑(编号 2),只需要考虑神经网络评估 y 1 y_1 y1(即 p c p_c pc)的准确度。
为了让大家了解对象定位的细节,这里我用平方误差简化了描述过程。实际应用中,你可以不对 c 1 c_1 c1、 c 2 c_2 c2、 c 3 c_3 c3和 softmax 激活函数应用对数损失函数,并输出其中一个元素值,通常做法是对边界框坐标应用平方差或类似方法,对𝑝𝑐应用逻辑回归函数,甚至采用平方预测误差也是可以的。
以上就是利用神经网络解决对象分类和定位问题的详细过程,结果证明,利用神经网络输出批量实数来识别图片中的对象是个非常有用的算法。下节课,我想和大家分享另一种思路,就是把神经网络输出的实数集作为一个回归任务,这个思想也被应用于计算机视觉的其它领域,也是非常有效的,所以下节课见。
3.2 特征点检测(Landmark detection)
上节课,我们讲了如何利用神经网络进行对象定位,即通过输出四个参数值 b x b_x bx、 b y b_y by、 b h b_h bh和 b w b_w bw给出图片中对象的边界框。更概括地说,神经网络可以通过输出图片上特征点的(𝑥, 𝑦)坐标来实现对目标特征的识别,我们看几个例子。

假设你正在构建一个人脸识别应用,出于某种原因,你希望算法可以给出眼角的具体位置。眼角坐标为(𝑥, 𝑦),你可以让神经网络的最后一层多输出两个数字 l x l_x lx和 l y l_y ly,作为眼角的坐标值。如果你想知道两只眼睛的四个眼角的具体位置,那么从左到右,依次用四个特征点来表示这四个眼角。对神经网络稍做些修改,输出第一个特征点( l 1 x l_{1x} l1x, l 1 y l_{1y} l1y),第二个特征点( l 2 x l_{2x} l2x, l 2 y l_{2y} l2y),依此类推,这四个脸部特征点的位置就可以通过神经网络输出了。

也许除了这四个特征点,你还想得到更多的特征点输出值,这些(图中眼眶上的红色特征点)都是眼睛的特征点,你还可以根据嘴部的关键点输出值来确定嘴的形状,从而判断人物是在微笑还是皱眉,也可以提取鼻子周围的关键特征点。为了便于说明,你可以设定特征点的个数,假设脸部有 64 个特征点,有些点甚至可以帮助你定义脸部轮廓或下颌轮廓。选定特征点个数,并生成包含这些特征点的标签训练集,然后利用神经网络输出脸部关键特征点的位置。
具体做法是,准备一个卷积网络和一些特征集,将人脸图片输入卷积网络,输出 1 或 0,1 表示有人脸,0 表示没有人脸,然后输出( l 1 x l_{1x} l1x, l 1 y l_{1y} l1y)……直到( l 64 x l_{64x} l64x, l 64 y l_{64y} l64y)。这里我用𝑙代表一个特征,这里有129 个输出单元,其中1表示图片中有人脸,因为有64个特征,64×2=128,所以最终输出 128+1=129 个单元,由此实现对图片的人脸检测和定位。这只是一个识别脸部表情的基本构造模块,如果你玩过 Snapchat 或其它娱乐类应用,你应该对 AR(增强现实)过滤器多少有些了解,Snapchat 过滤器实现了在脸上画皇冠和其他一些特殊效果。检测脸部特征也是计算机图形效果的一个关键构造模块,比如实现脸部扭曲,头戴皇冠等等。当然为了构建这样的网络,你需要准备一个标签训练集,也就是图片𝑥和标签𝑦的集合,这些点都是人为辛苦标注的。

最后一个例子,如果你对人体姿态检测感兴趣,你还可以定义一些关键特征点,如胸部的中点,左肩,左肘,腰等等。然后通过神经网络标注人物姿态的关键特征点,再输出这些标注过的特征点,就相当于输出了人物的姿态动作。当然,要实现这个功能,你需要设定这些关键特征点,从胸部中心点( l 1 x l_{1x} l1x, l 1 y l_{1y} l1y)一直往下,直到( l 32 x l_{32x} l32x, l 32 y l_{32y} l32y)。
一旦了解如何用二维坐标系定义人物姿态,操作起来就相当简单了,批量添加输出单元,用以输出要识别的各个特征点的(𝑥, 𝑦)坐标值。要明确一点,特征点 1 的特性在所有图片中必须保持一致,就好比,特征点 1 始终是右眼的外眼角,特征点 2 是右眼的内眼角,特征点3 是左眼内眼角,特征点 4 是左眼外眼角等等。所以标签在所有图片中必须保持一致,假如你雇用他人或自己标记了一个足够大的数据集,那么神经网络便可以输出上述所有特征点,你可以利用它们实现其他有趣的效果,比如判断人物的动作姿态,识别图片中的人物表情等等。
以上就是特征点检测的内容,下节课我们将利用这些构造模块来构建对象检测算法。
更多推荐
所有评论(0)