本文是Deep Learning Specialization系列课程的第4课《Convolutional Neural Networks》中Convolutional Neural Networks练习部分的学习笔记。
本文主要是通过NumPy来一步步实现卷积运算(Convolutional layer)和池化运算(Pooling layer)部分。具体包括:
- 填充
- 一个窗口的卷积运算
- 完整的卷积运算
- 池化运算
1. 卷积运算
1.1 填充
填充有两个好处:
- 能保证卷积神经网络的大小不变,以应用很深的网络
- 在运算中保留更多的处于边缘的信息
填充的原理如图所示:
在填充的运算中,我们可以直接使用NumPy提供的 np.pad 函数。比如,要对形状为(5, 5, 5, 5, 5)的a
数组,将其第二维填充pad=1
,第四维填充pad=3
,其他维度不做填充(pad=0
),其表达式为:
a_pad = np.pad(a, ((0, 0), (1, 1), (0, 0), (3, 3), (0, 0)), mode = 'constant', constant_values = (0, 0))
在我们的例子中,输入数据X的维度为(m, n_h, n_w, n_c)
,我们只对图片的高、宽进行填充,最终填充的结果维度为(m, n_h + 2*pad, n_w + 2*pad, n_c)
。其具体实现为:
def zero_pad(X, pad):
X_pad = np.pad(X, ((0, 0), (pad, pad), (pad, pad), (0, 0)), mode='constant', constant_values = (0, 0))
return X_pad
1.2 一个窗口的卷积运算
在卷积运算中,我们是需要将滤波器与输入数据进行叠加运算,并根据步长来移动窗口,最后得到卷积运算后的结果,具体如下图所示:
我们这里先来实现一个窗口的卷积运算,即将滤波器叠加到输入图像,相乘后求和得到的结果,这里没有滤波器窗口的移动。这里a_slice_prev
与W
的尺寸相同,都为(f, f, n_c_prev)
def conv_single_step(a_slice_prev, W, b):
s = np.multiply(a_slice_prev, W)
Z = np.sum(s)
Z = Z + b
return Z
1.3 卷积运算
下面,就要将滤波器窗口移动起来了,这里就需要用到我们前面学到的关于第l
层各参数的知识了:
- 权重: ( f [ l ] , f [ l ] , n c [ l − 1 ] ) ∗ n c [ l ] (f^{[l]}, f^{[l]}, n_c^{[l-1]}) * n_c^{[l]} (f[l],f