深度学习 -- 神经网络 3
上一讲介绍了2层神经网络,下面扩展开来,介绍通用L层神经网络
深层神经网络
构建神经网络的几个重要步骤通过更加直观的示意图来表示,如下:
这就是深度神经网络的内部实现原理,通过多次迭代训练后,最终得到一个模型,然后用此模型进行预测
在实现该网络之前,首先了解下面几个重要的符号
- Superscript denotes a quantity associated with the layer.
- Example: is the layer activation. and are the layer parameters.
- Superscript denotes a quantity associated with the example.
- Example: is the training example.
- Lowerscript denotes the entry of a vector.
- Example: denotes the entry of the layer’s activations).
1. 网络结构
在深度学习 – 神经网络1中,我们的实例是判断一张图片是否为猫,当时的准确率为70%,那么接下来我们继续以此为例,用多层神经网络来提高它的准确率
输入层:输入单元数 = 12288
隐藏层:总层数为L,第层的隐藏单元数为,**函数采用ReLU
输出层:输出单元数 = 1,**函数仍然采用sigmoid
参数维度如下表所示:
**Layer ** | **Shape of W** | **Shape of b** | **Activation** | **Shape of Activation** |
**Layer 1** | $(n^{[1]},12288)$ | $(n^{[1]},1)$ | $Z^{[1]} = W^{[1]} X + b^{[1]} $ | $(n^{[1]},209)$ |
**Layer 2** | $(n^{[2]}, n^{[1]})$ | $(n^{[2]},1)$ | $Z^{[2]} = W^{[2]} A^{[1]} + b^{[2]}$ | $(n^{[2]}, 209)$ |
$\vdots$ | $\vdots$ | $\vdots$ | $\vdots$ | $\vdots$ |
**Layer L-1** | $(n^{[L-1]}, n^{[L-2]})$ | $(n^{[L-1]}, 1)$ | $Z^{[L-1]} = W^{[L-1]} A^{[L-2]} + b^{[L-1]}$ | $(n^{[L-1]}, 209)$ |
**Layer L** | $(n^{[L]}, n^{[L-1]})$ | $(n^{[L]}, 1)$ | $Z^{[L]} = W^{[L]} A^{[L-1]} + b^{[L]}$ | $(n^{[L]}, 209)$ |
2. 实现过程
2.1 初始化参数
由于现在是L层,每层都有一套参数和,那么我们就需要一个更加通用的函数,使得它能够支持不同层数和不同的单元数,而层数和单元数都能够简单的通过参数来设定。initialize_parameters_deep(layer_dims),比如layer_dims = [5, 4, 3, 1],那么就表示该神经网络一共4层(不包括输入层),每层的单元数分别为5,4,3,1
关于这些参数初始化为多少合适,这个在后面的课程 改善神经网络 中再详细介绍,在这里参数W仍然为标准正态分布随机数*0.01,b为0
2.2 前向传播
之前讲过,一个隐藏单元实现两个基本功能:线性部分和**部分。
线性部分很简单,直接采用下面的公式:
其中,输入层表示为
该公式适用于神经网络的任何一层和任意数量的样本。
**部分,也就是**函数的部分,这里我们在隐藏层全部采用ReLU,输出层采用sigmoid。 在这里**函数 “g” 可以是sigmoid()或者relu()。
这里需要注意的就是在隐藏层,**函数都为ReLU,实现上只是一个循环即可,但是对于最后一层的输出层,它不在循环中,而是要单独处理,因为它这里采用的**函数式sigmoid。
2.3 计算cost
在这里使用的cost函数J是交叉熵:
这里需要注意的就是在计算时要保持维度正确,对于该例,最终的J应该是一个1 x m的向量
2.4 反向传播
反向传播的目标就是得到损失函数对于每一层参数W和b的导数–>, 。
计算过程如下:(通过正向传播的公式:,可以推导出第层参数的导数):
注意:和,和的维度完全是一样的。
在代码实现上,首先对输出层单独求导和,然后循环对隐藏层中每层的参数求导和。
具体实现可参考代码实例中的*L_model_backward(AL, Y, caches)*函数。
2.5 更新参数
这个是最简单的一个过程,操作如下:
其中为学习率。每一次迭代,我们都可以得到一次更新的,然后在下一个迭代中的正向传播过程中,会使用更新过的。这样num_iterations后,得到最终的参数。