Loading [MathJax]/jax/output/HTML-CSS/jax.js

Deep Learning Note: 1-9 深度神经网络

  前面以一个简单的 2 层神经网络为例,介绍了前向传播和反向传播的计算过程。下面扩展到 L 层神经网络的情况。

图 1

图 1

  以图 1 所示的网络为例,记网络的层数为 L,此时 L=4。使用 n[l] 表示第 l 层中节点的个数,记输入层为第 0 层,输入有三个特征,故 n[0]=nx=3;第一个隐藏层有 5 个节点,故 n[1]=5,以此类推,n[2]=5n[3]=3n[4]=n[L]=1。使用 a[l] 表示第 l 层的激活值,则有 a[l]=g[l](z[l]),其中 g[l] 为第 l 层的激活函数。使用 W[l]b[l] 分别表示第 l 层的权重和偏置。

1. 计算网络输出

  对于图 1 所示的网络,单个样本前向传播的计算步骤为:

  • 第一层:

z[1]=W[1]x+b[1]=W[1]a[0]+b[1]

a[1]=g[1](z[1])

  • 第二层:

z[2]=W[2]a[1]+b[2]

a[2]=g[2](z[2])

  • 第三层:

z[3]=W[3]a[2]+b[3]

a[3]=g[3](z[3])

  • 第四层(输出层):

z[4]=W[4]a[3]+b[4]

a[4]=g[4](z[4])

  更一般地,可以将单个样本前向传播第 l 层的计算写为如下的形式:

z[l]=W[l]a[l1]+b[l]

a[l]=g[l](z[l])

  m 个样本前向传播的向量化实现形式为:

Z[l]=W[l]A[l1]+b[l]

A[l]=g[l](Z[l])

  式 (3)、(4) 向量化地计算了 m 个样本在第 l 层上的前向传播,但无法向量化整个 L 层网络的计算,仍需要逐层计算各层的激活值,作为下一层的输入,逐层向前传播到输出层。

2. 检查矩阵的维数

  如前所示的计算涉及大量的矩阵运算,通过检查各矩阵的维数是否匹配,可以快速地对计算的合法性和正确性进行初步校验。

图 2

图 2

  以图 2 所示的网络为例,首先看第 1 层,有:

z[1]=W[1]x+b[1]

  上式中 z[1] 的大小与第一层节点数相同,是一个 n[1]×13×1 的向量;x 是一个 n[0]×12×1 的向量;W[1] 是一个 n[1]×n[0]3×2 的矩阵,它与 2×1x 相乘得到一个 3×1 的向量,与 z[1] 的大小相符。b[1] 的大小与 W[1]xz[1] 相同,是一个 n[1]×13×1 的向量。

  一般的,对于第 l 层,z[l]a[l] 都是 n[l]×1 的向量,权重 W[l] 是一个 n[l]×n[l1] 的矩阵,偏置 b[l] 是一个 n[l]×1 的向量。

  由此可以快速得到各层参数的大小为:

  • W[2]5×3b[2]5×1
  • W[3]4×5b[3]4×1
  • W[4]2×4b[4]2×1
  • W[5]1×2b[5]1×1

  在进行反向传播时,dW[l]db[l] 的大小与 W[l]b[l] 相同,分别为 n[l]×n[l1]n[l]×1

  下面考虑向量化计算 m 个样本的情况,对第一层,有:

Z[1]=W[1]X+b[1]

  上式中 Z[1] 的大小为 n[1]×mW[1] 的大小不变,仍为 n[1]×n[0]X[1] 的大小为 n[0]×m;对于 b[1],仍可以将它看成是 n[1]×1 的向量,但在实际运算中,要把它复制并水平叠加成 n[1]×m 的形式,才能与 W[1]X 相加,在 Python 中可以利用其广播机制自动完成这一操作。

  在向量化计算 m 个样本的时候,对于第 l 层,W[l]b[l] 的大小与计算单个样本的情况一致,分别为 n[l]×n[l1]n[l]×1。而对于 Z[l]A[l],以及反向传播时的偏导 dZ[l]dA[l],都是 n[l]×m 的矩阵。

