深度神经网络的训练过程(以向量化的角度)

python基础

浏览数:386

2019-8-28

BP 算法的训练过程,各种博客和参考书已经讲的很清楚了,但不管是周志华的《机器学习》,还是林轩田的《机器学习技法》,都只是对 3 层的神经网络的训练做了非向量化的推导。本文将结合 Andrew Ng 的最新视频,从向量和矩阵运算的角度推一遍任意层神经网络(全连接)的训练算法。

为什么要公式向量化

从工程的角度来讲,向量化可以极大的加快程序的运行速度。举一个例子,求两个向量(列向量)的内积,你可能会写出以下两个公式:


在实现的过程中,公式 (1) 使用了 for 循环,公式 (2) 使用了优化过的矩阵乘法,第一种的速度会远快于第二种。

符号约定

符号 意义
l 表示神经网络的层数
m batch_size
C 表示每一层的神经元的个数
J cost function
a 学习率
符号 shape 意义 i 的取值
Z[i] (Ci, ) 表示第 i 层的输入(未经激活函数) 2 – l
A[i] (Ci, ) 表示第 i 层的输入 1 – l
w[i] (Ci, Ci-1) 表示第 i 层神经元的权重矩阵 2 – l
b[i] (Ci, ) 表示第 i 层神经元的偏置(bias 2 – l

正向传播过程

输入:A[1],即 X
输出:A[l] ,即 y^
对于 i = 2, 3, ... l

其中


式子中的 * 符号指的是智能乘法,表示矩阵的对应位置相乘。

误差反向传导过程

BP 算法的原理是利用链式法则,对于每一个路径只访问一次就能求顶点对所有下层节点的偏导值。
先来看看 Jw[l] 的导数

其中


再来看 Jw[l-1] 的导数

通过观察 dw[l]dw[l-1],可以找到递推的规律:

BP 算法前向递推的规律:
起始条件



对于
i = l - 1, l - 2, ... 2,有


经过了一轮循环,求出了神经网络各层的 dw,然后按照下式更新网络参数:



这就完成了一个 epoch 的训练。

技巧

上述算法的缺点是,由于在后向传播的过程中,需要求激活函数 φ 对 输入 Z[i] 的导数,所以我们在进行前向传播的过程中,需要保存一下每一层的 Z 的值,这无疑增大了内存的消耗,在这里我们有一个技巧:

当激活函数为 SigomidTanhReLU 时,其导数可由其函数值表示,例如:Sigomid 函数的导数为 f(x) * (1 - f(x))Tanh 函数的导数为 1 - f(x)^2

所以,在参与上式 dZ 的运算中,利用函数的化简可以约分掉与 Z[i] 相关的项(用 A[i] 替代了) 的值,这样我们就可以适当的变换一下迭代公式,使 Z[i] 不出现在公式中,这样就不用再额外存储 Z 了。

实现

具体的 Python 实现,请点击这里

参考资料

作者:农大鲁迅