Deeplearnng.AI第四部分第一周、卷积神经网络
文章目录
- 1.2边缘检测
- 1.3更多边缘检测内容(More edge detection)
- 1.4 Padding
- 1.5 卷积步长(Strided convolutions)
- 1.6 三维卷积(Convolutions over volumes)
- 1.7 单层卷积网络(One layer of a convolutional network)
- 1.8 简单卷积网络示例(A simple convolutional network example)
- 1.9池化层(Pooling layers)
- 1.10 卷及神经网络例子(Convolutional neural network example)
- *1.11为什么使用卷积?
1.2边缘检测
在数学中“∗”就是卷积的标准标志,但是在Python中,这个标识常常被用来表示乘法或者元素乘法。
为了计算第一个元素,在4×4左上角的那个元素,使
用3×3的过滤器,将其覆盖在输入图像,如下图所示。然后进行元素乘法(element-wise products)运算,所以[3∗10∗01∗(−1)1∗15∗08∗(−1)1∗27∗02∗(−1)]=[30(−1)10(−8)20(−2)]\begin{bmatrix} 3*1\ \ 0*0\ \ 1*(-1)\\ 1*1\ \ 5*0\ \ 8*(-1)\\ 1*2\ \ 7*0\ \ 2*(-1) \end{bmatrix}= \begin{bmatrix} 3\ \ 0\ \ (-1)\\ 1\ \ 0\ \ (-8)\\ 2\ \ 0\ \ (-2) \end{bmatrix}⎣⎡3∗1 0∗0 1∗(−1)1∗1 5∗0 8∗(−1)1∗2 7∗0 2∗(−1)⎦⎤=⎣⎡3 0 (−1)1 0 (−8)2 0 (−2)⎦⎤,然后将矩阵每个元素相加得到最左上角的元素,即 -5.
同理,得到第二个元素-4,
以此类推得到:
在不同的编程语言要实现这个运算,会有不同的函数。所以在编程练习中,你会使用一个叫conv_forward的函数。如果在tensorflow下,这个函数叫tf.conv2d,在其他深度学习框架中,如Keras,这个框架下用Conv2D实现卷积运算。所有编程框架都有函数来实现卷积运算。
以上是“卷积”的计算过程,那么什么是垂直边缘检测呢。下面来看另外一个例子。这是一个简单的6×6图像,左边的一半是10,右边一般是0。如果你把它当成一个图片,左边那部分看起来是白色的,像素值10是比较亮的像素值,右边像素值比较暗,我使用灰色来表示0,尽管它也可以被画成黑的。图片里,有一个特别明显的垂直边缘在图像中间,这条垂直线是从黑到白的过渡线,或者从白色到深色。
如果把最右边的矩阵当成图像,它是这个样子。在中间有段亮一点的区域,对应检查到这个6×6图像中间的垂直边缘。这里的维数似乎有点不正确,检测到的边缘太粗了。因为在这个例子中,图片太小了。如果你用一个1000×1000的图像,而不是6×6的图片,你会发现其会很好地检测出图像中的垂直边缘。在这个例子中,在输出图像中间的亮处,表示在图像中间有一个特别明显的垂直边缘。从垂直边缘检测中可以得到的启发是,因为我们使用3×3的矩阵(过滤器),所以垂直边缘是一个3×3的区域,左边是明亮的像素,中间的并不需要考虑,右边是深色像素。在这个6×6图像的中间部分,明亮的像素在左边,深色的像素在右边,就被视为一个垂直边缘,卷积运算提供了一个方便的方法来发现图像中的垂直边缘。
1.3更多边缘检测内容(More edge detection)
这里还有个更复杂的例子,左上方和右下方都是亮度为10的点。如果你将它绘成图片,右上角是比较暗的地方,这边都是亮度为0的点,我把这些比较暗的区域都加上阴影。而左上方和右下方都会相对较亮。如果你用这幅图与水平边缘过滤器卷积,就会得到右边这个矩阵。
再次强调,我们现在所使用的都是相对很小的图片,仅有6×6。但这些中间的数值,比如说这个10(右边矩阵中黄色方框标记元素)代表的是左边这块区域(左边6×6矩阵中黄色方框标记的部分)。这块区域左边两列是正边,右边一列是负边,正边和负边的值加在一起得到了一个中间值。但假如这个一个非常大的1000×1000的类似这样棋盘风格的大图,就不会出现这些亮度为10的过渡带了,因为图片尺寸很大,这些中间值就会变得非常小。
总而言之,通过使用不同的过滤器,你可以找出垂直的或是水平的边缘。但事实上,对于这个3×3的过滤器来说,我们使用了其中的一种数字组合。
但在历史上,在计算机视觉的文献中,曾公平地争论过怎样的数字组合才是最好的,所以你还可以使用这种:[10(−1)20(−2)10(−1)]\begin{bmatrix} 1\ \ 0\ \ (-1)\\ 2\ \ 0\ \ (-2)\\ 1\ \ 0\ \ (-1) \end{bmatrix}⎣⎡1 0 (−1)2 0 (−2)1 0 (−1)⎦⎤,叫做sobelsobelsobel的过滤器,它的优点在于增加了中间一行元素的权重,这使得结果的鲁棒性会更高一些。
但计算机视觉的研究者们也会经常使用其他的数字组合,比如这种:[30(−3)100(−10)30(−3)]\begin{bmatrix} 3\ \ \ 0\ \ (-3)\\ 10\ \ 0\ \ (-10)\\ 3\ \ \ 0\ \ (-3) \end{bmatrix}⎣⎡3 0 (−3)10 0 (−10)3 0 (−3)⎦⎤这种叫做ScharrScharrScharr过滤器,它有着和之前完全不同的特性,实际上也是一种垂直边缘检测,如果你将其翻转90度,你就能得到对应水平边缘检测。
1.4 Padding
为了构建深度神经网络,你需要学会使用的一个基本的卷积操作就是padding,让我们来看看它是如何工作的。
在前面的学习,我们知道对于一个是6x6的图像,通过一个3x3的卷积之后会得到4x4的图像。如果我们有n∗nn*nn∗n的图像,同f∗ff*ff∗f的卷积核过滤器做卷积,那么输出的维度就是:(n−f+1)∗(n−f+1)(n-f+1)*(n-f+1)(n−f+1)∗(n−f+1)。
但是这么卷积会使每次做卷积的时候图像缩小。如果不想让你的图像在每次卷积之后缩小,可以这样:
先在图像边缘填充一些像素,如上图,那么6∗66*66∗6的图像就编程8∗88*88∗8的图像,再用卷积核卷积作用之后会得到(8−3+1)∗(8−3+1)(8-3+1)*(8-3+1)(8−3+1)∗(8−3+1),即还是6∗66*66∗6的图像,这样你就得到了一个尺寸和原图像相等的图像。习惯上,你可以用0去填充,如果ppp是填充的数量,在这个案例中,p=1p=1p=1,因为我们在周围都填充了一个像素点,输出也就变成了(n+2p−f+1)∗(n+2p−f+1)(n+2p-f+1)*(n+2p-f+1)(n+2p−f+1)∗(n+2p−f+1),所以就变成了,和输入的图像一样大。这个涂绿的像素点(左边矩阵)影响了输出中的这些格子(右边矩阵)。这样一来,丢失信息或者更准确来说角落或图像边缘的信息发挥的作用较小的这一缺点就被削弱了。
卷积的padding通常有两种选择:分别是Valid卷积和Same卷积Valid卷积和 Same卷积Valid卷积和Same卷积,
- Valid卷积,即,不填充,如果有一个n∗nn*nn∗n的图像,用一个f∗ff*ff∗f的过滤器卷积,它将会输出(n−f+1)∗(n−f+1)(n-f+1)*(n-f+1)(n−f+1)∗(n−f+1)维的图像。
- Same卷积,即填充后输出和输入大小一样。根据公式n+2p−f+1n+2p-f+1n+2p−f+1,如果有一个n∗nn*nn∗n的图像,同ppp个像素填充,输出大小就是(n+2p−f+1)∗(n+2p−f+1)(n+2p-f+1)*(n+2p-f+1)(n+2p−f+1)∗(n+2p−f+1)。如果想让n+2p−f+1=nn+2p-f+1=nn+2p−f+1=n,使得输入输出相等,那么用此等式求解p,p=f−12p=\frac{f-1}{2}p=2f−1。所以当卷积核尺寸fff是一个奇数的时候,只要选择相应的填充尺寸ppp,你就能确保得到和输入相同尺寸的输出。
1.5 卷积步长(Strided convolutions)
如果你想用3×3的过滤器卷积这个7×7的图像,和之前不同的是,我们把步幅设置成了2。你还和之前一样取左上方的3×3区域的元素的乘积,再加起来,最后结果为91。
计算第二个值的时候和之前有所不同,之前我们移动蓝框的步长是1,现在移动的步长是2,我们让过滤器跳过2个步长,注意一下左上角,这个点移动到其后两格的点,跳过了一个位置。然后你还是将每个元素相乘并求和,你将会得到的结果是100。
以此类推计算出卷积后的值:
所以在这个例子中,我们用3×3的矩阵卷积一个7×7的矩阵,得到一个3×3的输出。输入和输出的维度是由下面的公式决定的。如果你用一个f∗ff*ff∗f的过滤器卷积一个n∗nn*nn∗n的图像,你的padding为ppp,步幅为s,在这个例子中s=2s=2s=2,你会得到一个输出,因为现在你不是一次移动一个步子,而是一次移动sss个步子,输出于是变为(n+2p−fs+1)∗(n+2p−fs+1)(\frac{n+2p-f}{s}+1)*(\frac{n+2p-f}{s}+1)(sn+2p−f+1)∗(sn+2p−f+1)
此例中,n = 7, p = 0, f = 3, s = 2, 代入公式得(7-3)/2 + 1 = 3。
现在只剩下最后的一个细节了,如果商不是一个整数怎么办?在这种情况下,我们向下取整。⌊x⌋\lfloor x \rfloor⌊x⌋这是向下取整的符号,这意味着x向下取整到最近的整数。这个原则实现的方式是,你只在蓝框完全包括在图像或填充完的图像内部时,才对它进行运算。如果有任意一个蓝框移动到了外面,那你就不要进行相乘操作,这是一个惯例。你的3×3的过滤器必须完全处于图像中或者填充之后的图像区域内才输出相应结果,这就是惯例。因此正确计算输出维度的方法是向下取整,以免n+2p−fs+1\frac{n+2p-f}{s}+1sn+2p−f+1不是整数。
从技术上讲,我们实际上做的,我们在前面视频中使用的操作,有时被称为互相关(cross-correlation)而不是卷积(convolution)。但在深度学习文献中,按照惯例,我们将这(不进行翻转操作)叫做卷积操作。
1.6 三维卷积(Convolutions over volumes)
从一个例子开始,假如说你不仅想检测灰度图像的特征,也想检测RGB彩色图像的特征。彩色图像如果是6×6×36×6×36×6×3,这里的3指的是三个颜色通道,你可以把它想象成三个6×66×66×6图像的堆叠。为了检测图像的边缘或者其他的特征,不是把它跟原来的3×33×33×3的过滤器做卷积,而是跟一个三维的过滤器,它的维度是3×3×33×3×33×3×3,这样这个过滤器也有三层,对应红绿、蓝三个通道。
给这些命个名字(原图像),这里的第一个6代表图像高度,第二个6代表宽度,这个3代表通道的数目。同样你的过滤器也有一个高,宽和通道数,并且图像的通道数必须和过滤器的通道数匹配,所以这两个数(紫色方框标记的两个数)必须相等。下一张图里,我们就会知道这个卷积操作是如何进行的了,这个的输出会是一个4×44×44×4的图像,注意是4×4×14×4×14×4×1,最后一个数不是333了。
上面左边的图像是6x6x36x6x36x6x3,中间是3x33x33x3的filter,为了简化这个3x3x33x3x33x3x3的卷积核,我们将它画成一个三维的立方体。
为了计算这个卷积操作的输出,先把这个3x3x33x3x33x3x3的卷积核放到最左上角的位置,这个卷积核有3x3x3=273x3x3=273x3x3=27个数,依次取这272727个数,然后乘以相应的RGB通道中的数字,先是红色通道的前999个数字,然后是绿色通道,然后再是蓝色通道,乘以左边黄色立方体覆盖的对应的272727个数,然后把这些数都加起来,就得到了输出的第一个数字。
要计算下一个输出,你把这个立方体滑动一个单位,再与这272727个数相乘,把它们都加起来,就得到了下一个输出,以此类推。
- 例如这个过滤器是3×3×33×3×33×3×3的,你只想检测图像红色通道的边缘,那么你可以将第一个过滤器设为[10(−1)10(−1)10(−1)]\begin{bmatrix} 1\ \ 0\ \ (-1)\\ 1\ \ 0\ \ (-1)\\ 1\ \ 0\ \ (-1) \end{bmatrix}⎣⎡1 0 (−1)1 0 (−1)1 0 (−1)⎦⎤,和之前一样,而绿色通道全为000,[000000000]\begin{bmatrix} 0\ \ 0\ \ 0\\ 0\ \ 0\ \ 0\\ 0\ \ 0\ \ 0 \end{bmatrix}⎣⎡0 0 00 0 00 0 0⎦⎤,蓝色的通道也全为零,如果你把这三个堆叠在一起形成一个3×3×33×3×33×3×3的过滤器,那么这就是一个检测垂直边界的过滤器,但只对红色通道有用。
- 或
者如果你不关心垂直边界在哪个颜色通道里,那么你可以用一个这样的过滤器,[10(−1)10(−1)10(−1)]\begin{bmatrix} 1\ \ 0\ \ (-1)\\ 1\ \ 0\ \ (-1)\\ 1\ \ 0\ \ (-1) \end{bmatrix}⎣⎡1 0 (−1)1 0 (−1)1 0 (−1)⎦⎤,[10(−1)10(−1)10(−1)]\begin{bmatrix} 1\ \ 0\ \ (-1)\\ 1\ \ 0\ \ (-1)\\ 1\ \ 0\ \ (-1) \end{bmatrix}⎣⎡1 0 (−1)1 0 (−1)1 0 (−1)⎦⎤,[10(−1)10(−1)10(−1)]\begin{bmatrix} 1\ \ 0\ \ (-1)\\ 1\ \ 0\ \ (-1)\\ 1\ \ 0\ \ (-1) \end{bmatrix}⎣⎡1 0 (−1)1 0 (−1)1 0 (−1)⎦⎤,所有三个通道都一样。所以通过设置第二个过滤器参数,你就有了一个边界检测器,3×3×33×3×33×3×3的边界检测器,用来检测任意颜色通道里的边界。参数的选择不同,你就可以得到不同的特征检测器,所有的都是3×3×33×3×33×3×3的过滤器。按照计算机视觉的惯例,当你的输入有特定的高宽和通道数时,你的过滤器可以有不同的高,不的宽,但是必须一样的通道数。理论上,我们的过滤器只关注红色通道,或者只关注绿色或者蓝色通道也是可行的。再注意一下这个卷积立方体,一个6×6×66×6×66×6×6的输入图像卷积上一个3×3×33×3×33×3×3的过滤器,得到一个4×44×44×4的二维输出。现在你已经了解了如何对立方体卷积,还有最后一个概念,对建立卷积神经网络至关重要。就是,如果我们不仅仅想要检测垂直边缘怎么办?如果我们同时检测垂直边缘和水平边缘,还有45°45°45°倾斜的边缘,还有70°70°70°倾斜的边缘怎么做?换句话说,如果你想同时用多个过滤器怎么办?这是我们上一张幻灯片的图片,我们让这个6×6×36×6×36×6×3的图像和这个3×3×33×3×33×3×3的过滤器卷积,得到4×44×44×4的输出。(第一个)这可能是一个垂直边界检测器或者是学习检测其他的特征。第二个过滤器可以用橘色来表示,它可以是一个水平边缘检测器。
和第一个卷积核卷积,可以得到第一个4×44×44×4的输出,然后卷积第二个过滤器,得到一个不同的4×44×44×4的输出。把这两个输出堆叠在一起,这样你就都得到了一个4×4×24×4×24×4×2的输出立方体,一个立方盒子,所以这就是一个4×4×24×4×24×4×2的输出立方体。它用6×6×36×6×36×6×3的图像,然后卷积上这两个不同的3×3×33×3×33×3×3的过滤器,得到两个4×44×44×4的输出,它们堆叠在一起,形成一个4×4×24×4×24×4×2的立方体,这里的2的来源于我们用了两个不同的过滤器。
现在总结一下维度,如果你有一个n∗n∗nc(通道数)n*n*n_c(通道数)n∗n∗nc(通道数)的输入图像,在这个例子中就是6∗6∗36*6*36∗6∗3,其中ncn_cnc就是通道数,然后卷积上一个f∗f∗ncf*f*n_cf∗f∗nc的卷积核,最后得到了(n−f+1)∗(n−f+1)∗nc′(n-f+1)*(n-f+1)*n_c'(n−f+1)∗(n−f+1)∗nc′,其中nc′n_c'nc′就是下一层的通道数,就是你所用的卷积核的个数(一个卷积核有RBG三层),此例中就是4∗4∗24*4*24∗4∗2。此时的步长是222,无padding。
现在你可以用它的一小部分直接在三个通道的RGB图像上进行操作。更重要的是,你可以检测两个特征,比如垂直和水平边缘或者10个或者128个或者几百个不同的特征,并且输出的通道数会等于你要检测的特征数。
对于这里的符号,吴恩达先生常用通道数(ncn_cnc)来表示最后一个维度,在文献里大家也把它叫做333维立方体的深度。这两个术语,即通道或者深度,经常被用在文献中。
1.7 单层卷积网络(One layer of a convolutional network)
前面已经讲了如何通过两个过滤器卷积处理一个三维图像,并输出两个不同的4×44×44×4矩阵。假设使用第一个过滤器进行卷积,得到第一个4×44×44×4矩阵。使用第二个过滤器进行卷积得到另外一个4×44×44×4矩阵。
形成一个卷积神经网络层,然后加入偏差b1b_1b1,它是一个实数,通过Python的广播机制给这161616个元素都加上同一偏差。然后应用非线性激活函数ReLU,输出结果是一个4×4矩阵。
同样,对于第二个4∗44*44∗4矩阵,我们加上不同的偏差,它也是一个实数,161616个数字都加上同一个实数,然后应用非线性激活函数ReLU,最终得到另一个4×44×44×4矩阵。然后重复我们之前的步骤,把这两个矩阵堆叠起来,最终得到一个4×4×24×4×24×4×2的矩阵。我们通过计算,从6×6×36×6×36×6×3的输入推导出一个4×4×24×4×24×4×2矩阵,它是卷积神经网络的一层,把它映射到标准神经网络中四个卷积层中的某一层或者一个非卷积神经网络中。
注意前向传播中一个操作就是z[1]=W[1]a[0]+b[1]z^{[1]}=W^{[1]}a^{[0]}+b^{[1]}z[1]=W[1]a[0]+b[1],其中a[0]=xa^{[0]}=xa[0]=x,执行激活函数操作得a[1]a^{[1]}a[1],即a[1]=g(z[1])a^{[1]}=g(z^{[1]})a[1]=g(z[1])。这里的输入是a[0]a^{[0]}a[0],即xxx,卷积核用变量W[1]W^{[1]}W[1]表示。
这就是a[0]a^{[0]}a[0]到a[1]a^{[1]}a[1]的操作,即卷积神经网络的一层。
- 为了加深理解,我们来做一个练习。
假设你有101010个过滤器,而不是222个,神经网络的一层是3×3×33×3×33×3×3,那么,这一层有多少个参数呢?每一层都是一个3∗3∗33*3*33∗3∗3的矩阵,就有272727个参数,再加入一个偏差就是28个,如果是10个卷积核,那就有28*10=280个参数。 - 最后我们总结一下用于描述卷积神经网络中的一层(以lll层为例),也就是卷积层的各种标记。
f[l]f^{[l]}f[l]表示卷积核的大小,为f∗ff*ff∗f,
上标[l]^{[l]}[l]表示lll层,
p[l]p^{[l]}p[l]表示padding的填充像素数量,可以指定为(Valid or Same),
s[l]s^{[l]}s[l]表示步长。
该层的输入表示为n∗n∗ncn*n*n_cn∗n∗nc,ncn_cnc表示该层的颜色通道数。此时需要对其进行修改,增加上标[l−1][l-1][l−1],即n[l−1]∗n[l−1]∗nc[l−1]n^{[l-1]}*n^{[l-1]}*n_c^{[l-1]}n[l−1]∗n[l−1]∗nc[l−1],因为它是上一层的激活值。由于有时候所用图片高度和宽度可能不等,分别用下标H,WH,WH,W标记,即,nH[l−1]∗nW[l−1]∗nc[l−1]n_H^{[l-1]}*n_W^{[l-1]}*n_c^{[l-1]}nH[l−1]∗nW[l−1]∗nc[l−1]。那么在第lll层,图片的维数是nH[l−1]∗nW[l−1]∗nc[l−1]n_H^{[l-1]}*n_W^{[l-1]}*n_c^{[l-1]}nH[l−1]∗nW[l−1]∗nc[l−1],第lll层的输入就是上一层的激活输出。而此层的输出其图片的维数是nH[l]∗nW[l]∗nc[l]n_H^{[l]}*n_W^{[l]}*n_c^{[l]}nH[l]∗nW[l]∗nc[l]。
在第lll层的输出图像维数中:
nH[l]=⌊nH[l−1]+2p[l]−f[l]s[l]+1⌋n_H^{[l]}=\lfloor \frac{n_H^{[l-1]}+2p^{[l]}-f^{[l]}}{s^{[l]}} +1\rfloornH[l]=⌊s[l]nH[l−1]+2p[l]−f[l]+1⌋,
nW[l]=⌊nW[l−1]+2p[l]−f[l]s[l]+1⌋n_W^{[l]}=\lfloor \frac{n_W^{[l-1]}+2p^{[l]}-f^{[l]}}{s^{[l]}} +1\rfloornW[l]=⌊s[l]nW[l−1]+2p[l]−f[l]+1⌋,
下面确定卷积核的大小。一般用3∗3∗k3*3*k3∗3∗k大小的卷积核(当然也可以是5∗5∗k5*5*k5∗5∗k等等),那么kkk如何确定?输入的通道数必须和卷积核的通道数一致。因此卷积核的维度就是
f[l]∗f[l]∗nc[l−1]f^{[l]}*f^{[l]}*n_c^{[l-1]}f[l]∗f[l]∗nc[l−1]。
应用偏差和非线性函数之后,这一层的输出等于它的激活值a[l]a^{[l]}a[l],其维度是nH[l]∗nW[l]∗nc[l]n_H^{[l]}*n_W^{[l]}*n_c^{[l]}nH[l]∗nW[l]∗nc[l]。当我们有m个例子,就有输出A[l]=m∗nH[l]∗nW[l]∗nc[l]A^{[l]}=m*n_H^{[l]}*n_W^{[l]}*n_c^{[l]}A[l]=m∗nH[l]∗nW[l]∗nc[l]。了解了卷积神经网络中某一卷积层的工作原理,我们就可以把它们堆叠起来形成一个深度卷积神经网络。
1.8 简单卷积网络示例(A simple convolutional network example)
直接看1.10即可
1.9池化层(Pooling layers)
除了卷积层,卷积网络也经常使用池化层来缩减模型的大小,提高计算速度,同时提高所提取特征的鲁棒性,我们来看一下。先举一个池化层的例子,然后我们再讨论池化层的必要性。假如输入是一个4×44×44×4矩阵,用到的池化类型是最大池化(max pooling)。执行最大池化的操作是一个2×22×22×2矩阵。执行过程非常简单,把4×44×44×4的输入拆分成不同的区域,我把这些区域用不同颜色来标记。对于2×22×22×2的输出,输出的每个元素都是其对应颜色区域中的最大元素值。
左上区域的最大值是9,右上区域的最大元素值是2,左下区域的最大值是6,右下区域的最大值是3。为了计算出右侧这4个元素值,我们需要对输入矩阵的2×2区域做最大值运算。这就像是应用了一个规模为2的过滤器,因为我们选用的是2×2区域,步幅是2,这些就是最大池化的超参数。因为我们使用的过滤器为2×2,最后输出是9。然后向右移动2个步幅,计算出最大值2。然后是第二行,向下移动2步得到最大值6。最后向右移动3步,得到最大值3。这是一个2×2矩阵,即f=2f=2f=2,步幅是2,即s=2s=2s=2。
之前讲的计算卷积层输出大小的公式同样适用于最大池化,即n+2p−fs+1\frac{n+2p-f}{s}+1sn+2p−f+1
下面来看另一个例子:
此例是计算3∗33*33∗3输出的每个元素,我们看左上角这些元素 ,注意这是一个3∗33*33∗3 区域,因为有 3 个过滤器,取最大值 9。然后移动一个元素,因为步幅是 1,蓝色区域的最大值是 9.继续向右移动,蓝色区域的最大值是 5。然后移到下一行,因为步幅是 1,我们只向下移动一个格,所以该区域的最大值是 9。这个区域也是 9。这两个区域的最大值都是 5。最后这三个区域的最大值分别为 8,68,68,6 和 999。超参数f=3,s=1f = 3,s = 1f=3,s=1,最终输出如下图所示。
以上就是一个二维输入的最大池化的演示,如果输入是三维的,那么输出也是三维的。
例如,输入是 5×5×25×5×25×5×2,那么输出是 3×3×23×3×23×3×2。计算最大池化的方法就是分别对每个通道执行刚刚的计算过程。如上图所示,第一个通道依然保持不变。对于第二个通道,我刚才画在下面的,在这个层做同样的计算,得到第二个通道的输出。一般来说,如果输入是5x5xncn_cnc,输出就是3x3xncn_cnc,ncn_cnc个通道中每个通道都单独执行最大池化计算,以上就是最大池化算法。
另外还有一种池化类型,平均池化,但是它不太常用。这种运算取的不是每个过滤器的最大值,而是平均值。如下图所示
示例中,紫色区域的平均值是 3.75,后面依次是 1.25、4 和 2。这个平均池化的超级参数f=2,s=2,f = 2,s = 2,f=2,s=2,我们也可以选择其它超参数。
总结一下,池化的超级参数包括过滤器大小fff和步幅sss,常用的参数值为f=2,s=2,f = 2,s = 2,f=2,s=2,应用频率非常高,其效果相当于高度和宽度缩减一半。也有使用f=3,s=2f = 3,s = 2f=3,s=2的情况。至于其它超级参数就要看你用的是最大池化还是平均池化了。你也可以根据自己意愿增加表示padding 的其他超级参数,虽然很少这么用。最大池化时,往往很少用到超参数 padding,当然也有例外的情况,我们下周会讲。大部分情况下,最大池化很少用 padding。目前p最常用的值是 0,即 p=0。最大池化的输入就是nH∗nW∗ncn_H*n_W*n_cnH∗nW∗nc,假设没有 padding,则输出⌊nH−fs+1⌋∗⌊nW−fs+1⌋∗nc\lfloor \frac{n_{_H}-f}{s}+1\rfloor *\lfloor \frac{n_{_W}-f}{s}+1\rfloor*n_c⌊snH−f+1⌋∗⌊snW−f+1⌋∗nc
1.10 卷及神经网络例子(Convolutional neural network example)
-
假设,有一张大小为 32×32×332×32×332×32×3 的输入图片,这是一张 RGB 模式的图片,你想做手写体数字识别。32×32×3 的 RGB 图片中含有某个数字,比如 7,你想识别它是从 0-9 这 10 个数字中的哪一个,我们构建一个神经网络来实现这个功能。
下面这个网络模型和经典网络 LeNet-5 非常相似,灵感也来源于此。LeNet-5 是多年前 Yann LeCun 创建的,我所采用的模型并不是 LeNet-5,但是受它启发,许多参数选择都与LeNet-5 相似。
该网络的输入是 32×32×3 的矩阵,假设第一层使用过滤器大小为 5×5,步幅是 1, padding是 0,过滤器个数为 6,那么输出为 28×28×6。将这层标记为 CONV1,它用了 6 个过滤器,增加了偏差,应用了非线性函数,可能是 ReLU 非线性函数,最后输出 CONV1 的结果。
然后构建一个池化层,这里我选择用最大池化,参数f = 2, s = 2,因为 padding 为 0。现在开始构建池化层,最大池化使用的过滤器为 2×2,步幅为 2,表示层的高度和宽度会减少一半。因此,28×28 变成了 14×14,通道数量保持不变,所以最终输出为 14×14×6,将该输出标记为 POOL1。
人们发现在卷积神经网络文献中,卷积有两种分类。一类卷积是一个卷积层和一个池化层一起作为一层,这就是神经网络的 Layer1。另一类卷积是把卷积层作为一层,而池化层单独作为一层。人们在计算神经网络有多少层时,通常只统计具有权重和参数的层。因为池化层没有权重和参数,只有一些超参数。这里,我们把 CONV1和 POOL1 共同作为一个卷积,并标记为 Layer1。在此例中,Layer1的输出为14x14x6
接着构建第二个卷积层大小为 5×5,步幅为 1,这次我们用 10 个过滤器,最后输出一个 10×10×10 的矩阵,标记为 CONV2。然后加入最大池化超参数f = 2,s = 2。最后输出为 5×5×10,标记为 POOL2,这就是神经网络的第二个卷积层,即 Layer2。
现在将 POOL2 平整化为一个大小为 400 的一维向量。可以把平整化结果想象成这样的一个神经元集合,然后利用这 400 个单元构建下一层。下一层含有 120 个单元,这就是我们第一个全连接层,标记为 FC3。这 400 个单元与 120 个单元紧密相连,这就是全连接层。它很像我们在第一和第二门课中讲过的单神经网络层,这是一个标准的神经网络。它的权重矩阵为W[3]W^{[3]}W[3] ,维度为 120×40。这就是所谓的“全连接”,因为这 400 个单元与这 120 个单元的每一项连接,还有一个偏差参数。输出 120 个维度,因为有 120 个输出。
然后我们对这个 120 个单元再添加一个全连接层,这层更小,假设它含有 84 个单元,标记为 FC4。
最后,用这 84 个单元后面接一个 softmax 单元。如果我们想通过手写数字识别来识别手写 0-9 这 10 个数字,这个 softmax 就会有 10 个输出。 -
接下来我们讲神经网络的激活值形状,激活值大小和参数数量。输入为 32×32×3,这些数做乘法,结果为 3072,所以激活值a[0]a^{[0]}a[0]有 3072 维,激活值矩阵为 32×32×3,输入层没有参数。计算其他层的时候,试着自己计算出激活值,这些都是网络中不同层的激活值形状和激活值大小。
第二卷积层的参数相对较少,前面课上我们提到过,其实许多参数都存在于神经网络的全连接层。观察可发现,随着神经网络的加深,激活值尺寸会逐渐变小,如果激活值尺寸下降太快,也会影响神经网络性能。示例中,激活值尺寸在第一层为 6000+,然后减少到 1600左右,慢慢减少到 84,最后输出 softmax结果。我们发现,许多卷积网络都具有这些属性,模式上也相似。
*1.11为什么使用卷积?
这是本周最后一节课,我们来分析一下卷积在神经网络中如此受用的原因,然后对如何整合这些卷积,如何通过一个标注过的训练集训练卷积神经网络做个简单概括。和只用全连接层相比,卷积层的两个主要优势在于参数共享和稀疏连接,举例说明一下。
假设有一张 32×32×3 维度的图片,这是上节课的示例,假设用了 6 个大小为 5×5 的过滤器,输出维度为 28×28×6。32×32×3=3072,28×28×6=4704。我们构建一个神经网络,其中一层含有 3072 个单元,下一层含有 4074 个单元,两层中的每个神经元彼此相连,然后计算权重矩阵,它等于 4074×3072≈1400 万,所以要训练的参数很多。虽然以现在的技术,我们可以用 1400 多万个参数来训练网络,因为这张 32×32×3 的图片非常小,训练这么多参数没有问题。如果这是一张 1000×1000 的图片,权重矩阵会变得非常大。我们看看这个卷积层的参数数量,每个过滤器都是 5×5,一个过滤器有 25 个参数,再加上偏差参数,那么每个过滤器就有 26 个参数,一共有 6 个过滤器,所以参数共计 156 个,参数数量还是很少。
卷积网络映射这么少参数有两个原因,一是参数共享。观察发现,特征检测如垂直边缘检测如果适用于图片的某个区域,那么它也可能适用于图片的其他区域。也就是说,如果你用一个 3×3 的过滤器检测垂直边缘,那么图片的左上角区域,以及旁边的各个区域(左边矩阵中蓝色方框标记的部分)都可以使用这个 3×3 的过滤器。每个特征检测器以及输出都可以在输入图片的不同区域中使用同样的参数,以便提取垂直边缘或其它特征。它不仅适用于边缘特征这样的低阶特征,同样适用于高阶特征,例如提取脸上的眼睛,猫或者其他特征对象。即使减少参数个数,这 9 个参数同样能计算出 16 个输出。直观感觉是,一个特征检测器,如垂直边缘检测器用于检测图片左上角区域的特征,这个特征很可能也适用于图片的右下角区域。因此在计算图片左上角和右下角区域时,你不需要添加其它特征检测器。假如有一个这样的数据集,其左上角和右下角可能有不同分布,也有可能稍有不同,但很相似,整张图片共享特征检测器,提取效果也很好。
使得卷积网络参数相对较少的第二个方法是使用稀疏连接,我来解释下。这个 0 是通过3×3 的卷积计算得到的,它只依赖于这个 3×3 的输入的单元格,右边这个输出单元(元素 0)仅与 36 个输入特征中 9 个相连接。而且其它像素值都不会对输出产生任影响,这就是稀疏连接的概念。
再举一个例子,这个输出(右边矩阵中红色标记的元素 30)仅仅依赖于这 9 个特征(左边矩阵红色方框标记的区域),看上去只有这 9 个输入特征与输出相连接,其它像素对输出没有任何影响。
神经网络可以通过这两种机制减少参数,以便我们用更小的训练集来训练它,从而预防过度拟合。你们也可能听过,卷积神经网络善于捕捉平移不变。通过观察可以发现,向右移动两个像素,图片中的猫依然清晰可见,因为神经网络的卷积结构使得即使移动几个像素,这张图片依然具有非常相似的特征,应该属于同样的输出标记。实际上,我们用同一个过滤器生成各层中,图片的所有像素值,希望网络通过自动学习变得更加健壮,以便更好地取得所期望的平移不变属性。这就是卷积或卷积网络在计算机视觉任务中表现良好的原因。
最后,我们把这些层整合起来,看看如何训练这些网络。比如我们要构建一个猫咪检测,xxx表示一张图片y^\hat{y}y^ 是二进制标记或某个重要标记。我们选定一个卷及神经网络,输入图片,增加卷积层和池化层,然后添加全连接层,最后输出一个 softmax,即y^\hat yy^。卷积层和全连接层有不同的参数www和偏差bbb,我们可以用任何参数集合来定义代价函数。一个类似于我们之前讲过的那种代价函数,并随机初始化其参数www和bbb,代价函数JJJ等于神经网络对整个训练集的预测的损失总和再除以mmm(即CostJ=1m∑i=1mL(y^(i),y(i))Cost\ J=\frac{1}{m}\sum^m_{i=1}L(\hat y^{(i)},y^{(i)})Cost J=m1∑i=1mL(y^(i),y(i))。所以训练神经网络,你要做的就是使用梯度下降法,或其它算法,例如 Momentum 梯度下降法,含 RMSProp 或其它因子的梯度下降来优化神经网络中所有参数,以减少代价函数JJJ的值。通过上述操作你可以构建一个高效的猫咪检测器或其它检测器。
总结
以上是生活随笔为你收集整理的Deeplearnng.AI第四部分第一周、卷积神经网络的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: ubuntu16.04安装R及RStud
- 下一篇: Deeplearnng.AI第四部分第二