View on GitHub

essay

All about my technical essays and practicals

重新入门神经网络·简单的前馈神经网络

学习神经网络最好的办法就是从头推导并用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…