记录吴恩达Andrew Ng深度学习专项课程笔记,方便之后回顾,共5门课。第一门课《神经网络与深度学习》(Neural Networks and Deep Learning)的4周课程笔记请见如下链接:
1-1 Coursera吴恩达《神经网络与深度学习》第一周课程笔记-深度学习概论
1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础
1-3 Coursera吴恩达《神经网络与深度学习》第三周课程笔记-浅层神经网络
1-4 Coursera吴恩达《神经网络与深度学习》第四周课程笔记-深层神经网络
第二门课《改善深度神经网络》(Improving Deep Neural Networks: Hyperparameter tuning, Regularization and Optimization)的3周课程笔记请见如下链接:
2-1 Coursera吴恩达《改善深度神经网络》 第一周课程笔记-深度学习的实践方面
2-2 Coursera吴恩达《改善深度神经网络》第二周课程笔记-优化算法
2-3 Coursera吴恩达《改善深度神经网络》第三周课程笔记-超参数调试、Batch正则化和编程框架
第三门课《构建机器学习项目》(Structuring Machine Learning Projects)的2周课程笔记请见如下链接:
3-1 Coursera吴恩达《构建机器学习项目》 第一周课程笔记-机器学习策略(1)
3-2 Coursera吴恩达《构建机器学习项目》 第二周课程笔记-机器学习策略(2)
今天开始介绍第四门课:大名鼎鼎的卷积神经网络!这是第四门课《卷积神经网络》(Convolutional Neural Networks)第一周卷积神经网络基础的课程笔记,主要介绍卷积神经网络(CNN)的基本概念、模型和具体应用,能够让我们更深入的了解卷积神经网络,该门课共四周,那我们开始吧。
目录
《1.1 计算机视觉》 Computer Vision
《1.2 边缘检测示例》 Edge Detection Example
《1.3 更多边缘检测内容》More Edge Detection
《1.4 Padding》Padding
《1.5 卷积步长》 Strided Convolutions
《1.6 三维卷积》Convolutions Over Volume
《1.7 单层卷积网络》One Layer of a Convolutional Network
《1.8 简单卷积网络示例》Simple Convolutional Network Example
《1.9 池化层》Pooling Layers
《1.10 卷积神经网络示例》Convolutional neural network Example
《1.11 为什么使用卷积?》 Why Convolutions
Summary
计算机视觉(computer vision)是一个飞速发展的一个领域,这多亏了深度学习(deep learning)。深度学习与计算机视觉可以帮助汽车,查明周围的行人和汽车,并帮助汽车避开它们。还使得人脸识别技术变得更加效率和精准,你们即将能够体验到或早已体验过仅仅通过刷脸就能解锁手机或者门锁。机器学习甚至还催生了新的艺术类型。深度学习之所以让Andrew兴奋有下面两个原因:
第一,计算机视觉的高速发展标志着新型应用产生的可能,这是几年前,人们所不敢想象的。通过学习使用这些工具,你也许能够创造出新的产品和应用。
第二,人们对于计算机视觉的研究是如此富有想象力和创造力,由此衍生出新的神经网络结构与算法(neural network architectures and algorithms),这实际上启发人们去创造出计算机视觉与其他领域的交叉成果(cross-fertilization)。
例如,图片分类(image classification),或者图片识别(image recognition)。比如(左上方)给出这张64×64的图片,让计算机去分辨出这是一只猫。还有一个例子(左下方),在计算机视觉中有个问题叫做目标检测(object detection),比如在一个无人驾驶项目中,你不一定非得识别出图片中的物体是车辆,但你需要计算出其他车辆的位置,以确保自己能够避开它们。还有一个更有趣的例子(右上方),就是神经网络实现的图片风格迁移(neural style transfer),比如说你有一张图片,但你想将这张图片转换为另外一种风格。
但在应用计算机视觉时要面临一个挑战,就是数据的输入可能会非常大。
举个例子,在过去的课程中,一般操作的都是64×64的小图片,实际上,它的数据量是64×64×3,因为每张图片都有3个颜色通道(color channels)。如果计算一下的话,可得知数据量为12288,所以我们的特征向量维度为12288。这其实还好,因为64×64真的是很小的一张图片。如果你要操作更大的图片,比如一张1000×1000的图片,它足有1兆(one megapixel)那么大,但是特征向量的维度达到了1000×1000×3,因为有3个RGB通道,所以数字将会是300万。如果你要输入300万的数据量,这就意味着,特征向量的维度高达300万(three million)。所以在第一隐藏层中,你也许会有1000个隐藏单元,如果你使用了标准的全连接网络(standard fully connected network),权重矩阵W[1]的大小将会是1000×300万,有30亿个参数。
在参数如此大量的情况下,难以获得足够的数据来防止神经网络发生过拟合和竞争需求。为此,你需要进行卷积计算,它是卷积神经网络中非常重要的一块。
卷积运算(convolutional operation)是卷积神经网络最基本的组成部分(fundamental building blocks),使用边缘检测(edge detection)作为入门样例(motivating example)。接下来,你会看到卷积是如何进行运算的。
在之前的人脸例子中,我们知道神经网络的前几层是如何检测边缘的,然后,后面的层有可能检测到物体的部分区域,更靠后的一些层可能检测到完整的物体。让我们举个例子(下方),给了这样一张图片,让电脑去搞清楚这张照片里有什么物体,你可能做的第一件事是检测图片中的垂直边缘(vertical edges)和水平边缘(horizontal edges)。所以如何在图像中检测这些边缘?
这是一个6×6的灰度图像(grayscale image)。因为是灰度图像,所以它是6×6×1的矩阵,为了检测图像中的垂直边缘,需要构造一个3×3矩阵。在共用习惯中,在卷积神经网络的术语中,它被称为过滤器(filter),也被称为核(kernel)。对这个6×6的图像进行卷积运算,卷积运算用星号“*”(asterisk)来表示,用3×3的过滤器对其进行卷积。python中,卷积用conv_forward()表示;tensorflow中,卷积用tf.nn.conv2d()表示;keras中,卷积用Conv2D()表示。
在过滤器覆盖的区域执行:每个元素对应相乘再求和,这个卷积运算的输出将会是一个4×4的矩阵,这个就是垂直边缘检测器。为什么这样可以做垂直边缘检测呢?看另外一个例子。
这是一个简单的6×6图像,左边的一半是10,右边一般是0。如果你把它当成一个图片,左边那部分看起来是白色的,像素值10是比较亮的像素值,右边像素值比较暗,我使用灰色来表示0,尽管它也可以被画成黑的。图片里,有一个特别明显的垂直边缘在图像中间,这条垂直线是从黑到白的过渡线,或者从白色到深色。
如果你用一个1000×1000的图像,而不是6×6的图片,可以很好地检测出图像中的垂直边缘。在这个例子中,在输出图像中间的亮处,表示在图像中间有一个特别明显的垂直边缘。从垂直边缘检测中可以得到的启发是,因为使用3×3的矩阵(过滤器),所以垂直边缘是一个3×3的区域,左边是明亮的像素(bright pixels),中间的并不需要考虑,右边是深色像素(dark pixels)。在这个6×6图像的中间部分,明亮的像素在左边,深色的像素在右边,就被视为一个垂直边缘,卷积运算提供了一个方便的方法来发现图像中的垂直边缘。
在本视频中,你将学习如何区分正边和负边,这实际就是由亮到暗(light to dark)与由暗到亮(dark to light)的区别,也就是边缘的过渡(edge transitions)。
还是上一个视频的例子。这张6×6的图片,左边较亮,而右边较暗,将它与垂直边缘检测滤波器进行卷积,检测结果就显示在了右边这幅图的中间部分。现在将图片进行翻转,变成了左边比较暗,右边比较亮。从结果可以看到这个过滤器确实可以区分这两种明暗变化的区别。
左边的垂直边缘过滤器(vertical edge detection)是一个3×3的区域,左边相对较亮,而右边相对较暗。右边这个水平边缘过滤器(horizontal edge detection)也是一个3×3的区域,上边相对较亮,而下方相对较暗。
还有个更复杂的例子,左上方和右下方都是亮度为10的点。如果你将它绘成图片,右上角是比较暗的地方,这边都是亮度为0的点,把这些比较暗的区域都加上阴影。而左上方和右下方都会相对较亮。如果你用这幅图与水平边缘过滤器卷积,就会得到右边这个矩阵。
再举个例子,这里的30(右边矩阵中绿色方框标记元素)代表了左边这块3×3的区域(左边矩阵绿色方框标记部分),这块区域确实是上边比较亮,而下边比较暗的,所以它在这里发现了一条正边缘(positive edge)。而这里的-30(右边矩阵中紫色方框标记元素)又代表了左边另一块区域(左边矩阵紫色方框标记部分),这块区域确实是底部比较亮,而上边则比较暗,所以在这里它是一条负边。
再次强调,现在使用的都是相对很小的图片,但假如这个一个非常大的1000×1000的类似这样棋盘风格的大图,就不会出现这些亮度为10的过渡带了,因为图片尺寸很大,这些中间值就会变得非常小。
总而言之,对于这个3×3的过滤器(左边)来说,这是其中的一种数字组合。也可以使用Sobel的过滤器(中间),它的优点在于增加了中间一行元素的权重,这使得结果的鲁棒性会更高一些。或者Scharr过滤器(右边),它有着和之前完全不同的特性,实际上也是一种垂直边缘检测,如果你将其翻转90度,你就能得到对应水平边缘检测。随着深度学习的发展,我们学习的其中一件事就是当你真正想去检测出复杂图像的边缘,你不一定要去使用那些研究者们所选择的这九个数字,但你可以从中获益匪浅。把这矩阵中的9个数字当成9个参数,并且在之后你可以学习使用反向传播算法,其目标就是去理解这9个参数。
所以这种将这9个数字当成参数的思想,已经成为计算机视觉中最为有效的思想(most powerful ideas)之一。在下面两节视频中,将讨论如何去使用padding,以及卷积各种不同的发展,这两节内容将会是卷积神经网络中卷积模块的重要组成部分(important pieces),所以下节视频再见。
为了构建深度神经网络,你需要学会使用的一个基本的卷积操作就是padding,下面来看看它是如何工作的。
如果你用一个3×3的过滤器卷积一个6×6的图像,你最后会得到一个4×4的输出,也就是一个4×4矩阵。这背后的数学解释是,如果我们有一个n×n的图像,用f×f的过滤器做卷积,那么输出的维度就是(n - f + 1) × (n - f + 1)。在这个例子里是6-3+1=4。
这样的话会有两个缺点,第一个缺点是每次做卷积操作,你的图像就会缩小。第二个缺点是那些在角落或者边缘区域的像素点在输出中采用较少,意味着你丢掉了图像边缘位置的许多信息。为了解决这两个问题,一是输出缩小,二是图像边缘的大部分信息都丢失了,你可以在卷积操作之前填充这幅图像。在这个案例中,你可以沿着图像边缘再填充一层像素。如果你这样操作了,那么6×6的图像就被你填充成了一个8×8的图像。如果你用3×3的图像对这个8×8的图像卷积,你得到的输出就不是4×4的,而是6×6的图像,就得到了一个尺寸和原始图像6×6的图像。习惯上,你可以用0填充,如果p表示填充的数量,在这个例子中,p=1,因为在周围都填充了一个像素点。输出维度变成了(一般向下取整):
这样一来,丢失信息或者更准确来说角落或图像边缘的信息发挥的作用较小的这一缺点就被削弱了。
如果你想的话,也可以填充两个像素点。至于选择填充多少像素,通常有两个选择,分别叫做Valid卷积和Same卷积。
Valid卷积意味着不填充。另一个经常被用到的填充方法叫做Same卷积,那意味你填充后,你的输出大小和输入大小是一样的。利用n+2p-f+1=n求解,使得输出和输入大小相等,那么p = (f - 1)/2。
习惯上,计算机视觉中,f通常是奇数,甚至可能都是这样。你很少看到一个偶数的过滤器在计算机视觉里使用,Andrew认为有两个原因。
其中一个可能是,如果f是一个偶数,那么你只能使用一些不对称填充(asymmetric padding)。只有是奇数的情况下,Same卷积才会有自然的填充,我们可以以同样的数量填充四周,而不是左边填充多一点,右边填充少一点,这样不对称的填充。
第二个原因是当你有一个奇数维过滤器(odd dimension filter),比如3×3或者5×5的,它就有一个中心点(central position)。有时在计算机视觉里,如果有一个中心像素点(central pixel)会更方便,便于指出过滤器的位置。习惯上,Andrew推荐你只使用奇数的过滤器。
总之,你已经看到如何使用padding卷积,为了指定卷积操作中的padding,你可以指定p的值。也可以使用Valid卷积,也就是p=0。也可使用Same卷积填充像素,使你的输出和输入大小相同。以上就是padding,在接下来的视频中我们讨论如何在卷积中设置步长。
卷积中的步长(strided convolutions)是另一个构建卷积神经网络的基本操作,看下面一个例子。
如果你想用3×3的过滤器卷积这个7×7的图像,和之前不同的是,我们把步幅设置成了2。注意一下左上角,这个点移动到其后两格的点,跳过了一个位置。然后你还是将每个元素相乘并求和,你将会得到的结果是100。依次类推,得到最终结果。如果你使用一个f x f的过滤器卷积一个n x n的图像,padding为p,步幅为s,这样输出的大小变为:
在这个例子中,n = 7,p = 0, f = 3,s = 2,(7 + 0 - 3)/2 + 1 = 3,即3×3的输出。
注意一个细节,如果商(fraction)不是一个整数(integer),则向下取整。这个原则实现的方式是,你只在蓝框完全包括在图像或填充完的图像内部时,才对它进行运算。如果有任意一个蓝框移动到了外面,那就不要进行相乘操作,这是一个惯例(convention)。3×3的过滤器必须完全处于图像中或者填充之后的图像区域内才输出相应结果。
总结一下维度情况,一个n x n的图像或者矩阵,与一个f x f的过滤器卷积,padding为p,步幅为s,这样输出的大小如上图。
(这一部分了解即可)如上图,这里有一个关于互相关(cross-correlation)和卷积(convolution)的技术性建议(technical comment)。这不会影响到你构建卷积神经网络的方式,但取决于你读的是数学教材(math textbook)还是信号处理教材(signal processing textbook)。在数学教材中,卷积首先将3 x 3的过滤器沿水平和垂直轴翻转,然后再用这个翻转的矩阵进行元素乘积求和,而我们在视频中定义卷积运算时,跳过了这个镜像操作(mirroring operation)。从技术上讲,我们在前面视频中使用的操作,有时被称为互相关(cross-correlation)而不是卷积(convolution)。但在深度学习文献中,按照惯例,我们将(不进行翻转操作)叫做卷积操作。因此我们将在这些视频中使用这个约定。如果你读了很多机器学习文献的话,你会发现许多人都把它叫做卷积运算,不需要用到这些翻转。
事实证明在信号处理中或某些数学分支中,在卷积的定义包含翻转,使得卷积运算符拥有这个性质(enjoy this property),即结合律(associativity):
这一性质对深度神经网络来说并不重要,因此省略了这个双重镜像操作(omitting this double mirroring operation),既简化了代码,又使神经网络也能正常工作。
现在已经了解了如何进行卷积,以及如何使用填充,如何在卷积中选择步幅。但到目前为止,我们所使用的是关于矩阵的卷积。在下一集视频中,将看到如何对立体进行卷积,这将会使你的卷积变得更加强大,让我们继续下一个视频。
现在看看如何执行卷积不仅仅在二维(2D)图像上,而是三维立体(three dimensional volumes)上。
假如说你不仅想检测灰度图像的特征,也想检测RGB彩色图像(红、绿、蓝)的特征。彩色图像如果是6×6×3,这里的3指的是三个颜色通道(可以想象成三个6×6图像的堆叠)。为了检测图像的边缘或者其他的特征,不是把它跟原来的3×3的过滤器做卷积,而是跟一个三维的过滤器,它的维度是3×3×3,这样这个过滤器也有三层,对应红绿、蓝三个通道。
注意这些名字,第一个6代表图像高度(height),第二个6代表宽度(width),这个3代表通道的数目(channels)。同样过滤器(filter)也有高,宽和通道数,并且图像的通道数必须和过滤器的通道数匹配,所以这两个数(紫色方框标记的两个数)必须相等。
这个是6×6×3的图像,这个是3×3×3的过滤器,最后一个数字通道数必须和过滤器中的通道数相匹配。为了简化这个3×3×3过滤器的图像,画成一个三维的立方体。为了计算这个卷积操作的输出,你要做的就是把这个3×3×3的过滤器先放到最左上角的位置(upper left most position),这个3×3×3的过滤器有27个数,27个参数就是3的立方。依次取这27个数,然后乘以相应的红绿蓝通道中的数字。先取红色通道的前9个数字,然后是绿色通道,然后再是蓝色通道,乘以左边黄色立方体覆盖的对应的27个数,然后把这些数都加起来,就得到了输出的第一个数字。计算下一个输出,则把立方体滑动一个单位,再分别与27个数相乘求和,依次类推。
不同通道的滤波算子可以不相同。如果你想检测图像红色通道的边缘,那么可以设置绿色和蓝色通道的元素全部为0。或者也可以将三个通道的过滤器全部设置为水平边缘检测。
按照计算机视觉的惯例,当你的输入有特定的高宽和通道数时,你的过滤器可以有不同的高,不同的宽,但是必须一样的通道数。理论上,我们的过滤器只关注红色通道,或者只关注绿色或者蓝色通道也是可行的。同时注意一下,一个6×6×6的输入图像卷积上一个3×3×3的过滤器,得到一个4×4的二维输出。
现在还有一个概念至关重要。我们不仅仅想要检测垂直边缘怎么办?如果我们同时检测垂直边缘和水平边缘,还有45°倾斜的边缘,还有70°倾斜的边缘怎么做?换句话说,如果你想同时用多个过滤器怎么办?(第一个黄色表示)这可能是一个垂直边界检测器或者是学习检测其他的特征。第二个过滤器橘色表示,它可以是一个水平边缘检测器。这样的输出是一个4×4×2的立方体,这里的2的来源于用了两个不同的过滤器。
总结一下维度,如果有一个n × n × n_c的输入图像,这里是6×6×3,这里n_c是通道数目,然后卷积一个f × f × n_c,这里是3×3×3,然后得到结果的维度为(假设步幅是1,并且没有padding):
更重要的是,你可以检测两个特征,比如垂直和水平边缘或者10个或者128个或者几百个不同的特征,并且输出的通道数会等于你要检测的特征数。
这里的n_c(通道数)表示最后一个维度,文献中也称深度(depth)。在这些视频里Andrew会用通道这个术语来表示过滤器的第三个维度的大小。
这个视频讲的是如何构建卷积神经网络的卷积层(convolutional layer),看一个例子。
上个视频,我们知道如何通过两个过滤器卷积处理一个三维图像,并输出两个不同的4×4矩阵。假设使用第一个过滤器进行卷积,得到第一个4×4矩阵,形成一个卷积神经网络层,然后增加偏差(bias),它是一个实数(real number),通过Python的广播机制给这16个元素都加上同一偏差。然后应用非线性函数,它是一个非线性激活函数ReLU,输出结果是一个4×4矩阵。
对于第二个4×4矩阵,我们加上不同的偏差,它也是一个实数,16个数字都加上同一个实数,然后应用非线性函数,也就是一个非线性激活函数ReLU,最终得到另一个4×4矩阵。重复我们之前的步骤,把这两个矩阵堆叠起来,最终得到一个4×4×2的矩阵。我们通过计算,从6×6×3的输入推导出一个4×4×2矩阵,它是卷积神经网络的一层,把它映射到标准神经网络中四个卷积层中的某一层或者一个非卷积神经网络中。
注意向前传播的一个操作是:
这里的过滤器用变量W^[1]表示。卷积的输出结果是一个4×4矩阵,它的作用类似于W^[1]*a^[0],然后加上偏差。这一部分(图中蓝色边框标记的部分)就是应用激活函数ReLU之前的值,它的作用类似于z^[1],最后应用非线性函数(non-linearity),得到的这个4×4×2矩阵,成为神经网络的下一层,也就是激活层(activation layer)。
这就是a^[0]到a^[1]的演变过程,首先执行线性函数,然后所有元素相乘做卷积,具体做法是运用线性函数再加上偏差,然后应用激活函数ReLU。这样就通过神经网络的一层把一个6×6×3的维度a^[0]演化为一个4×4×2维度的a^[1],这就是卷积神经网络的一层。
这个示例中有两个过滤器(两个特征),因此最终得到一个4×4×2的输出。如果我们用了10个过滤器,而不是2个,最后会得到一个4×4×10维度的输出图像,因为我们选取了其中10个特征映射。
为了加深理解,做一个练习。
假设你有10个过滤器,神经网络的一层是3×3×3,那么,这一层有多少个参数呢?下面来计算一下,每一层都是一个3×3×3的矩阵,因此每个过滤器有27个参数,然后加上一个偏差,用参数b表示,现在参数为28个。上一页幻灯片里有2个过滤器,而现在有10个,加在一起是28×10,也就是280个参数。注意一点,无论输入的图片多大,参数始终是280个。用这10个过滤器来提取特征,如垂直边缘,水平边缘和其它特征。即使这些图片很大,参数却很少,这就是卷积神经网络的一个特征,叫作“避免过拟合”。
最后总结一下,用于描述卷积神经网络的一层,例如l层,的各种标记。
其中,上标[l]用来标记l层,f^[l]表示过滤器大小,p^[l]表示padding的数量,s^[l]表示步幅。输入为上一层的激活值,所用图片的高度和宽度可能不同,分别用下标H和W标记,即:
输出图像的大小为:
联系之前的内容,l层输出图像的高度和宽度分别为:
那么通道数量又是什么?这些数字从哪儿来的?我们知道输出图像也有深度,它等于该层中过滤器的数量。如果有2个过滤器,输出图像就是4×4×2,它是二维的,如果有10个过滤器,输出图像就是4×4×10。输出图像中的通道数量就是神经网络中这一层所使用的过滤器的数量。因此,输出通道数量就是输入通道数量,所以过滤器维度为:
加上偏差和应用非线性函数之后,这一层的输出等于它的激活值a^[l],它的输出维度为:
当你执行批量梯度下降或小批量梯度下降算法时,如果有m个例子,就是有m个激活值的集合,那么输出表示为:
如果采用批量梯度下降(batch gradient descent),变量的排列顺序如下:首先是索引(index)和训练示例(training examples),然后是其它三个变量(these three variables)。
该如何确定权重参数(weights parameters),即参数W呢?权重也就是所有过滤器的集合再乘以过滤器的总数量,即
最后我们看看偏差参数(bias parameters),每个过滤器都有一个偏差参数,它是一个实数。偏差包含了这些变量,它是该维度上的一个向量。后续为了方便,偏差表示为一个的四维矩阵(four dimensional matrix)或四维张量(four dimensional tensor),即
注意一下,大家在线搜索或查看开源代码时,关于高度,宽度和通道的顺序并没有完全统一的标准卷积,有些作者会采用把通道放在首位的编码标准。实际上在某些架构中,当会有一个变量(variable)或参数(parameter)来标识计算通道数量和通道损失数量的先后顺序。只要保持一致,这两种卷积标准都可用。课上Andrew会采用这种卷积标识法,按高度,宽度和通道损失数量的顺序依次计算。
这节课的重点是,卷积神经网络的某一卷积层的工作原理,以及如何计算某一卷积层的激活函数,并映射到下一层的激活值。了解了卷积神经网络中某一卷积层的工作原理,我们就可以把它们堆叠起来形成一个深度卷积神经网络,我们下节课讨论。
假设有一张图片,你想做图片分类(image classification)或图片识别(image recognition),输入定义为x,输出为0或1,来判断有没有猫。这里用了一张比较小的图片,大小是39×39×3,高度和宽度都等于39,第0 层的通道数为3。符号为:
假设第一层用一个3×3的过滤器来提取特征,步长为1,采用valid卷积,有10个过滤器,则输出为:
这(37×37×10)是第一层激活值的维度。
然后下一个卷积层,这次我们采用的过滤器是5×5的矩阵,步幅为2,p=0,有20个过滤器,则输出为:
这(17×17×20)是第一层激活值的维度。
最后一个卷积层,假设过滤器还是5×5,步幅为2,假设使用了40个过滤器。padding为0,40个过滤器,最后结果为7×7×40。
到此,这张39×39×3的输入图像就处理完毕了,为图片提取了7×7×40个特征,计算出来就是1960个特征。然后对该卷积进行处理,可以将其平滑或展开成1960个单元。平滑处理后可以输出一个向量,其填充内容是logistic回归单元(logistic regression unit)还是softmax回归单元(softmax unit),完全取决于我们是想识图片上有没有猫,还是想识别K种不同对象中的一种,用y帽表示最终神经网络的预测输出。明确一点,最后这一步是处理所有数字,即全部的1960个数字,把它们展开(unroll)成一个很长的向量。为了预测最终的输出结果,我们把这个长向量填充到softmax回归函数中。
这是卷积神经网络的一个典型范例(pretty typical example),设计卷积神经网络时,确定这些超参数比较费工夫。要决定过滤器的大小、步幅、padding以及使用多少个过滤器。这周和下周,Andrew会针对选择参数的问题提供一些建议和指导。
注意一点,随着网络加深,高度(height)和宽度(width)会在一段时间内保持一致,然后随着网络深度的加深而逐渐减小,从39到37,再到17,最后到7。而通道数量(channels)在增加,从3到10,再到20,最后到40。
如上图,一个卷积网络通常有三层,一个是卷积层(convolution layer),我们常常用Conv来标注。一个是池化层(pooling layer),我们称之为POOL。最后一个是全连接层(fully connected layer),用FC表示。虽然仅用卷积层也有可能构建出很好的神经网络,但大部分神经网络架构师依然会添加池化层和全连接层。幸运的是,池化层和全连接层比卷积层更容易设计。后两节课我们会快速讲解这两个概念以便你更好的了解神经网络中最常用的这几种层,你就可以利用它们构建更强大的网络了。
除了卷积层,卷积网络也经常使用池化层来缩减模型的大小(reduce the size of their representation),提高计算速度(speed up computation),同时提高所提取特征的鲁棒性(robust),下面来看一下。
上面是池化层的例子,假设输入是4×4矩阵,池化类型是最大池化(max pooling)。执行最大池化的树池是一个2×2矩阵。执行过程非常简单,把4×4的输入拆分成不同的区域(不同区域用不同颜色来标记)。对于2×2的输出,输出的每个元素都是其对应颜色区域中的最大元素值。例如,左上区域的最大值是9,右上区域的最大元素值是2,左下区域的最大值是6,右下区域的最大值是3。这就像是应用了一个规模为2的过滤器,因为我们选用的是2×2区域,步幅是2,这些就是最大池化的超参数,即f = 2,s = 2。
这是对最大池化功能的直观理解,你可以把这个4×4输入看作是某些特征的集合,也许不是。你可以把这个4×4区域看作是某些特征的集合,也就是神经网络中某一层的非激活值集合。数字大意味着可能探测到了某些特定的特征,左上象限具有的特征可能是一个垂直边缘,一只眼睛,或是大家害怕遇到的CAP特征。显然左上象限中存在这个特征,这个特征可能是一只猫眼探测器。然而,右上象限并不存在这个特征。最大化操作的功能就是只要在任何一个象限内提取到某个特征,它都会保留在最大化的池化输出里。所以最大化运算的实际作用就是,如果在过滤器中提取到某个特征,那么保留其最大值。如果没有提取到这个特征,可能在右上象限中不存在这个特征,那么其中的最大值也还是很小,这就是最大池化的直观理解(intuition)。
必须承认,人们使用最大池化的主要原因是此方法在很多实验中效果都很好。
其中一个有意思的特点就是,它有一组超参数,但并没有参数需要学习。在实际操作中,一旦确定f和s,就是一个固定运算,梯度下降无需改变任何值。先看一下最终输出结果:
这是一个新的例子,输入是5×5的矩阵,采用最大池化法,过滤器参数为3×3,即f = 3,步幅为1,s = 1,输出矩阵是3×3。之前讲的计算卷积层输出大小的公式同样适用于最大池化,可以用来计算最大池化的输出大小,即
具体计算步骤可以查看:池化层
以上是一个二维输入的演示,如果输入是三维的,那么输出也是三维的。
例如,输入是5×5×2,那么输出是3×3×2。计算最大池化的方法就是分别对每个通道执行刚刚的计算过程。如上图,第一个通道保持不变,第二个通道做同样的运算,画在下面。
另外还有一种类型的池化,平均池化(average pooling),但是并不常用,运算时选取的不是每个过滤器的最大值,而是平均值。
上图的例子,紫色区域的平均值是3.75,后面依次是1.25、4和2。这个平均池化的超级参数f = 2,s = 2,我们也可以选择其它超级参数。目前来说,最大池化比平均池化更常用。但也有例外,就是深度很深的神经网络,你可以用平均池化来分解规模为7×7×1000的网络的表示层,在整个空间内求平均值,得到1×1×1000。
现在总结一下,如上图,池化的超级参数包括过滤器大小和步幅,常用的参数值为f = 2,s = 2,应用频率非常高,其效果相当于高度和宽度缩减一半。也有使用f =3,s=2的情况。至于其它超级参数就要看你用的是最大池化还是平均池化了。最大池化时,往往很少用到超参数padding,当然也有例外的情况。假设没有padding,最大池化的输入和输出分别为:
需要注意的一点是,池化过程中没有需要学习的参数。执行反向传播时,反向传播没有参数适用于最大池化。只有这些设置过的超参数(f,s),可能是手动设置的,也可能是通过交叉验证设置的。
现在,池化层的内容就讲完了,它只是计算神经网络某一层的静态属性(fixed function)。现在我们已经知道如何构建卷积层和池化层了。下节课,我们会分析一个更复杂的可以引进全连接层的卷积网络示例。
如上图,假设有一张大小为32×32×3的输入图片,这是一张RGB模式的图片,你想做手写体数字识别。32×32×3的RGB图片中含有某个数字,比如7,你想识别它是从0-9这10个数字中的哪一个,我们构建一个神经网络来实现这个功能。Andrew用的这个网络模型和经典网络LeNet-5非常相似,灵感也来源于此。
输入是32×32×3的矩阵。①假设第一层使用过滤器大小为5×5,步幅是1,padding是0,过滤器个数为6,那么输出为28×28×6。将这层标记为CONV1,它用了6个过滤器,增加了偏差,应用了非线性函数,可能是ReLU非线性函数,最后输出CONV1的结果。②构建一个池化层,这里选择用最大池化(max pooling),参数f = 2,s = 2,padding为0,最大池化使用的过滤器为2×2,步幅为2,表示层的高度和宽度会减少一半。因此,28×28变成了14×14,通道数量保持不变,所以最终输出为14×14×6,将该输出标记为POOL1。
补充内容:人们发现在卷积神经网络文献中,卷积有两种分类,这与所谓层的划分存在一致性(consistence)。(1)一类卷积是一个卷积层和一个池化层一起作为一层,这就是神经网络的Layer1。(2)另一类卷积是把卷积层作为一层,而池化层单独作为一层。人们在计算神经网络有多少层时,通常只统计具有权重和参数的层。因为池化层没有权重和参数,只有一些超参数。这里,我们把CONV1和POOL1共同作为一个卷积,并标记为Layer1。
③再构建一个卷积层,过滤器大小为5×5,步幅为1,这次我们用10个过滤器,最后输出一个10×10×10的矩阵,标记为CONV2。
④然后最大池化(max pooling),参数f =2,s=2,高度和宽度会减半,最后输出为5×5×10,标记为POOL2,这就是神经网络的第二个卷积层,即Layer2。
new③如果对Layer1应用另一个卷积层,过滤器为5×5,即f=5,步幅是1,padding为0,所以这里省略了,过滤器16个,所以CONV2输出为10×10×16。我们看看CONV2,这是CONV2层。
new④继续执行做大池化计算,参数f =2,s=2,你能猜到结果么?对10×10×16输入执行最大池化计算,参数f =2,s=2,高度和宽度减半,结果为5×5×16,通道数和之前一样,标记为POOL2。这是一个卷积,即Layer2,因为它只有一个权重集和一个卷积层CONV2。
new⑤5×5×16矩阵包含400个元素,现在将POOL2平整化为一个大小为400的一维向量。然后利用这400个单元构建下一层。下一层含有120个单元,这就是我们第一个全连接层(full connection),标记为FC3。这400个单元与120个单元紧密相连,这就是全连接层。它的权重矩阵为W^[3],维度为120×400。这就是所谓的“全连接”,因为这400个单元与这120个单元的每一项连接,还有一个偏差参数。最后输出120个维度,因为有120个输出。
new⑥然后我们对这个120个单元再添加一个全连接层,这层更小,假设它含有84个单元,标记为FC4。
new⑦最后,用这84个单元填充一个softmax单元。如果我们想通过手写数字识别来识别手写0-9这10个数字,这个softmax就会有10个输出。
此例中的卷积神经网络很典型,看上去它有很多超参数,关于如何选定这些参数,后面Andrew提供更多建议。常规做法是,尽量不要自己设置超参数,而是查看文献中别人采用了哪些超参数,选一个在别人任务中效果很好的架构,那么它也有可能适用于你自己的应用程序。
需要注意的是,随着层数增加,高度和宽度都会减小,从32×32到28×28,到14×14,到10×10,再到5×5;而通道数量会增加,从3到6到16不断增加,然后得到一个全连接层。
在神经网络中,另一种常见模式就是一个或多个卷积后面跟随一个池化层,然后一个或多个卷积层后面再跟一个池化层,然后是几个全连接层,最后是一个softmax。这是神经网络的另一种常见模式(other pretty common pattern)。
接下来看一下神经网络的激活值形状(activation shape),激活值大小(the activation size)和参数数量(the number of parameters)。
输入为32×32×3,这些数做乘法,结果为3072,所以激活值a^[0]有3072维,激活值矩阵为32×32×3,输入层没有参数。非池化层的参数主要关注w和b,最后一列结果:输入层没有参数;(5*5+1)*8=208;池化层参数为0;26*16=416;池化层参数为0;400*120+1=48001;120*84+1=10081;84*10+1=841。
有几点要注意,(1)第一,池化层和最大池化层没有参数;(2)第二卷积层的参数相对较少,其实许多参数都存在于神经网络的全连接层。随着神经网络的加深,激活值尺寸会逐渐变小,如果激活值尺寸下降太快,也会影响神经网络性能。示例中,激活值尺寸在第一层为6000,然后减少到1600,慢慢减少到84,最后输出softmax结果。我们发现,许多卷积网络都具有这些属性,模式上也相似。
神经网络的基本构造模块(basic building blocks)已经介绍完了,一个卷积神经网络包括卷积层、池化层和全连接层。许多计算机视觉研究正在探索如何把这些基本模块整合起来,构建高效的神经网络,整合这些基本模块确实需要深入的理解。根据Andrew的经验,找到整合基本构造模块最好方法就是大量阅读别人的案例。
下节课,也是本周最后一节课,将讨论为什么大家愿意使用卷积,使用卷积的好处和优势是什么,以及如何整合多个卷积,如何检验神经网络,如何在训练集上训练神经网络来识别图片或执行其他任务。
这是本周最后一节课,我们来分析一下卷积在神经网络中如此受用的原因,然后对如何整合这些卷积,如何通过一个标注过的训练集(labeled training set)训练卷积神经网络做个简单概括。和只用全连接层相比,卷积层的两个主要优势在于参数共享(parameter sharing)和稀疏连接(sparsity of connections),举例说明一下。
输入是一张32×32×3维度的图片(上节课的示例),假设用了6个大小为5×5的过滤器,输出维度为28×28×6。我们构建一个神经网络,其中一层含有32×32×3=3072个单元,下一层含有28×28×6=4704个单元,如果采用全连接的方式,两层中的每个神经元彼此相连,然后计算权重矩阵,它等于4074×3072≈1400万,所以要训练的参数很多。虽然以现在的技术,我们可以用1400多万个参数来训练网络,因为这张32×32×3的图片非常小,训练这么多参数没有问题。如果这是一张1000×1000的图片,权重矩阵会变得非常大。我们看看这个卷积层的参数数量,每个过滤器都是5×5,一个过滤器有25个参数,再加上偏差参数,那么每个过滤器就有26个参数,一共有6个过滤器,所以参数共计156个,参数数量还是很少。
卷积网络映射这么少的参数有两个原因,如下图:
(1)一是参数共享(parameter sharing)。观察发现,特征检测如垂直边缘检测如果适用于图片的某个区域,那么它也可能适用于图片的其他区域。因此,如果你用一个3×3的过滤器检测垂直边缘,那么图片的左上角区域,以及旁边的各个区域(左边矩阵中蓝色方框标记的部分)都可以使用这个3×3的过滤器。每个特征检测器以及输出都可以在输入图片的不同区域中使用同样的参数,以便提取垂直边缘或其它特征。它不仅适用于边缘(edges)特征这样的低阶特征(low level features),同样适用于高阶特征(high level features),例如提取脸上的眼睛,猫或者其他特征对象。即使减少参数个数,这9个参数同样能计算出16个输出。直观感觉是,一个特征检测器(feature detector),如垂直边缘检测器用于检测图片左上角区域的特征,这个特征很可能也适用于图片的右下角区域。因此在计算图片左上角和右下角区域时,就不需要添加其它特征检测器。假如有一个这样的数据集,其左上角和右下角可能有不同分布,也有可能稍有不同,但很相似,整张图片共享特征检测器,提取效果也很好。
(2)第二个方法是使用稀疏连接(sparsity of connections)。这个0(等式右端输出结果矩阵的第一个元素,绿色圆圈标记)是通过3×3的卷积计算得到的,它只依赖于这个3×3的输入的单元格,右边这个输出单元(元素0)仅与36个输入特征中9个相连接。而且其它像素值都不会对输出产生任影响,这就是稀疏连接的概念。
再看一个例子,加深对稀疏连接的理解。这个输出(右边矩阵中红色标记的元素 30)仅仅依赖于这9个特征(左边矩阵红色方框标记的区域),看上去只有这9个输入特征与输出相连接,其它像素对输出没有任何影响。
神经网络可以通过这两种机制减少参数,以便我们用更小的训练集来训练它,从而预防过度拟合。卷积神经网络善于捕捉平移不变。通过观察可以发现,向右移动两个像素,图片中的猫依然清晰可见,因为神经网络的卷积结构使得即使移动几个像素,这张图片依然具有非常相似的特征,应该属于同样的输出标记。实际上,我们用同一个过滤器生成各层中,图片的所有像素值,希望网络通过自动学习变得更加健壮,以便更好地取得所期望的平移不变属性。这就是卷积或卷积网络在计算机视觉任务中表现良好的原因。最后我们把这些层整合起来,看看如何训练这些网络。
如上图,要构建一个猫咪检测器(cat detector),我们有标记训练集,x表示一张图片(image),y是二进制标记(binary labels)或某个重要标记(key causes)。我们选定了一个卷积神经网络,输入图片,增加卷积层和池化层,然后添加全连接层,最后输出一个softmax,即y帽。卷积层和池化层有不同的参数w和b,用任何参数集合来定义代价函数。训练网络时,使用梯度下降算法或者其他算法来优化神经网络的所有参数,来减少代价函数的值。通过上述操作你可以构建一个高效的猫咪检测器或其它检测器。
本周我们讲了构建卷积神经网络的一些知识储备:卷积,padding,步长的概念,卷积层,池化层,全连接层这些组件。通过这周的课程,我们已经学习了卷积神经网络的所有基本构造模块,以及如何在高效图片识别系统中整合这些模块。下周,我们将继续深入学习卷积神经网络。我曾提到卷积神经网络中有很多超参数,下周,我打算具体展示一些最有效的卷积神经网络示例,你也可以尝试去判断哪些网络架构类型效率更高。人们通常的做法是将别人发现和发表在研究报告上的架构应用于自己的应用程序。下周看过更多具体的示例后,相信你会做的更好。此外,下星期我们也会深入分析卷积神经网络如此高效的原因,同时讲解一些新的计算机视觉应用程序,例如,对象检测(object detection)和神经风格迁移(neural style transfer)以及如何利用这些算法创造新的艺术品形式。
说明:记录学习笔记,如果错误欢迎指正!转载请联系我。