1.视频网站:mooc慕课https://mooc.study.163.com/university/deeplearning_ai#/c
2.详细笔记网站(中文):http://www.ai-start.com/dl2017/
3.github课件+作业+答案:https://github.com/stormstone/deeplearning.ai
1.5 卷积步长 Strided convolutions
卷积中的步幅(Strided convolutions)是另一个构建CNN的基本操作,让我向你展示一个例子。
如上图,如果你想用3×3的过滤器卷积这个7×7的图像,和之前不同的是,我们把步幅设置成了2(Stride=2)。你还和之前一样取左上方的3×3区域的元素的乘积,再加起来,最后结果为91。
观察上图,只是之前我们移动蓝框的步长是1,现在移动的步长是2,我们让过滤器跳过2个步长,注意一下左上角,这个点移动到其后两格的点,跳过了一个位置。然后你还是将每个元素相乘并求和,你将会得到的结果是100。
现在我们继续,将蓝色框移动两个步长,你将会得到83的结果。
观察上图,当你移动到下一行的时候,你也是使用步长2而不是步长1,所以我们将蓝色框移动到第三行。注意到我们跳过了一个位置,得到69的结果。
现在你继续移动两个步长,会得到91,127,最后一行分别是44,72,74。
在这个例子中,我们用3×3的矩阵卷积一个7×7的矩阵,得到一个3×3的输出。
输入和输出的维度是由下面的公式决定的。
如果你用一个
f
f
f x
f
f
f的过滤器卷积一个
n
n
n x
n
n
n的图像,你的padding为
p
p
p,步幅为
s
s
s,在这个例子中
s
=
2
s=2
s=2,你会得到一个输出,因为现在你不是一次移动一个步子,而是一次移动
s
s
s个步子,输出于是变为
n
+
2
p
−
f
s
+
1
×
n
+
2
p
−
f
s
+
1
\frac {n+2p-f}{s}+1\times \frac {n+2p-f}{s}+1
sn+2p−f+1×sn+2p−f+1
本例中, n = 7 , p = 0 , f = 3 , s = 2 n=7,p=0,f=3,s=2 n=7,p=0,f=3,s=2, 7 + 0 − 3 2 + 1 = 3 \frac{7+0-3}2 +1=3 27+0−3+1=3,即3×3的输出。
现在只剩下最后的一个细节了,如果商不是一个整数怎么办?
在这种情况下,我们向下取整。
⌊
⌋
\lfloor \rfloor
⌊⌋是向下取整的符号,这也叫做对
z
z
z进行地板除(floor),
⌊
z
⌋
=
f
l
o
o
r
(
z
)
\lfloor z \rfloor=floor(z)
⌊z⌋=floor(z),这意味着
z
z
z向下取整到最近的整数。
这个原则实现的方式是,你只在蓝框完全包括在图像或填充完的图像内部时,才对它进行运算。
如上图右上角,如果有任意一个蓝框移动到了外面,那你就不要进行相乘操作,这是一个惯例。你的3×3的过滤器必须完全处于图像中或者填充之后的图像区域内才输出相应结果。因此正确计算输出维度的方法是向下取整,以免 n + 2 p − f s \frac {n+2p-f}s sn+2p−f不是整数。
维度总结
总结一下维度情况,如果你有一个 n n n x n n n的矩阵或者 n n n x n n n的图像,与一个 f f f x f f f的矩阵,或者说 f f f x f f f的过滤器卷积。Padding是 p p p,步幅为 s s s,输出尺寸就是这样: ⌊ n + 2 p − f s + 1 ⌋ × ⌊ n + 2 p − f s + 1 ⌋ \lfloor\frac {n+2p-f}{s}+1\rfloor\times \lfloor\frac {n+2p-f}{s}+1\rfloor ⌊sn+2p−f+1⌋×⌊sn+2p−f+1⌋
可以选择所有的数使结果是整数是挺不错的,尽管一些时候,你不必这样做,只要向下取整也就可以了。你也可以自己选择一些 n n n, f f f, p p p和 s s s的值来验证这个输出尺寸的公式是对的。
互相关和卷积
在讲下一部分之前,这里有一个关于互相关(cross-correlation)和卷积的技术性建议,这不会影响到你构建CNN的方式,但取决于你读的是数学教材还是信号处理教材,在不同的教材里符号可能不一致。
如上图。如果你看的是一本典型的数学教科书,那么卷积的定义是做元素乘积求和,实际上还有一个步骤是你首先要做的,也就是在把上图中的6×6矩阵和3×3过滤器卷积之前,首先你将3×3的过滤器沿水平和垂直轴翻转。
所以 [ 3 4 5 1 0 2 − 1 9 7 ] \begin{bmatrix} 3 & 4 & 5\\ 1 & 0 & 2\\-1 & 9 & 7\\ \end{bmatrix} ⎣⎡31−1409527⎦⎤变为 [ 7 2 5 9 0 4 − 1 1 3 ] \begin{bmatrix} 7 & 2 & 5\\ 9 & 0 & 4\\-1 & 1 & 3\\ \end{bmatrix} ⎣⎡79−1201543⎦⎤。这相当于将3×3的过滤器在水平和垂直轴上做了个镜像。
然后你再把这个翻转后的矩阵的元素和6x6矩阵相乘来计算输出的4×4矩阵左上角的元素。然后把它们平移一个位置,再平移一格,逐个计算乘积,以此类推。
我们在前面课程中定义卷积运算时,全部都跳过了这个镜像操作。从技术上讲,我们实际上做的这些操作,有时被称为互相关
(cross-correlation)而不是卷积(convolution)。但在深度学习文献中,按照惯例,我们将这(不进行翻转操作)叫做卷积操作。
总结,按照ML的惯例,我们通常不进行翻转操作(镜像操作)。从技术上说,这个操作可能叫做互相关更好。但在大部分的DL文献中都把它叫做卷积运算,因此我们将在课程中使用这个约定。如果你读了很多ML文献的话,你会发现许多人都把它叫做卷积运算,不需要用到这些翻转。
事实证明,在信号处理中或某些数学分支中,在卷积的定义包含翻转,使得卷积运算符拥有这个性质,即 ( A ∗ B ) ∗ C = A ∗ ( B ∗ C ) (A*B)*C=A*(B*C) (A∗B)∗C=A∗(B∗C),这在数学中被称为结合律。这对于一些信号处理应用来说很好,但对于深度NN来说它真的不重要,因此省略了这个双重镜像操作,就简化了代码,并使NN也能正常工作。
根据惯例,我们大多数人都叫它卷积,尽管数学家们更喜欢称之为互相关,但这不会影响到你在编程练习中要实现的任何东西,也不会影响你阅读和理解深度学习文献。