什么是神经网络
神经网络又称为人工神经网络(Artificial Neural Network , ANN),是指一系列受生物学和神经科学启发,而构造的数学模型。下图便是一个简单的神经元模型

神经元是形成神经网络的基本单元,如上图示,激活函数决定了该神经元是否有输出值,所以激活函数在此数学模型中至关重要。因其位置的特殊性,需要有以下特点:
- 连续可导
- 函数及其导数尽可能简单,可提高网络计算效率
- 值域要在合适的区间内。
综上,目前常使用的激活函数有如下几个:Sigmoid函数,ReLU函数,Swish函数,GELU函数,Maxout单元等。
神经元结构,只是神经网络的基础单元。而神经网络的组建则需要许多神经元进行协同传输。常用的网络结构有如下三种:前馈网络,记忆网络,和图网络。

前馈神经网络是基础,本次也以前馈神经网络为例说明。

下面来说一下神经元传播的原理
如下示,是一个三层神经网络模型。

现在:
输入数据: i_1 = 0.05 , i_2 = 0.10
输出数据:o_1 = 0.01 ,o_2 = 0.99
初始权重:w_1 = 0.15 ,w_2 = 0.20 ,w_3 = 0.25 ,w_4 = 0.30 ,w_5 = 0.40 ,w_6 = 0.45 ,w_7 = 0.50 ,w_8 = 0.55
那么向前传播的路径为:输入层,隐藏层,输出层。以此顺序计算每个神经元的加权和,直到输出。
net_{h1} = w_1*i_1+w_2*i_2+b_1*1
net_{h1} = 0.15*0.05+0.2*0.1+0.35*1 =0.3775
此时,神经元 h_1 开始通过激活函数处理数据 ,并进行输出。我们这里用sigmoid函数。
out_{h1} = \cfrac{1}{1+e^{-net_{h1}}}=\cfrac{1}{1+e^{-0.3775}} = 0.593269992
同理,神经元 h_2 的输出 out_{h2} 也可以计算出来。 out_{h2} = 0.596884378
下面是从隐藏层到输出层 ,与上面计算类似,也是各个值乘以权重,计算得到。
net_{o1} = w_5*out_{h1}+w_6*out_{h2}+b_2*1=1.105905967
out_{o1}= \cfrac{1}{1+e^{-net_{o1}}}=0.75136507
同理,可以计算出 out_{o2} = 0.772928465
到这一步,我们的前向传播结束了,我们得到了输出值 [0.75136507,0.772928465]
然而这与实际值[0.01,0.99]相差甚远,所以就需要重新想办法更新权值,重新计算输出。(所以神经网络的训练过程,也就是在不断更新权值的过程)
如何更新权值?
这时我们就用到了BP(Error Back Propagation Training 误差反向传播)算法,从本质上讲,BP算法就是以网络误差平方为目标函数、采用梯度下降法来计算目标函数的最小值。
步骤如下:
1、计算总误差:
E_{total} = \sum \cfrac{1}{2}(target-output)^2
因为有两个输出,所以需要计算一下 out_{o1} , out_{o2} 这两个输出的误差和。
E_{o1} = \cfrac{1}{2}(target_{01}-out_{o1})^2= \cfrac{1}{2}(0.01-0.75136507)^2 = 0.274811083
E_{o2}= 0.023560026
E_{total} = E_{o1}+E_{o2} = 0.274811083 + 0.023560026=0.298371109
2、误差出来了,那么权重对误差到底产生了多少影响呢?这个时候就需要权重对误差求导了。以权重 w_5 为例:
\cfrac{\varphi E_{total}}{\varphi w_5} = \cfrac{\varphi E_{total}}{\varphi out_{o1}}* \cfrac{\varphi out_{o1}}{\varphi net_{o1}} * \cfrac{\varphi net_{o1}}{\varphi w_5}
3、下面分别对各个因子求导。
计算 \cfrac{\varphi E_{total}}{\varphi out_{o1}} :
E_{total} = \cfrac{1}{2}(target_{o1}-out_{o1})^2+\cfrac{1}{2}(target_{o2}-out_{o2})^2
\cfrac{\varphi E_{total}}{\varphi out_{o1}} = 2* \cfrac{1}{2}(target_{o1}-out_{o1})^{2-1}*(-1)+0
=-(0.01-0.75136507) = 0.74136507
计算 \cfrac{\varphi out_{o1}}{\varphi net{o1}} :
out_{o1} = \cfrac{1}{1+e^{-net_{h1}}}
\cfrac{\varphi out_{o1}}{\varphi net_{o1}} = out_{o1}(1-out_{o1})
=0.75136507*(1-0.75136507) = 0.186815602
计算第三项 \cfrac{\varphi net_{o1}}{\varphi w{5}} :
net_{o1} = w_{5}*out_{h1}+w_6*out_{h2}+b_2*1
\cfrac{\varphi net_{o1}}{\varphi w{5}} = 1*out_{h1}*w_5^{(1-1)}+0+)
= out_{h1} = 0.593269992
上面三个计算结果相乘:
\cfrac{\varphi E_{total}}{\varphi w_5} = 0.74136507 *0.186815602*0.593269992
=0.082167041
样我们就计算出来整体误差相对于其中一个权重偏导数了,这里面仍需要灌输一个概念:数学只是一个度量,只是表示某种相关关系或者程度的一个度量,其实公式并没有什么实际意义。其所有意义只是人为赋予的某种规律下的总结。
我们设学习速率为 0.5 ,则有新的值
w_{5new} = w_{5} - 0.5 \cfrac{\varphi E_{total}}{\varphi w_5} = 0.4-0.5* 0.082167041
= 0.35891648
同理,使用同样的方式,可以更新其他权重值。
然后把新的权重值带入,重新计算,用这种方法不断迭代。直到得出满意权重。
如何确定中间层的隐藏节点个数?
在BP神经网络中,输入层和输出层的节点个数都是确定的,而隐含层节点个数不确定,那么应该设置为多少才合适呢?实际上,隐含层节点个数的多少对神经网络的性能是有影响的,有一个经验公式可以确定隐含层节点数目,如下:
h=\sqrt{m+n}+a
其中,h 位隐含层节点数,m 为输入层节点数目,n为输出层节点数目。a为1~10之间的调节常数。
以上便是神经网络的反向传播原理。