体验完了“浅度”神经网络后,我们终于等到了这门课的正题——深度神经网络了。
其实这节课并没有引入太多新的知识,只是把上节课的2层网络拓展成了L层网络。对于编程能力强的同学(或者认真研究了我上节课的编程实战代码的同学,嘿嘿嘿),学完了上节课的内容后,就已经有能力完成这节课的作业了。
课堂笔记
深度神经网络概述与符号标记
所谓深度神经网络,只是神经网络的隐藏层数量比较多而已,它的本质结构和前两课中的神经网络是一样的。让我们再复习一下神经网络中的标记:
L L L表示网络的层数。
在这个网络中, L = 4 L=4 L=4。(注意:输入层并不计入层数,但可以用第“0”层称呼输入层)
上标中括号的标号 l ( l ∈ [ 0 , L ] ) l (l \in [0, L]) l(l∈[0,L])表示和第 l l l层相关的数据。比如, n [ l ] n^{[l]} n[l]是神经网络第 l l l层的神经元数(即每层输出向量的长度)。
这幅图里 n [ 1 ] = 5 n^{[1]}=5 n[1]=5, n [ 3 ] = 3 n^{[3]}=3 n[3]=3,以此类推。值得注意的是, n [ 0 ] = n x = 3 n^{[0]}=n_x=3 n[0]=nx=3。回想第二课的知识, n x n_x nx是输入向量的长度。
再比如, a [ l ] a^{[l]} a[l]是第 l l l层的输出向量。 a [ l ] = g [ l ] ( z [ l ] ) a^{[l]}=g^{[l]}(z^{[l]}) a[l]=g[l](z[l]),其中 g [ l ] g^{[l]} g[l]是第 l l l层的激活函数, z [ l ] z^{[l]} z[l]是第 l l l层的中间运算结果。 W [ l ] , b [ l ] W[l], b[l] W[l],b[l]是第 l l l层的参数。
和上节课的单隐层神经网络类似,对于 L L L层的网络,我们如下方法对单样本做前向传播(推理):
a [ l ] ← g [ l ] ( W [ l ] a [ l − 1 ] + b [ l ] ) f o r l ∈ [ 1 , 2 , . . . L ] \begin{aligned} a^{[l]} & \gets g^{[l]}(W^{[l]}a^{[l - 1]}+b^{[l]}) \\ for \ l & \in [1, 2, ... L] \end{aligned} a[l]for l←g[l](W[l]a[l−1]+b[l])∈[1,2,...L]
其中,输入输出分别为: x = a [ 0 ] , y ^ = a [ L ] x=a^{[0]}, \hat{y}=a^{[L]} x=a[0],y^=a[L]。
当我们考虑全体样本 X , Y X, Y X,Y时,上面的算式可以写成:
A [ l ] ← g [ l ] ( W [ l ] A [ l − 1 ] + b [ l ] ) f o r l ∈ [ 1 , 2 , . . . L ] \begin{aligned} A^{[l]} & \gets g^{[l]}(W^{[l]}A^{[l - 1]}+b^{[l]}) \\ for \ l & \in [1, 2, ... L] \end{aligned} A[l]for l←g[l](W[l]A[l−1]+b[l])∈[1,2,...L]
其中,输入输出分别为: X = A [ 0 ] , Y ^ = A [ L ] X=A^{[0]}, \hat{Y}=A^{[L]} X=A[0],Y^=A[L]。
从公式上看,使用向量化计算全体样本只是把小写字母换成了大写字母而已。用代码实现时,我们甚至也只需要照搬上述公式就行。但我们要记住,全体样本是把每个样本以列向量的形式横向堆叠起来,堆成了一个矩阵。我们心中对 X , Y X, Y X,Y的矩阵形状要有数。
在实现深度神经网络时,我们不可避免地引入了一个新的for循环:循环遍历网络的每一层。这个for循环是无法消除的。要记住,我们要消除的for循环,只有向量化计算中的for循环。它们之所以能被消除,是因为向量化计算可以使用并行加速,而不是for循环本身有问题。我们甚至可以把“向量化加法”、“向量化乘法”这些运算视为最小的运算单元。而在写其他代码时,不用刻意去规避for循环。
参数矩阵的形状是: W [ l ] : ( n [ l ] , n [ l − 1 ] ) , b [ l ] : ( n