1 卷积神经网络(Convolutional Neural Networks)
1.1 边缘检测(Edge Detection)
给定一个6 × 6的灰度图像数据X,需要对其进行垂直边缘检测,则构造一个3 × 3的矩阵F如下,也称作滤波器(Filter)或者核(Kernel):
然后求两个矩阵的卷积*,结果为4 × 4的矩阵:
上式中,输出矩阵Y的第一个元素为输入矩阵X左上角3 × 3子矩阵与滤波矩阵F的元素点乘之和:
其他元素依次类推,从而能够得到矩阵卷积的结果。在tensorflow中,tf.nn.conv2d可以实现矩阵的卷积操作。注意,实际上上述操作为互相关,但是在深度学习文献中通常称作卷积。
从卷积得到的图像,就能够对垂直边缘进行检测。不过下图中检测到的边缘较粗,主要是因为矩阵的元素太少,对于元素较多的图片,能够较好地检测出边缘。
如果将输入图像白灰对调,得到如下的结果,因此不同的检测结果可以看出颜色由亮到暗还是由暗到亮。
同样,如果检测水平边缘,可以用如下的滤波器:
还有一些其他的垂直边缘检测滤波器,将其翻转90°就成为水平边缘检测滤波器:
1.2 Padding
n × n的矩阵与f × f的矩阵卷积的结果,就是(n – f + 1) × (n – f + 1)维度的矩阵。
这种卷积有两个缺点:
(1) 每次卷积,图像就会缩小;
(2) 角落或者边缘区域的像素在输出中较少使用,这意味着失去了边缘像素的较多信息。
解决方法就是在图像周围填充像素,也就是Padding。填充后卷积,保证卷积前后的矩阵大小相等。假设填充p层,那么填充后的矩阵维度为(n + 2p – f + 1) × (n + 2p – f + 1)。
至于填充多少像素,有两个选择,Valid卷积和Same卷积。
(1) Valid卷积就是没有Padding。
(2) Same卷积就是Padding,使得输出和输出矩阵的大小相同,即:
因此,如果采用奇数维过滤器,Same卷积就可以对称地对图像进行填充。
1.3 卷积步长
Strided卷积,就是每次卷积移动一定的步长。例如,stride = 2时,按如下移动来计算卷积。
假如padding为p,stride为s,则输出矩阵的维度如下,如果维度不为整数,则向下取整:
1.4 立方卷积
如果对于RGB图像,输入矩阵是三维矩阵,滤波器也是三维矩阵,可以将矩阵当作立方,类似二维卷积计算点乘与求和,如下计算卷积:
如果想要同时检测水平边缘和垂直边缘,就需要使用两个滤波器,那么就得到如下两个输出,将两个输出堆叠起来得到一个新的立方。
因此,假如输入矩阵的维度为n × n × nC,滤波器维度为f × f × nC,那么输出矩阵的维度为(n – f + 1) × (n – f + 1)× nf,nf为使用的滤波器数量。
1.5 单层卷积网络
对卷积后得到的矩阵,采用非线性激活函数,例如ReLU函数,并加上偏差b,然后将输出堆叠起来,就得到了卷积神经网络的一层,如下:
图中,输入图像为a[0] = x,滤波器为W[1],最终得到的矩阵为a[1],则前向传播可以表示为:
Q:如果卷积神经网络的一层中包含10个3 × 3 × 3的滤波器,这层有多少个参数?
A:对于每个3 × 3 × 3滤波器,包含27个参数,再加上一个偏差,总共28个参数,因此10个滤波器共有280个参数。
对于卷积神经网络的第l层,定义f[l]为滤波器大小,p[l]为padding,s[l]为stride,nC[l]为滤波器数量,则输入矩阵维度为nH[l - 1] × nW[l - 1] × nC[l - 1],每个滤波器维度为f[l] × f[l] × nC[l - 1],权重W[l]维度为f[l] × f[l] × nC[l - 1] × nC[l],偏差b[l]维度为1 × 1 × 1 × nC[l],a[l]激活维度为nH[l] × nW[l] × nC[l],A[l]激活维度为m × nH[l] × nW[l] × nC[l],且有如下关系:
1.6 池化层(Pooling)
在卷积神经网络中,通常有三种层:
(1) 卷积层(CONV);
(2) 池化层(POOL);
(3) 全连接层(FC)。
最大池化(Max Pooling)只有两个参数,滤波器大小f和步长s,输出为每个子矩阵的最大元素。例如如下矩阵,f = 2, s = 2:
而平均池化(Average Pooling),则是取每个子矩阵的平均值,如下:
在神经网络中,最大池化要比平均池化用的更多,很少会使用padding。
对于维度为nH × nW × nC的输入矩阵,输出的维度为:
池化层的超参数为f、s和Max/Average Pooling,没有需要学习的参数,仅仅计算某一层的静态属性。
1.7 卷积神经网络示例
在卷积网络中,由于池化层中没有需要训练的参数,可以将卷积层与池化层当作一层。下图给出了一个神经网络示例CONV1 -> POOL1 -> CONV2 -> POOL2 -> FC3 ->FC4 -> Softmax。随着层数的增加,高度nH和宽度nW会降低,而信道nC会增加。
该网络的参数如下:
|
|
|
|
---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
卷积层的优点在于参数较少,原因如下:
(1) 参数共享(Parameter Sharing):特征检测如果适用于图片的某个区域,那么也可以用于图片的其他区域。
(2) 稀疏连接(Sparsity of Connections):每一层的每个输出仅仅依赖于很小数量的输入。
2 代码实现
2.1 卷积神经网络代码实现
先对卷积神经网络的各个模块进行代码实现。
卷积层包含以下几部分:
(1) Zero Padding;
(2) Convolve window;
(3) Convolution forward;
(4) Convolution backward。
池化层包含以下几部分:
(1) Pooling forward;
(2) Create mask ;
(3) Distribute value;
(4) Pooling backward 。
2.1.1 Zero-Padding
Zero-Padding的优点在于,能够保持图像更多的边缘信息,卷积运算可以保持图像的大小,特别是“same”卷积前后的图像宽与高保持不变。
维度为(m, nH, nW, nC)的矩阵,采用Zero-Padding后的维度为(m, nH + 2 * pad, nW + 2 * pad, nC),核心代码如下:
2.1.2 单步卷积计算conv_single_step
计算卷积的每一步,需要先进行矩阵点乘,然后再对矩阵进行求和,核心代码如下:
2.1.3 卷积层正向传播conv_forward
在计算卷积时,选取输入矩阵a_prev的子块,并依次移动,计算与权重W的卷积,注意满足如下关系:
核心代码如下:
2.1.4 池化层正向传播pool_forward
实现最大池化和平均池化,不需要使用padding,注意满足如下关系:
核心代码如下:
2.1.5 卷积层反向传播conv_backward
反向传播如下:
核心代码如下:
2.1.6 池化层反向传播pool_backward
为了实现池化层反向传播,需要先实现两个函数。
(1) 对于最大池化,create_mask_from_window()将最大元素设置为1,而将其他元素设置为0,例如:
核心代码如下:
(2) 对于平均池化,distribute_value()设置元素相等的矩阵,例如:
核心代码如下:
利用以上两个函数,池化层反向传播核心代码如下:
2.2 卷积神经网络TensorFlow实现
下面采用TensorFlow实现如下手势判断的案例。
2.2.1 Create Placeholders
创建X和Y的placeholder,先不指定样本数量,核心代码如下:
2.2.2 参数初始化initialize_parameters
采用xavier对卷积层参数初始化,取W[1]的维度为(4, 4, 3, 8),W[2]的维度为(2, 2, 8, 16),tensorflow会自动处理偏移b,也会自动对全连接层处理。核心代码如下:
2.2.3 正向传播forward_propagation
实现正向传播:Conv2d -> ReLU -> Maxpool -> Conv2d -> ReLU -> Maxpool -> Flatten -> Fullyconnected,需要用到下面几个函数。
(1) 卷积层:tf.nn.conv2d(X, W1, strides = [1, s, s, 1], padding = ‘SAME’);
(2) ReLU函数:tf.nn.relu(Z1);
(3) 最大池化层:tf.nn.max_pool(A, ksize = [1, f, f, 1], strides = [1, s, s, 1], padding = ‘SAME’);
(4) 全连接层:tf.contrib.layers.fully_connected(F, num_outputs, activation_fn = None),此处不实现Softmax层,而是将Softmax层和代价函数写入一个函数中。
正向传播的核心代码如下:
2.2.4 计算代价函数compute_cost
代价函数计算与Softmax层捆绑在一个函数中,核心代码如下:
2.2.5 构建模型model
将以上几个模块结合起来,采用Adam + mini-batch优化算法,核心代码如下:
2.2.6 测试model
测试核心代码如下
得到如下结果:
代码下载地址:https://gitee.com/tuzhen301/Coursera-deeplearning.ai4-1