神经元模型
神经网路中最基本的成分是“神经元”模型,在生物神经网络中,每个神经元与其他神经元相连,当他“兴奋”时,就会向相连的神经元发送化学物质,从而改变这些神经元类的电位;如果某神经元的电位超过一个“阈值”,那么他就会被激活。将上述描述当成一个数学模型——M-P神经元模型,神经元接收来自n个神经元传递过来的输入信号,这些输入信号通过带权重的连接进行传输,将神经元接收到的总输入值与神经元的自身的阈值进行比较,然后通过“激活函数”处理产生神经元的输出。理想中的激活函数是阶跃函数,但是它不连续,通常我们用sigmoid函数作为激活函数。
把许多神经元按一定的层次连接起来就得到了神经网络。一个神经网络视为包含了许多参数的数学模型,这个模型是由若干函数相互代入得到的。
感知机与多层网络
感知机由两层神经网络组成,输入层接收外界输入信号传递给输出层,输出层是M-P神经元,感知机能很容易的实现逻辑与、或、非运算,博客的下文附有实现感知机逻辑与或非的代码。
跟一般的,给定训练数据集,权重$w_i(i=1,2,...n)$以及阈值$\theta$可以通过学习得到,对训练样例(x,y),若当前感知机的输出为$\hat{y}$,则感知机权重将这样调整:
$$w_i\leftarrow w_i+\Delta w_i,\\\Delta w_i=\eta (y-\hat{y})x_i$$
式中$\eta$称为学习率,若感知机预测正确$\hat{y}=y$,则权重不需要调整。
需要注意的是,感知机只有输出层神经元进行激活函数处理,即只有一层功能神经元,其学习能力非常有限,感知机的学习过程一定会收敛,而求得适当的权重,感知机不能解决异或这样的非线性问题。要解决非线性问题,需要考虑考虑多层功能神经元,两层感知机能够解决异或问题,输出层和输入层之间的神经元被称为隐层,隐层和输出层都是拥有激活函数的功能神经元。常见的神经网络如下图所示的层级结构,每层的神经元与下一层的神经元会全连接,同层的神经元之间不存在连接,也不存在跨层连接。这样的神经网络通常称为“多层前馈神经网络”。其中输入层神经元负责接收输入信号,隐层和输出层神经元对信号进行加工,最终结果由输出层神经元输出,神经网络学到的东西,蕴含在连接权与阈值中。
误差逆传播算法
多层网络的学习能力比单层感知机强得多,我们要训练多层网络就要用到误差传播算法(error BackPropagtion),BP算法不仅可以用于多层前馈神经网络,还可用于其他类型的神经网络,如:递归神经网络...,但是我们通常说的“BP网络”一般是指BP算法训练多层前馈神经网络。
给定训练集$D={(x_1,y_1),(x)2,y_2),...,(x_m,y_m)}$,即输入实例由d个属性描述,输出$l$维实例向量。
上图是一个BP神经网络及算法中的变量符号,一共拥有d个输入神经元、$l$个输出神经元、q个隐层神经元的多层前馈网络结构,
$\theta_j$表示输出层第j个神经元的阈值
$\gamma_h$表示隐层第h个神经元的阈值
$v_{ih}$表示输入层第i个神经元与隐层第h个神经元之间的连接权
$w_{hj}$表示隐层第h个神经元与输出层第j个神经元之间的连接权
$a_h= \sum_ {i=1}^{d}v_{jh}x_i$表示隐层第h个神经元接收到的输入
$\beta_j=\sum_{h=1}^{j}w_{hj}b_h$表示输出层第j个神经元收到的输入
其中$b_h$为隐层第h个神经元的输出,隐层和输出层的功能神经元的激活函数都使用Sigmoida函数。
对训练样例$(x_k,y_k)$,神经网络的输出为$\hat{y}_k=(\hat{y}_1,\hat{y}_2...\hat{y}_l)$,神经网络最终输出=输出神经元的输入-输出神经元的阈值。$\hat{y}_j=f(\beta_j-\theta _j)$,则神经网络在$(x_k,y_k)$上的均方误差为$$E_k=\frac{1}{2}\sum_{h=1}^{l}(\hat{y}_j-y_j^k)^2$$
我们来算算神经网络一共需要多少参数:输入层到隐层$d*q$个权重、隐层到输出层$q*l$个权重、$q$个隐层神经元的阈值、$l$个输出层神经元的阈值。
BP是一个迭代学习的算法,在迭代的过程中采用感知机规则对参数进行更新,$v\leftarrow v+\Delta v$,我们就以隐层到输出层的连接权$w_{hj}$为例来进行推导。BP算法基于梯度下降策略,以目标的负梯度方向对参数进行调整。有$$\Delta w{hj}=-\eta \frac{\partial E_k}{\partial w_{hj}}$$
注意到$w_{hj}$先影响到第j个输出层神经元的输入值$\beta_j$,在影响到输出值$\hat{y}_y^k$,然后影响到$E_k$,有
$$\frac{\partial E_k}{\partial w_{hj}}=\frac{\partial E_k}{\partial \hat{y}_j^k}·\frac{\partial \hat{y}_j^k}{\partial \beta_j}·\frac{\partial \beta_j}{\partial w_{hj}}$$
由于$\beta_j=\sum_{h=1}^{j}w_{hj}b_h$,显然有$\frac{\partial \beta_j}{\partial w_{hj}}=b_h$
根据$E_k=\frac{1}{2}\sum_{h=1}^{l}(\hat{y}_j-y_j^k)^2$和$\hat{y}_j=f(\beta_j-\theta _j)$,在结合Sigmoid函数的性质${f}'=f(x)(1-f(x))$,有(下面负号哪来的,有待考证)
$$\frac{\partial E_k}{\partial w_{hj}}=\frac{\partial E_k}{\partial \hat{y}_j^k}·\frac{\partial \hat{y}_j^k}{\partial \beta_j}·b_h\\=-(\hat{y}_j-y_j^k){f}'(\beta _j-\theta _j)·b_h\\=\hat{y}_j(1-\hat{y}_j)(\hat{y}_j-y_j^k)·b_h$$
我们简化一下式子,令$g_i=\hat{y}_j(1-\hat{y}_j)(\hat{y}_j-y_j^k)$,则隐层到输出层的连接权$w_{hj}$的更新公式为
$$\Delta w_{hj}=\eta g_ib_h$$
类似的$$\Delta \theta _j=-\eta g_i$$
$$\Delta v_{ih}=\eta e_hx_i$$
$$\Delta \gamma _h=-\eta e_h$$
$$e_h=-\frac{\partial E_k}{\partial b_h}·\frac{\partial b_h}{\partial \alpha _h}\\=-\sum_{j=1}^{l}\frac{\partial E_k}{\partial \beta _j}·\frac{\partial \beta _j}{\partial b_h}{f}'(\alpha _h-\gamma _h)\\=\sum_{j=1}^{l}w_{hj}g_j{f}'(\alpha _h-\gamma _h)\\=b_h(1-b_h)\sum_{j=1}^{l}w_{hj}g_j$$
BP算法流程:
1、先将输入实例提供给输入层神经元,然后逐层将信号传递,知道产生输出层的结果
2、然后计算输出层的误差,再将误差逆向传播至隐层神经元
3、最后根据隐层神经元的误差来对连接权和阈值进行调整,该迭代过程循环进行,直到达到某些条件为止。
回过头来,BP算法的目标是要最小化训练集D上的累计误差$$E=\frac{1}{m}\sum_{k=1}^{m}E_k$$
我们之前介绍的是“标准BP算法”,每次仅仅针对一个训练样例来更新连接权和阈值,计算单个神经元的均方误差$E_k$。针对于此,推出了累积误差逆传播算法。累积BP算法直接针对累积误差最小化,不需要想标准BP算法那样进行更多次的迭代,只需要读取整个训练集D一遍后才对参数进行更新。但当参数下降到一定的程度后,再用标准BP算法求解最小误差。
一个包含足够多神经元的隐层,多层前馈网络就能以任意精度逼近任意复杂度的连续函数,然后设置多少隐层神经元仍然是未知数,实际应用仍然要靠“试错法”。
BP神经网络经常遭遇过拟合,也就是训练误差持续降低,但是测试误差很高。有两种策略来缓解BP神经网络的过拟合,
第一种策略“早停”:用训练集来计算梯度、更新连接权和阈值,测试集用来估计误差,若训练集误差降低但测试集误差升高,则停止训练,同时返回具有最小验证集误差的连接权和阈值。
第二种策略“正则化”:其基本思想是在误差目标函数中增加一个用于描述网络复杂度的部分,例如连接权与阈值平方和。仍令$E_k$表示第k个训练样本的误差,$w_i$表示连接权和阈值,则误差目标函数改变为:$$E=\lambda \frac{1}{m}\sum_{k=1}^{m}E_k+(1-\lambda )\sum_{i}w_i^2$$
其中$\lambda\in (0,1)$用于对经验误差与网络复杂度这两项进行折中,常通过交叉验证来估计。
全局做小和局部极小
其他常见的神经网络
RBF网络
ART网络
SOM网络
级联相关网络
Elman网络
Boltzmann机
深度学习
python实现
感知机逻辑与或非