本文可以看作是一个记录学习的文档,主要记录了自己学习神经网络的BP算法的过程。文章从基本的标量对矩阵的导数着手,一步步的深入到对BP算法的推导和理解。如果你目前还是一个不懂矩阵导数的新手,并且试图自己编程实现一个神经网络,那么这篇文章或许能帮助到你!
本文很多内容都是参考自下面的文章,其中的很多内容对我的理解帮助很大,在此对几位作者表示感谢!同时本文也可以看作是对这几篇文章的一个总结
长躯鬼侠:矩阵求导术(上)zhuanlan.zhihu.com目录
- 问题引出:一个经典的两层MLP示意
- 标量对矩阵的导数
- BP算法的推导
- 算法的编程实现逻辑
1问题引出
推导BP算法还得从经典的多层感知机(MLP)入手
上图表示了一个单隐藏层的MLP。下面将在这个MLP模型下探讨BP算法:
中间的激活层使用Sigmoid函数,输出层使用softmax函数,损失函数使用交叉熵。则可以写出该网络的损失函数为:
BP算法的核心在于如何利用损失函数的梯度来更新各层的权重
2标量对矩阵的导数
主要参考(作者对矩阵求导讲得十分详细,本文的内容很多来自与该文章,只是增加了一些细节的理解!)
长躯鬼侠:矩阵求导术(上)zhuanlan.zhihu.com(1)标量对矩阵的导数的定义:,对X逐元素求导排成与X尺寸相同的矩阵。
(2)全微分和导数的关系:首先来看是nx1向量的情况,此处的也即为我们所关心的梯度向量,所以如果求出了全微分,那么求梯度也就很自然了。当然实际情况我们要求的导数并非一个向量,而是一个矩阵,根据上面有:
不难理解,对于矩阵的情况,只是后面的导数和微分向量的内积变为了内积的 迹!!!
为了更好的理解,首先来看一个例子以验证上面的公式:
将上面的式子展开,再根据上面标量对矩阵求导的定义,不难直接写出:
而根据全微分定义,很容易写出
而上面的结果恰好等于:
有了上面的铺垫,下面便可以来求取交叉熵结合sofmax函数的导数了(要无障碍看懂下面推导内容,建议先看“矩阵求导术”文章中的几个例题):
求
注:
以下求解过程全部来源于上面文章中的过程,此处只对其中的细节作说明:
用到的性质:
推导过程如下:
再由矩阵导数与微分的关系:
BP算法正式推导!!!
有了上面的内容作为铺垫,下面推导BP算法的过程就相当容易,首先考虑输入为单样本,输入
求
令:
根据约定:习惯性的将损失函数对每一层的输出(未激活)的导数记为
如果最后一层采用的是softmax激活函数和交叉熵损失函数的结合,那么根据我们前面的推导:
也即为:输出-真实值............这可以作为softmax+Cross entropy的一个结论!!!
利用链导法则可以继续向后求取
首先需要得到
而容易看出
再次根据链导法则:
以上过程实际上是针对单个样本输入的情况!下面将会在其基础上推导出N个样本输入情况下的BP算法。
推导过程类似:下面直接给出结论:
BP算法的编程实现逻辑
以上部分针对两层的网络对BP算法进行了一个详细的推导!!但对于计算机来说,我们必须把整个反向传播过程理出一个迭代的逻辑出来才可以。
下面需要对N个隐藏层的反向传播作一个概括描述,假设网络有
上面的四条公式就概括了含有
为了更好的理解上面几组公式,不妨将前面推导出来的两层网络结果带入进行验证。
首先验证输出层:
由于我们所使用的激活函数为sigmoid,其导数可以用其自身表示为
回传到第一层进行验证:
该验证过程其实正是我们编写程序的逻辑!!!
反传的逻辑就可以如下编程实现:
- 在前传的过程中保存
- 反向传播的过程利用上面的四个公式来不断求取
以更新。注意初始化入口是在最后的输出层处的也即,其值根据输出层所采用的激活函数和损失函数类型决定,经典的softmax+Cross entropy对应的.常常当作结论使用!!!