神经网络作为运用广泛的智能算法,被用于很多技术领域,虽然在Matlab等软件当中已经封装了相关的函数库,任何人都能够十分方便地使用编程软件构建神经网络。但是笔者认为如果不能详细了解神经网络的构建过程,那么对于神经网络的了解也将是雾里看花,使用也是十分僵化不能变通。因此,详细地自主架构神经网络是很有必要的。
目标:BP神经网络 作用:拟合数据,输入数据为0.32,0.87,0.89,0.33;目标输出为0.99,0.32,0.45,0.12。 参考:https://blog.csdn.net/zhaomengszu/article/details/77834845.
神经网络算法是典型的学习型算法,其输出结果与执行次数有关,算法系统中存在负反馈调节,符合如下的系统流程: BP神经网络主要由前向传播和后向传播两个算法组成,通过正向传播和反向传播之间的不断循环实现基于目标的学习。正向传播的作用是复现我们的推演假设,得到推演结果,反向传播算法的主要作用是依据上一次推演结果判断误差,并实现对于参数的调整,预备下一次运算。其中决定神经网络性能之一的便是反向传播的方式和方法,BP神经网络采用的是梯度下降法来确定性能。由于本文主要任务是将概念性的公式翻译成编程语言,因此算法的推导和变形不做过多赘述,仅列出已经经过简化之后的公式,相关推导请阅读参考博文。
构建神经网络为4输入4输出,目标隐含层的个数设计为3,层数为1,示意图如下: 具体算法步骤: 1)确定相关数值:设定每层传播之间的权值(图示的w1和w2,分别为43和34的数组),确定学习效率yeta=0.5,输入数据和参考目标; 2)构建前向传播算法,确定隐含层的数据,使用激活函数为Sigmod函数,具体公式为:
如法炮制,计算出实际输出层的值: 完成前向传播模块布置; 3)构建后向传播算法,更新w1和w2的值,具体公式如下: 由于参考文章中已有推导证明,可以自行阅读。 如法炮制再向前更新一步,计算出w1,但是结果略微有所区别,具体公式如下: 前向传播算法完成。 4)加上循环嵌套和相应的连接代码,完成算法,具体代码如下:
a=[0.32,0.87,0.89,0.33] #实际输入 target_c=[0.99,0.32,0.45,0.12] #目标输出 w1=[[0.4,0.5,0.6],[0.4,0.5,0.6],[0.4,0.5,0.6],[0.4,0.5,0.6]] #第一层传播权值 w2=[[0.3,0.4,0.5,0.6],[0.4,0.5,0.6,0.7],[0.5,0.6,0.7,0.8]] #第二层传播权值 Etc=[] #隐含层数据 c=[] #实际输出 yeta=0.5 e=2.71828 def forward(): #前项传播算法 for i in range(3): x1=0 for j in range(4): x1=x1+a[j]*w1[j][i] x1=1/(1+e**(-1*x1)) Etc.append(x1) for i in range(4): x2=0 for j in range(3): x2=x2+Etc[j]*w2[j][i] x2=1/(1+e**(-1*x2)) c.append(x2) def behind(): #后向传播算法 for i in range(3): for j in range(4): w2[i][j]=w2[i][j]+yeta*(target_c[j]-c[j])*c[j]*(1-c[j])*Etc[i] for i in range(4): for j in range(3): x4=0 for k in range(4): x4=x4+(target_c[k]-c[k])*c[k]*(1-c[k])*w2[j][k] w1[i][j]=w1[i][j]+yeta*x4*Etc[j]*(1-Etc[j])*a[i] def clear(): c.clear() Etc.clear() for i in range(100000): #学习过程 forward() behind() clear() forward() print(c)上述代码思路与参考思路略有不同,做过一定的简化,但是并不影响运行,从最后所得出的数据便可以很直观地看出来。
下面展示一下具体执行过程中的结果输出:
上图所示分别为学习过程执行了1次、10次、100次、1000次、10000次之后的结果,最终的结果和参考目标0.98,0.32,0.45,0.12的误差几乎没有,说明收敛完成,精度很高。 并给出相关的参数值: w1=[1.388,1.458,1.528 3.086,3.105,3.125 3.147,3.165,3.184 1.419,1.488,1.558] w2=[4.161,-1.448,-0.923,-2.721 4.283,-1.366,-0.836,-2.651 4.404,-1.284,-0.750,-2.580]
本次代码个人认为比较成功地实现了BP神经网络的作用,最终也得到了比较精确的结果,通过数据我还发现:BP神经网络在处理尖峰的时候会出现数据消峰现象,即在学习次数有限时,位于尖峰处的数据响应永远是最慢的。观察上述数据我们发现在执行10000次学习之后,后三个数据的精度都已经达到了0.0001,而第一位数据与目标的差距数量级还在0.01。分析原因是BP神经网络的收敛函数速度较慢,对于偏差比较大的数据不能够较快地收敛到位,因此才会出现数据消峰的情况。测试过程中出现的第一个数据的问题符合BP神经网络的特征,因此认为测试代码的确符合BP神经网络的运算。 当然,笔者也感觉到此次代码存在不足,后面会继续修正。