卷积神经网络-吴恩达深度学习课程第四课
时间:2021/02/16
一.卷积神经网络
1.1 计算机视觉
卷积神经网络一般应用于计算机视觉领域,由于有的时候图片的像素点很多,导致神经网络输入特征值的维数很多。
1.2 边缘检测示例
如下图所示,原图是一个6*6*1的矩阵,卷积核是一个3*3*1的矩阵,经过卷积后得到一个4*4*1的矩阵。
下图展示了垂直边缘检测的原理:
1.3 更多边缘检测例子
垂直边缘检测不仅可以检测垂直方向的边缘,还可以区分该边是从亮到暗(正边)还是从暗到亮(负边)。
除了之前卷积核中数字组合外还有很多,在做边缘检测的过程中最好将卷积核中的数字作为参数进行学习,这样得到的神经网络效果最好。
1.4 Padding
对于之前介绍的卷积方式,其存在两个缺陷:一是当一个6*6的图像经过3*3的卷积核卷积后会变成一个4*4的图像,这使图像经过卷积后变小了;二是原矩阵边缘处只被运算一次,而中心处会被运算多次,导致边缘处大部分信息被丢失了。
下图是两种卷积方式:Valid卷积是令padding为0;Same卷积是通过添加padding使卷积前和卷积后图像的大小相同。
引入padding后维数的公式为n+2p-f+1。
1.5 卷积步长
当步长为2时,每进行一次运算后都要向左或者下移动两个像素点,如下图。
下图是有步长的情况下维数的计算公式:
1.6 三维卷积
对三维图像进行卷积时,卷积核的通道数要与三维图像的通道数相等。当我们想对图像的多个边缘特征进行检测时,我们可以使用多个卷积核,这样卷积后生成图像的通道数为使用的卷积核的个数。
对于三维卷积具体运算的实例如下:如果使用的是下图3*3*3的卷积核,则一共有27个参数,进行卷积运算时让数值与相应的参数相乘后求和,这就是最后4*4*1矩阵中的一个值。
1.7 单层卷积网络
通过下图来说明卷积层所做的操作,但我们有一个6*6*3的图片输入时,我们想要提取图片的两个特征值,所以我们用了两个3*3*3的卷积核,从而生成了4*4*2的两个矩阵,然后对矩阵增添一个偏置量b,这样就相当于完成了完成了全连接神经网络的线性运算z=w*a+b。之后对得到的矩阵运用激活函数就可以完成该卷积层的运算。
下图是对各个变量以及参数的维数的总结
1.8 简单卷积网络示例
下图展示了使用一个卷积神经网络实现图片分类,在最后我们要将得到的矩阵展开成一个向量,然后输入到输出层的sigmoid函数或者softmax函数。对于卷积神经网络来说,通常图片会变小,通道数会增加。
1.9 池化层
下图是最大池化,在每个作用区域内选择值最大的一个放在输出的方格上。当输入有多层时,对每一层都采用相同的操作,这样输入和输出的层数是相同的。最大池化的功能就是只要在任何一个象限内提取到某个特征,它都会保留在最大池化的输出里。最大池化运算的实际作用就是,如果在过滤器中提取到某个特征,那么保留其最大值,如果没有提取的这个特征,那么其最大值也是很小的。
下图是平均池化,平均池化没有最大池化应用的广泛。
需要注意的是,池化过程中的参数都是静态的,不需要进行学习。并且,卷积过程中计算维数的公式也可以应用在池化过程中。池化层的主要作用是特征降维,提高模型的鲁棒性。
1.10 卷积神经网络示例
一个卷积神经网络通常包含卷积层、池化层和全连接层,一般将卷积层和池化层作为一层。下图就是一个卷积神经网络的示例:
1.11 为什么使用卷积
与只使用全连接层相比,卷积层有两个优势:参数共享和稀疏连接。这样可以有效减少参数的数量。
二.实例探究
2.1 为什么要进行实例探究
下图是后面几节课的提纲:
2.2 经典网络
下图是LeNet-5神经网络的结构:
下图是AlexNet神经网络的结构:
下图是VGG-16神经网络的结构:每经过一次卷积和池化后图像大小减半,通道数加倍。
2.3 残差网络
下图是一个残差块,输入a[l]会传送到l+2层的线性部分之后,这样它会直接参加非线性部分的计算。
下图是一个残差神经网络的示例:对于一般的神经网络,当网络层数变多时,训练错误会先减少后增加,但是对于ResNet不会出现这种情况。
2.4 残差网络为什么有用?
残差网络起作用的主要原因就是这些残差块学习恒等函数非常容易,能够保证网络的性能不会收到影响,很多时候甚至可以提高效率,或者说至少不会降低网络效率,因此创建类似残差网络可以提升网络性能。一般卷积神经网络的结构都是几个卷积层后面跟一个池化层,在网络的最后还有一个或多个全连接层。
2.5 网络中的网络以及1*1卷积
下图中用对一个1*1*32的卷积对6*6*32的图像进行卷积操作,相当于对6*6个单元分别进行添加了一个全连接层。
正如下图所示,1*1卷积层可以减少或者增加图像的通道数,之前学习的池化层会减少图像的高度和宽度,但不会改变图像的通道数。
2.6 谷歌Inception网络简介
Inception模块的作用:代替人工确定卷积层中的卷积核大小或者确定是否需要创建卷积层和池化层。即不需要人为的决定使用哪个过滤器,是否需要池化层等,由网络自行决定这些参数,可以给网络添加所有可能值,将输出连接起来,网络自己学习它需要什么样的参数。因此可以使计算量大大减少,收敛更快。
由于使用Inception模块的计算量还是比较多的,上图中的网络是1.2亿次,所以可以在中间添加瓶颈层来减少运算量。下图的运算量为1240万次,约为上面运算量的十分之一。
2.7 Inception网络
下图就是一个Inception模块,一个Inception模块可能由很多不同的卷积核甚至池化层构成,它们都要采用same卷积方式,这样最后的输出才可以拼接在一起,为了避免池化层的通道数过多,在池化层后面还加上了一个1*1的卷积核来减少通道数。
下图是一个Inception神经网络,我们可以看到在下面的网络中有很多分支,这些分支的作用就是通过隐藏层来做出预测。它确保了即便是隐藏单元和中间层也参与了特征计算,它们也能预测图片的分类,它在Inception网络中起到了一种调整的效果,并且能够防止网络发生过拟合。
2.8 使用开源的实现方案
开发一个计算机视觉应用的常用工作流程:先选择一个你喜欢的架构,接着寻找一个开源实现,从GitHub下载下来,以此为基础开始构建。
2.9 迁移学习
如果我们可以要做一个下图这样的三分类神经网络,,我们可以使用开源的神经网络结构和初始权重,然后将网络的最后一层改为三分类的softmax层。在我们数据量比较少的情况下,我们可以选择将softmax层之前的层冰冻起来,即参数不变,这样只需要训练softmax层的参数。由于前面几层都冰冻起来了,即为静态参数,不需要训练,我们可以将softmax的输入数据计算出来,然后存入硬盘中,该数据是静态的,不会改变,所以只需要计算一次。这就可以使该深层网络简化为一个浅层网络。
如果我们拥有的数据更多,则网络需要冰冻的层数越少,但我们最好使用参考网络的权重作为初始权重,这样可以提高训练速度。
2.10 数据扩充
数据扩充(数据增强)可以弥补计算机视觉领域数据不足的问题。具体的数据扩充的方法如下:
镜像对称和随即裁剪
色彩转换
2.11 计算机视觉现状
在神经网络中主要依靠两部分,第一部分是被标记的数据,第二部分使是手工工程。当数据量较少时,需要的手工工程比较多,需要对神经网络进行精心的设计。
三.目标检测
3.1 目标定位
对于分类定位问题,通常只有一个较大的物体在图片的中央,我们需要识别该物体的类别并标记物体的位置。而对象检测问题在一张图片中可能会有多个不同类别的对象,我们需要识别各个物体的类别并标记位置。具体如下图:
对于目标定位问题,我们通常要输出该物体的类别以及物体中心点的坐标和宽高。
该目标定位神经网络要输出8个值,分别是图中是否有目标对象(pc)、目标对象的坐标(bx、by)、目标对象的宽和高(bh、bw)和三种类别物体的可能性(c1、c2、c3)。当pc=1时,下面7个值是有效的;当pc=0时,下面7个值是无效的。所以这也就对应着两种代价函数的计算公式,这里代价函数使用的是平方差。
3.2 特征点检测
如果我们想要做人脸识别或者人体姿态检测,我们可以人为设置一些特征点,在训练集上标记处特征点的位置用来训练,这样在输出时就可以输出标记点的位置,要注意训练集上标记点要前后一致。
3.3 目标检测
这里介绍的是基于滑动窗口的目标检测方法。训练集是类似于图像分类的,标记图片中是否有汽车。
具体检测时是选定一个检测窗口大小以及步长,然后从图片的左上角开始依次将检测窗口中的图像输入到网络中。这种检测方法存在问题:当选择的步长过大时,检测效果可能不是很好,但当步长过小时,需要的运算量会很大。
3.4 卷积的滑动窗口实现
要实现的卷积的滑动窗口,我们首先要将之前神经网络中的全连接层转化为卷积层。具体如下图,通过设置相应的卷积核就可以实现这样的操作:
如果我们在选择的检测窗口大小是14*14*3,那我们训练集中的图片大小与检测窗口的大小相同。按照上一节的方法,假如我们输入的图片大小是16*16*3,选择的步长为2,则我们先从图片的左上角开始选择一个检测窗口,然后输入到网络中输出分类结果,然后右移两个单元,在重复上面的方法,然后再移动,这样的操作要重复4次。但这种方法会有很多重复的运算。所以我们采用卷积层代替全连接层,不再按检测窗口输入图片,而是将整个图片一起输入到网络中,这样重复的部分会共享结果,不会重复运算。就如下图中的第二个网络最后输出的是一个2*2*4的矩阵,每一个1*1*4的矩阵相当于之前网络的一个输出。
3.5 Bounding Box预测
下图展示了滑动窗口在目标检测方面的问题,即不能准确识别目标的边界。
YOLO算法可以很好的解决图像边界的问题。这里我们将图片分成9个部分,当然分的越细检测的越精准,我们按对象中心点所在的方块决定对象所属的方块。对于每一个方块,我们都要输出8个值,分别是是否有物体、物体的坐标、物体的宽高和属于各个种类的概率。我们并不是将方块一个一个输入,而是对整个图像整体进行输入,这样会加快计算速度。
3.6 交并比
交并比函数用来评价对象检测算法表现是否良好。在下图中,红框是对象的实际边界,紫框是对象检测算法检测出来的边界,交并比函数的计算方法就是用两个边界交集的大小除以两个边界并集的大小。一般当交并比(IOU)>0.5时可以接受,如果交并比=1,则两个边界完美重合。
3.7 非极大值抑制
如下图,由于我们会先将图片划分称很多小网格,所以可能出现一个对象在很多网格中的情况,这样一个对象就会被检测多次,因为有多个网格会认为该对象在自己的区域内,同时输出多个对象边界,但在下图中实际上只有两个对象,所以我们的目标是输出两个对象边界。这里采用的方法就是非极大值抑制。
下图我们做的是汽车检测,只有汽车和非汽车两种可能,所以不需要c1、c2、c3。具体方法:先将pc值小于0.6的边框去除,然后选取剩余边框中pc值最大的边框输出,将与该边框交并比小于0.5的边框去除。然后循环选取剩余边框中pc值最大的,重复上述操作。如果是多目标检测,则最好对每一个目标独立进行上述过程。
3.8 Anchor Box
之前算法存在一个问题:一个格子只能检测一个对象。所以这里我们引入了anchor box,我们可以根据要检测对象的形状认为设定anchor box的形状,anchor box可以有多个。如下图,行人和汽车的中心点位于一个方格中,这是就要根据汽车和行人的形状设定两个anchor box,此时神经网络的输出不再是8维的,而是16维,其中上面8维是anchor box1的,下面8维是anchor box2的。至于如何判定对象输入anchor box1还是anchor box2,通过检测出目标的形状于anchor box的形状取交并比来判定。
anchor box可以使网络更具有针对性。但是也存在一些问题:
1.如果你设定了两个anchor box,但是一个网格中有三个对象,anchor box将无法很好的解决。
2.如果两个相同的对象在同一个anchor box中,anchor box也无法很好的解决。
3.9 YOLO算法
如果我们要做一个识别三个对象的目标检测网络,分别是行人、汽车和摩托车。我们将输入图像划分称3*3的网格。然后遍历每个网格进行目标检测。这里我们设定两个anchor box,所以网络最后会输出一个3*3*2*8的矩阵。
由于我们选择的是两个anchor box,所以每个网格都会有两个边框,注意:这里的边框并不一定要在一个网格内,也可以超出。然后若边框的pc值小于设定的阈值则删除,然后再根据非极大值抑制算法进行筛选,最后输出结果。
3.10 候选区域
R-CNN算法,也被称为带区域的CNN算法。它将目标检测分为两个过程,首先根据图像分割选出候选区域,然后对候选区域进行分类。
下面使R-CNN的改进版:
四.特殊应用:人脸识别和神经风格转换
4.1 什么是人脸识别
吴恩达老师在视频开头展示了百度开发的人脸识别系统,该系统用到了人脸识别和活体检测技术。
下面解释一下人脸验证和人脸识别:
人脸验证做的是1:1的对比,可以简单理解为证明你就是你。就是我们先告诉人脸识别系统,我是张三,然后用来验证站在机器面前的“我”到底是不是张三。
人脸识别做的是1:N的对比,即系统采集了“我”的一张照片之后,从海量的人像数据库中找到与当前使用者人脸数据相符合的图像,并进行匹配,找出来“我是谁”。
4.2 One-Shot学习
对于人脸识别来说,最难的是要解决一次学习的问题,即仅仅通过一张照片或一个人脸样例就能去识别这个人。
如果我们想要用softmax网络做识别4个人的人脸识别系统,那softmax的输出值可能有5个,但是这样的系统存在问题,如果我们要再加入一个人,那我们需要让softmax单元有6个输出,此时需要重新训练网络。
所以使用softmax网络做人脸识别系统是不可行的,下图提供了一种新的方法,即学习一个d函数(similarity function)。该函数是一个差异度函数,函数的输入是两张图片,该函数可以计算出两个图片的差异度,当差异度小于等于给定的阈值时,我们认为两张图片是同一个人,大于时为不同的人。但我们训练好d函数之后,我们令要检测图片为函数输入img1,然后遍历人脸数据库中的图片作为函数输入img2,然后分别输出差异度的值,根据差异度的值和阈值来进行人脸识别。
4.3 Siamese网络
我们定义一个网络,假设经过卷积层、池化层和全连接层后会输出一个128维的特征值f(x1),则该特征值就是输入图像x1的特征值,然后我们再将另一张图片x2输入进相同参数的网络,也输出一个128维的特征值f(x2),假如输出的特征值可以很好的表示输入图片,我们可以定义d函数为f(x1)和f(x2)之间的欧氏距离。当两张图片为同一个人时,d函数的输出值很小,当两张图片不为同一个人时,d函数的输出值很大。
所以我们该如何训练这个神经网络呢?Siamese网络学习的是编码函数f(x),即输出的是图片的特征向量。在训练的时候,我们定义的代价函数是两张图片特征向量的欧氏距离,我们训练的目的是使相同图片的代价函数小,不同图片的代价函数大,以此为依据进行反向传播。
4.4 Triplet损失
要使用三元组损失函数,我们需要将三张图片作为一组,其中第一张图片为anchor,第二张图片是positive,表示和第一张图片为同一个人,第三张图片为negative,表示和第一张图片不为同一张函数。我们的目的是使d(A,P)-d(A,N)+α<=0,这里的α为一个超参数。
损失函数的定义如下:
但是这个网络也存在一些问题,就是我们在训练网络时最好使三元组中d(A,P)与d(A,N)接近,这样会使网络训练起来更有效率,因为如果d(A,P)与d(A,N)本身就相差很大的话,网络训练起来太轻松了,也不会有很好的效果。
4.5 面部验证与二分类
除了上节课中介绍的使用三元组的方法进行人脸识别,也可以将人脸识别作为一个二分类问题,输出为1时表示是同一个人,输出为0时表示不是同一个人。这里采用一对完全相同的神经网络,输入一对图像,分别计算输入图像的特征向量,然后将两个特征向量输入到sigmoid单元中进行计算,具体计算公式见下图。
同时,对于这种二分类人脸识别算法还有一种技巧,假设图片x(i)是人脸数据库中的图片,我们可以不用每次计算人脸数据库中图片的特征值,而是预先计算好后作为静态数据存入数据库中,在识别时直接输入sigmoid单元即可。
4.6 什么是神经风格转换
下图是神经风格转换的两个例子,我们C来表示内容图像,用S来表示风格图像,用G来表示生成图像。
4.7 什么是深度卷积网络
我们选取能够最好激活隐藏单元的图片块,从中可以发现,浅层神经网络层学习的是边缘一类比较小的特征,而深层神经网络层学习的图像区域会更大,学习的特征也会更加全面。
4.8 代价函数
神经风格转换的输入需要两张照片,分别是内容图像和风格图像。所以代价函数也包含两个部分,一部分是内容代价,它用来衡量内容图片与生成图片之间的相似度,另一部分是风格代价,它用来衡量风格图片与生成图片之间的相似度,同时还有两个超参数。
具体神经风格转换算法的过程:先生成一个初始的生成图片,然后通过正向以及反向传播使代价函数变小。
4.9 内容代价函数
对于内容代价,我们要先选择一个隐含层来进行计算,这里一般选择中间层;然后使用一个预训练的网络,比如VGG;之后通过比较内容图像第l层的激活值和生成图像第l层的激活值来计算内容代价,当内容图像和生成图像相似时,使内容代价比较小。这里可以使用L2范式。
4.10 风格代价函数
如果我们使用第l层来定义风格代价,那么我们将风格代价定义为跨通道激活值之间的相关性。如下图,图像含有5个通道,所谓相关性的含义是:如果红色通道识别的是竖线,黄色通道识别的是橙色,则如果红色通道和黄色通道的相关性比较高,那么出现竖线时橙色出现的可能比较大,如果红色通道与黄色通道的相关性比较低,则出现竖线时一般不会出现橙色。
要计算风格代价,首先要计算出风格矩阵,求出风格图像和生成图像的风格矩阵,然后如下图求解风格代价。
4.11 一维到三维推广
使用一维的卷积核可以对一维数据进行卷积操作。
使用三维卷积核可以对三维数据进行卷积操作。