文章目录

  • 符号表示
  • 公式推导
  • 前向过程
  • 反向过程
  • 梯度更新
  • Loss层的梯度
  • L2 Loss
  • Cross Entropy Loss



该文档将以含有两个隐藏层的神经网络为基础进行正向和反向的公式推导,因为一个隐藏层的网络太简单,多个隐藏层与两个隐藏层在推导上没有本质区别,所以综合平衡知识性与文档撰写的便捷性,两个隐藏层比较合适。

整个文档主要包含以下内容或者特点:

  • 符号表示要足够清晰
  • 中间步骤尽量详细
  • 把batch_size引入进来
  • 以向量化的方式推导
  • 使用两个Loss:L2和Cross Entropy Loss

该文档与以下两个文档配合看更易理解:
与该对应的代码实现: MNIST攻略:原始数据解析和基于numpy的全连接网络实现 代码实现中用到的loss公式: Softmax以及Cross Entropy Loss求导

符号表示

全连接神经网络的正反传都不难,但是一定要有清晰的,好的符号表示系统,否则容易出错。有些符号可能开始不易被理解,但是结合图例和公式推导过程,后面慢慢应该就会感受到其中的用处。

推导过程中要特别注意矩阵的shape,因为矩阵乘法占据了绝大部分的运算,所以搞清楚矩阵乘法对shape的要求,即前矩阵的第二个维度应等于后矩阵的第一个维度,就可以有效地避免犯错。

编程实现全连接神经网络 全连接神经网络公式_神经网络


图1. 全连接神经网络结构图

  • 编程实现全连接神经网络 全连接神经网络公式_编程实现全连接神经网络_02 层的节点数用 编程实现全连接神经网络 全连接神经网络公式_神经网络_03
  • 编程实现全连接神经网络 全连接神经网络公式_公式推导_04 表示第 编程实现全连接神经网络 全连接神经网络公式_编程实现全连接神经网络_02 层第 编程实现全连接神经网络 全连接神经网络公式_神经网络_06 个节点的值,编程实现全连接神经网络 全连接神经网络公式_神经网络_07 的shape为 编程实现全连接神经网络 全连接神经网络公式_公式推导_08,其中 编程实现全连接神经网络 全连接神经网络公式_全连接_09
  • 编程实现全连接神经网络 全连接神经网络公式_编程实现全连接神经网络_10 表示与 编程实现全连接神经网络 全连接神经网络公式_公式推导_04 对应的激活值,激活函数记为 编程实现全连接神经网络 全连接神经网络公式_公式推导_12 其导数记为 编程实现全连接神经网络 全连接神经网络公式_神经网络_13 ,其shape与 编程实现全连接神经网络 全连接神经网络公式_公式推导_04 相同;输入用 编程实现全连接神经网络 全连接神经网络公式_全连接_15
  • 编程实现全连接神经网络 全连接神经网络公式_全连接_16 表示第 编程实现全连接神经网络 全连接神经网络公式_编程实现全连接神经网络_02 层的weight和bias,编程实现全连接神经网络 全连接神经网络公式_全连接_18 的shape为编程实现全连接神经网络 全连接神经网络公式_编程实现全连接神经网络_19编程实现全连接神经网络 全连接神经网络公式_全连接_20 的shape为编程实现全连接神经网络 全连接神经网络公式_全连接_21
  • 编程实现全连接神经网络 全连接神经网络公式_公式推导_22 表示任意变量,包括 编程实现全连接神经网络 全连接神经网络公式_神经网络_23 等,那么 编程实现全连接神经网络 全连接神经网络公式_编程实现全连接神经网络_24 表示该变量的梯度,shape与 编程实现全连接神经网络 全连接神经网络公式_公式推导_22 相同,计算公式为 编程实现全连接神经网络 全连接神经网络公式_编程实现全连接神经网络_26

根据上述符号表示方法(主要是看shape的对应关系),用于全连接的线性运算应当写为:编程实现全连接神经网络 全连接神经网络公式_公式推导_27 ,可以看到是 编程实现全连接神经网络 全连接神经网络公式_公式推导_28 在前 编程实现全连接神经网络 全连接神经网络公式_全连接_29 在后,而不是我们熟悉的 编程实现全连接神经网络 全连接神经网络公式_全连接_29 在前 编程实现全连接神经网络 全连接神经网络公式_公式推导_28

  • 公式与结构图的对应更加顺滑,因为在图中,编程实现全连接神经网络 全连接神经网络公式_编程实现全连接神经网络_32 的位置在 编程实现全连接神经网络 全连接神经网络公式_全连接_18
  • 可以把batch_size放在第一个维度,这也是各个深度学习框架的通用做法。

