上一篇文章学习矩阵求导的方法,这篇文章以上一篇文章为基础,推导一个三层的MLP的反向传播算法并给出它的代码实现。
前言
进行推导前需要先列出几个后面需要使用的函数
首先是大名的鼎鼎的交叉熵(Cross Entropy)函数,它的定义如下,其中 是独热码编码后的类别,的函数输出可以衡量输出是每个类别的概率大小。
我们后面的激活函数采用比较常见的函数,它的定义和导数是
当然,后面的推导也不会使用函数求导的完整结果(因为太长了),而是用表示,如果要更换或者别的激活函数,如只需要将求导结果带进去就可以了。
符号定义
假设我们的网络有 层,和分别表示第层的参数(wight)和偏置(bias),使用表示第层还没有经过激活函数的结果,使用 表示第层的输出同时也是第层的输入,也就是相当于, 函数作为激活函数。整个网络的前向传播的表达式可以写成下面的这种形式。
这里假设输入的向量和输出向量都是列向量
当然,如果不定义符号进行替换的话就可以写成下面的这种比较长的形式。
可以看到,MLP的本质其实就是我们最常见的复合函数的形式,只是我们的输入的变量是一个向量或者矩阵的形式。我们的任务就是借助上一篇文章中所提到的矩阵求导的手段求出 对每个和的偏导表达式。
第三层推导
根据前言部分函数的求导,可以直接求得的偏导数
将 写成迹的形式
通过红色的部分就得到了我们可以看到关于的微分形式,通过这个式子就可以写出关于的偏导数:
将前面蓝色的部分单独写下来,继续经过变形
同样的由红色部分,我们可以得到关于的偏导,蓝色的部分我们后续的推导需要用。
到这里,我们第三层的所有参数 和的梯度我们都算出来了。
第二层推导
接着把第三层推导剩下的蓝色部分单独提出来
根据上篇文章提到的可以化简为
可以得到
第一层推导
经过前两节的推导,我们得到了第二和第三层的表达式,但是他们的规律还不是非常的明显,我们继续推导第一层的偏导数。
可以得出
总结规律
将分别将 的偏导表达式写出来
假设网络有 层,编号依次为 1, 2 ...,损失函数关于网络最终输出的偏导为,可以比较明显地发现以下规律:
注意:这里的连乘是倒序的
的表达式为
跟类似,写出关于的偏导数,其实就是的偏导数去掉前面的
注意:这里的连乘是倒序的
代码实现
有了前面的推导过程,接下来就是代码的实现,代码将包含3个部分。
测试和训练数据生成
在开始实现之前,我们需要先准备一些数据用于验证我们的模型工作是否正常。这里就直接实用sklearn
库所提供的make_classification
函数生成测试用的数据
pythonN_CLASS = 3
from sklearn.datasets import make_classification
x, y = make_classification(n_samples=2000, n_features=5, n_classes=N_CLASS,
n_informative=5, n_repeated=0, n_redundant=0, n_clusters_per_class=1)
sns.scatterplot(x=x[:,0], y=x[:,1], hue=y)
测试用的数据将包含5个特征,也就是说输入的向量维度是5,总共有 3个类别