重新入门神经网络·简单的前馈神经网络
学习神经网络最好的办法就是从头推导并用python实现一遍最简单的前馈神经网络FNN(forward feed neural network)
GitHub的人工智能copilot最近帮我补全了很多代码。在惊喜之余,我不免对人工智能替代程序员产生担忧。为了一探究竟,决定认真学习一下机器学习里面最火的一个领域—-神经网络。
看了前两章《neural network and deep learning》之后,我感觉自己学到不少。因此也决定从头推导出神经网络模型的训练算法,也即大名鼎鼎的back propagation反向传播算法。
一、基本定义和训练流程
FNN分类器是一种简单的神经网络模型:一个FNN神经网络接受多个输入,最终输出结果,实现对输入数据的分类。
所以训练FNN神经网络和拟合线性回归模型从原理上讲没什么区别:
定义损失函数–>梯度下降–>得到令损失函数最小的模型参数
如果定义神经网络模型,令第l层的第i个神经元 ,有
(1-1)
经过激活函数后,其输出为:
(1-2)
那么对于这个模型,可以定义它的损失函数L为:
(1-3)
其中 f(x) 为神经网络的输出,y是x对应的目标值。
为了得到令损失函数L最小的模型参数和,可以对损失函数L使用梯度下降法。
二、梯度的求解和反向传播算法back propagation
神经网络结构过于复杂,直接对和求导几乎无法完成。幸好上世纪机器学习的先驱们发明了反向传播算法,可以相当快速的求解梯度。
反向传播算法的核心是灵活运用微分中的链式法则chain-rule,并巧妙的定义了中间变量。
A. 梯度的求解流程
首先需要求出L的梯度和
(2-1)
类似的
(2-2)
为简化计算,对于一样本数据(x,y),定义
(2-3)
那么
(2-1-1)
类似的
(2-2-1)
所以只要求出C对于和的梯度,然后将一批样本数据带入求和即可。
B. 求各自的梯度
根据(1-1) 和 的定义,函数C的梯度为
(2-4)
注意是 i+1
(2-5)
注意是 i
所以简单求出
(2-6)
(2-7)
因此剩下一个未知项
C. 反向传播back propagation
利用反向传播算法可以迭代求出 :
首先函数C可以表示为对于第i+1层的所有神经元z的多变量函数
(3-1)
而根据(1-1)已经知道
(3-2)
应用多变量的链式法则可以得到
(3-3)
如果记作,则(3-3)就是
(3-4)
而根据(1-1),(1-2),使用链式法则可以轻易求出
(3-5)
所以递推公式为
(3-6)
D. 前馈传播求出最后一层
对于递推公式(3-6)需要找到初始值,这里可以用神经网络直接代入x求解:
由于就是最后一层,即神经网络f的最终输出,所以
最终
(3-8)
E. 结合起来完成推导
(4-1)
(4-2)
(3-6)
(3-8)
所以$L$的梯度,为
(4-3)
(4-4)
三、根据推导出的公式用numpy实现前馈神经网络
为了检验学到的知识,利用推导出的公式实现一个3层的简单前馈神经网络,用于预测sklearn自带的鸢尾花数据集分类。
To be continue…