公式推导

虽然前面我们讲了要推导两个Loss,但是看完反向过程就会知道,我们并不用针对每一个Loss都重写一遍推导流程,只需要在反向传播的初期把相应的Loss梯度公式带进去即可。

前向过程

请注意,虽然下面的前向公式里写了Loss,但实际上只有Loss的梯度参与反向过程,Loss本身不参与计算,写下来以示敬意而已。
编程实现全连接神经网络 全连接神经网络公式_编程实现全连接神经网络_34

反向过程

反向过程要详细写,编程实现全连接神经网络 全连接神经网络公式_全连接_35 暂时不写具体表达式,针对不同的Loss,将其带入即可。编程实现全连接神经网络 全连接神经网络公式_编程实现全连接神经网络_36 表示变量 编程实现全连接神经网络 全连接神经网络公式_编程实现全连接神经网络_37 的转置。
乘法表示:两个变量中间为点表示矩阵乘法;编程实现全连接神经网络 全连接神经网络公式_编程实现全连接神经网络_38 表示element-wise乘法;编程实现全连接神经网络 全连接神经网络公式_全连接_39表示对 编程实现全连接神经网络 全连接神经网络公式_编程实现全连接神经网络_37

从下面推导过程体现出以下特点:

  • 传递性:在链式法则的作用下,每一个变量的梯度仅跟上一层变量的梯度有关,与更早的梯度无关(当然,本质上是有关的,但是由于传递性的存在,从计算公式上来看是无关的),其他参与计算的都是正向过程中缓存下来的变量。
  • 编程实现全连接神经网络 全连接神经网络公式_神经网络_07 在反向过程中不需要用到,虽然编程实现全连接神经网络 全连接神经网络公式_编程实现全连接神经网络_42函数中用到了编程实现全连接神经网络 全连接神经网络公式_公式推导_43,但是现在常用的激活函数的导数如sigmoid和relu等都不包含 编程实现全连接神经网络 全连接神经网络公式_神经网络_07 本身。这就意味着,编程实现全连接神经网络 全连接神经网络公式_神经网络_07 仅在前向过程中用一下就好了,因此前向过程中激活函数可以做原位运算(in-place),即 编程实现全连接神经网络 全连接神经网络公式_全连接_46编程实现全连接神经网络 全连接神经网络公式_神经网络_07

编程实现全连接神经网络 全连接神经网络公式_全连接_48
下面是反向过程中所有变量的shape,带 编程实现全连接神经网络 全连接神经网络公式_神经网络_49 和不带 编程实现全连接神经网络 全连接神经网络公式_神经网络_49 的shape一样,因为现在是反向过程,所以不带 编程实现全连接神经网络 全连接神经网络公式_神经网络_49 的变量就不再写了。配合等式左右两边变量的shape来看反向过程更易理解,特别是矩阵乘法中变量的前后顺序的确定。
编程实现全连接神经网络 全连接神经网络公式_公式推导_52

梯度更新

仅需要更新网络参数,即weight和bias,编程实现全连接神经网络 全连接神经网络公式_全连接_53 表示学习率。
编程实现全连接神经网络 全连接神经网络公式_编程实现全连接神经网络_54

Loss层的梯度

L2 Loss的梯度比较容易理解。Cross Entropy Loss的梯度推导可以参考另一篇文档《Softmax以及Cross Entropy Loss求导》。

一般来讲L2 Loss多用于回归任务,而Cross Entropy Loss多用于分类任务。

L2 Loss

编程实现全连接神经网络 全连接神经网络公式_全连接_55

Cross Entropy Loss

这部分可参考:
Softmax以及Cross Entropy Loss求导编程实现全连接神经网络 全连接神经网络公式_公式推导_56

注意,Cross Entropy Loss的梯度看起来与L2 Loss的梯度有点像,但其实差别还是挺大的,Cross Entropy Loss的 编程实现全连接神经网络 全连接神经网络公式_全连接_57 外面还包了个Softmax,另外因为针对任务的不同,两个Loss的标签 编程实现全连接神经网络 全连接神经网络公式_全连接_58