3. 深度神经网络的构造块

  对于网络的第 l 层,参数为权重 W[l] 和偏置 b[l]。前向传播时,输入为 a[l1],输出为 a[l],计算过程为:

Z[l]=W[l]a[l1]+b[l]

a[l]=g[l](Z[l])

  在计算式 (5) 时,通常会缓存 Z[l] 的结果,直接用于后续的反向传播。在进行反向传播时,输入为 da[l],以及前面缓存的 Z[l]。输出为 da[l1],以及参数的梯度 dW[l]db[l]

  由此得到神经网络的基本结构如图 3 所示。

图 3

图 3

  图 3 中,对于神经网络的第 l 层,首先通过前向传播,由第 l1 层的激活值 a[l1] 和第 l 层的参数 W[l]b[l],计算得到第 l 层的激活值 a[l],并缓存中间结果 Z[l]。然后通过反向传播,由第 l 层的激活值的导数 da[l] 和参数 W[l]b[l],计算得到第 l 层各参数的梯度 dW[l]db[l],以及第 l1 层的激活值的导数 da[l1]。使用梯度 dW[l]db[l] 更新该层的参数 W[l]b[l]

W[l]=W[l]αdW[l]

b[l]=b[l]αdb[l]

  以图 3 所示的结构为基础,可以将神经网络抽象为如图 4 所示的形式。

图 4

图 4

4. 前向传播

  结合前面计算网络输出的过程和网络的基本结构,可以得到第 l 层前向传播的计算过程为:

  • 输入:a[l1]
  • 输出:a[l],缓存 z[l]
  • 单个样本的计算:

z[l]=W[l]a[l1]+b[l]

a[l]=g[l](z[l])

  • 向量化计算 m 个样本:

Z[l]=W[l]A[l1]+b[l]

A[l]=g[l](Z[l])

5. 反向传播

  结合前文反向传播的推导和网络的基本结构,可以得到第 l 层前向传播的计算过程为:

  • 输入:da[l]
  • 输出:da[l1]dW[l]db[l]
  • 单个样本的计算:

dz[l]=da[l]g[l](z[l])

dW[l]=dz[l]a[l1]

db[l]=dz[l]

da[l1]=W[l]Tdz[l]

  • 向量化计算 m 个样本:

dZ[l]=dA[l]g[l](Z[l])

dW[l]=1mdZ[l]A[l1]T

db[l]=1mnp.sum(dZ[l],axis=1,keepdims=True)

dA[l1]=W[l]TdZ[l]

  如果使用式 (21) 作为损失函数,其中 ˆy 为第 L 层的输出,即 a[L],则 da[L] 如式 (22) 所示。

L(ˆy,y)=ylogˆy(1y)log(1ˆy)

da[L]=dˆy=yˆy+1y1ˆy

6. 参数和超参数

  训练神经网络时涉及到的参数除了模型本身的参数 Wb,还有其他一些参数,如学习率 α、迭代次数、隐藏层数量 L、隐藏单元数量 n[l]、激活函数等,这些参数并不直接作用于预测,但它们会在一定程度上控制或影响 Wb 的学习过程和结果,这些参数称为超参数(Hyperparameter)。

  除了上面提到的,在训练神经网络的过程中涉及的超参数还有很多,比如动量(Momentum)项、最小批大小(Minibatch Size)、正则化(Regularization)形式等等。

  由于涉及到众多的超参数,通常很难在一开始就找到最佳的选择,往往需要尝试各种选择和取值,进行比较。应用机器学习是一个非常依赖经验的过程,比如对某个超参数的取值有了一个猜想,那么接下来就要把它实现出来,进行实验,根据实验结果对超参数进行必要的调整,再进行实现···如此循环。

  另一方面,即便找到了较好的超参数,随着外界条件的变化,比如计算环境的变化,原有的超参数不再适用于新的环境,无法达到原来的性能。所以通常每隔一段时间,比如几个月或几年,需要重新尝试各种不同的超参数,检查是否有新的更好的参数选择。