文章目录

  • 一、理论基础
    • 1、前向传播
    • 2、反向传播
    • 3、激活函数
    • 4、神经网络结构
  • 二、BP神经网络的实现
    • 1、训练过程(BPNN.py)
    • 2、测试过程(test.py)
    • 3、测试结果
    • 4、参考源码及实验数据集

一、理论基础

反向传播神经网络(BPNN)是1986年由Rumelhart和McClelland为首的科学家提出的概念,是一种按照误差逆向传播算法训练的多层前馈神经网络,最常见结构为3层。
数据在神经网络中的训练过程可分为前向传播过程与反向传播过程。通过前向传递过程将数据输入网络,数据依次通过隐含层与输出层并进行相关计算,得到输出值与目标值之间的误差;然后在反向进行传递过程进行神经网络权值、阈值的调整,重复此过程,使得神经网络的输出结果不断逼近真实值。
常见的BP神经网络为3层,输入层、隐含层、输出层。其中输入层传入数据,然后在隐含层与输出层分别与权值、阈值进行计算、从而实现非线性变换,最后在输出层与目标值进行比较获取误差。

1、前向传播

前向传播过程中隐含层与输出层的输出公式及误差公式计算如下:


其中W与b为隐含层与输出层的权值和阈值,x为隐含层与输出层的输入数据,g为激活函数,h为输出,E为误差,y_i为目标值,y ̂_i为实际值。

2、反向传播

反向传播过程中输出层的误差项计算公式如下:

其中V与b_2为输出层的权值和阈值,E为损失函数。隐含层的误差项的计算公式可以此类推进行计算。
隐含层与输出层的权值和阈值的更新计算公式如下:


损失函数原理参考:
机器学习基础知识之损失函数

3、激活函数

在前向传播过程中,输入数据除了和隐含层、输出层的权值、阈值进行计算外,还会使用激活函数g对计算结果进行非线性计算。激活函数作为人工神经网络中神经元的核心,其作用在于将非线性因素引入神经元,它在输入传递至输出的过程中进行函数转换,以此将无限范围内的输入非线性变换为有限范围内的输出,一旦人工神经网络缺少激活函数,那么它每一层的数据传递过程就变成了单纯的矩阵计算过程,无论数据传递了多少层,最后的输出都是输入的线性组合。
常见的激活函数如下:
1、sigmod
Sigmod函数是一种常见的S型函数,它能够将输入变量映射到0到1之间,其公式如下:

2、Tanh
Tanh函数是一种双曲正切函数,它是由双曲正弦函数与双曲余弦函数推导而来,同样将输入处理成0到1之间,与sigmod不同的是它的输出是零中心的,其公式如下:

3、Relu
Relu函数将输入和零进行比较,输出较大值,其公式如下:

4、Leaky Relu
Leaky Relu函数和Relu函数不同的是,当输入小于零时,将输入与常量gamma进行计算作为输出,其公式如下:

激活函数对比及适用场景参考:
神经网络基础知识之激活函数

4、神经网络结构

BP神经网络的输入层和输出层层数通常需要根据实际问题进行确定,而隐含层的层数即节点数的确定,通常没有一个确定的方法,一般通过设置不同的节点数然后比较其网络训练结果来选择最优数量,而节点数的范围可通过以下公式进行确定:

其中h为隐含层单元数,n为输入层单元数,m为输出层单元数,a为1到10之间的常数。

二、BP神经网络的实现

以数据预测为例,下面介绍BP神经网络的实现过程。
选用某省市的表层土壤重金属元素数据集作为实验数据,该数据集总共96组,随机选择其中的24组作为测试数据集,72组作为训练数据集。选取重金属Ti的含量作为待预测的输出特征,选取重金属Co、Cr、Mg、Pb作为模型的输入特征。

1、训练过程(BPNN.py)

#库的导入
import numpy as np
import pandas as pd#激活函数tanh
def tanh(x):return (np.exp(x)-np.exp(-x))/(np.exp(x)+np.exp(-x))
#激活函数偏导数
def de_tanh(x):return (1-x**2)#输入数据的导入
df = pd.read_csv("train.csv")
df.columns = ["Co", "Cr", "Mg", "Pb", "Ti"]
Co = df["Co"]
Co = np.array(Co)
Cr = df["Cr"]
Cr = np.array(Cr)
Mg=df["Mg"]
Mg=np.array(Mg)
Pb = df["Pb"]
Pb =np.array(Pb)
Ti = df["Ti"]
Ti = np.array(Ti)
samplein = np.mat([Co,Cr,Mg,Pb])
#数据归一化,将输入数据压缩至0到1之间,便于计算,后续通过反归一化恢复原始值
sampleinminmax = np.array([samplein.min(axis=1).T.tolist()[0],samplein.max(axis=1).T.tolist()[0]]).transpose()
sampleout = np.mat([Ti])
sampleoutminmax = np.array([sampleout.min(axis=1).T.tolist()[0],sampleout.max(axis=1).T.tolist()[0]]).transpose()
sampleinnorm = (2*(np.array(samplein.T)-sampleinminmax.transpose()[0])/(sampleinminmax.transpose()[1]-sampleinminmax.transpose()[0])-1).transpose()
sampleoutnorm = (2*(np.array(sampleout.T)-sampleoutminmax.transpose()[0])/(sampleoutminmax.transpose()[1]-sampleoutminmax.transpose()[0])-1).transpose()
noise = 0.03*np.random.rand(sampleoutnorm.shape[0],sampleoutnorm.shape[1])
sampleoutnorm += noisemaxepochs = 5000  #训练次数
learnrate = 0.001  #学习率
errorfinal = 0.65*10**(-3)  #停止训练误差阈值
samnum = 72  #输入数据数量
indim = 4  #输入层节点数
outdim = 1  #输出层节点数
hiddenunitnum = 8  #隐含层节点数#随机生成隐含层与输出层的权值w和阈值b
scale = np.sqrt(3/((indim+outdim)*0.5))  #最大值最小值范围为-1.44~1.44
w1 = np.random.uniform(low=-scale, high=scale, size=[hiddenunitnum,indim])
b1 = np.random.uniform(low=-scale, high=scale, size=[hiddenunitnum,1])
w2 = np.random.uniform(low=-scale, high=scale, size=[outdim,hiddenunitnum])
b2 = np.random.uniform(low=-scale, high=scale, size=[outdim,1])#errhistory存储误差
errhistory = np.mat(np.zeros((1,maxepochs)))#开始训练
for i in range(maxepochs):print("The iteration is : ", i)#前向传播,计算隐含层、输出层输出hiddenout = tanh((np.dot(w1,sampleinnorm).transpose()+b1.transpose())).transpose()networkout = tanh((np.dot(w2,hiddenout).transpose()+b2.transpose())).transpose()#计算误差值err = sampleoutnorm - networkoutloss = np.sum(err**2)/2print("the loss is :",loss)errhistory[:,i] = loss#判断是否停止训练if loss < errorfinal:break#反向传播,利用结果误差进行误差项的计算delta2 = err*de_tanh(networkout)delta1 = np.dot(w2.transpose(),delta2)*de_tanh(hiddenout)#计算输出层的误差项dw2 = np.dot(delta2,hiddenout.transpose())dw2 = dw2 / samnumdb2 = np.dot(delta2,np.ones((samnum,1)))db2 = db2 / samnum#计算隐含层的误差项dw1 = np.dot(delta1,sampleinnorm.transpose())dw1 = dw1 / samnumdb1 = np.dot(delta1,np.ones((samnum,1)))db1 = db1/samnum#对权值、阈值进行更新w2 += learnrate*dw2b2 += learnrate*db2w1 += learnrate*dw1b1 += learnrate*db1
print('更新的权重w1:',w1)
print('更新的偏置b1:',b1)
print('更新的权重w2:',w2)
print('更新的偏置b2:',b2)
print("The loss after iteration is :",loss)#保存训练结束后的权值、阈值,用于测试
np.save("w1.npy",w1)
np.save("b1.npy",b1)
np.save("w2.npy",w2)
np.save("b2.npy",b2)

2、测试过程(test.py)

#库的导入
import numpy as np
import pandas as pd#激活函数tanh
def tanh(x):return (np.exp(x)-np.exp(-x))/(np.exp(x)+np.exp(-x))
#输入数据的导入,用于测试数据的归一化与返归一化
df = pd.read_csv("train.csv")
df.columns = ["Co", "Cr", "Mg", "Pb", "Ti"]
Co = df["Co"]
Co = np.array(Co)
Cr = df["Cr"]
Cr = np.array(Cr)
Mg=df["Mg"]
Mg=np.array(Mg)
Pb = df["Pb"]
Pb =np.array(Pb)
Ti = df["Ti"]
Ti = np.array(Ti)
samplein = np.mat([Co,Cr,Mg,Pb])sampleinminmax = np.array([samplein.min(axis=1).T.tolist()[0],samplein.max(axis=1).T.tolist()[0]]).transpose()
sampleout = np.mat([Ti])
sampleoutminmax = np.array([sampleout.min(axis=1).T.tolist()[0],sampleout.max(axis=1).T.tolist()[0]]).transpose()#导入训练的权值、阈值
w1=np.load('w1.npy')
w2=np.load('w2.npy')
b1=np.load('b1.npy')
b2=np.load('b2.npy')#测试数据的导入
df = pd.read_csv("test.csv")
df.columns = ["Co", "Cr", "Mg", "Pb", "Ti"]
Co = df["Co"]
Co = np.array(Co)
Cr = df["Cr"]
Cr = np.array(Cr)
Mg=df["Mg"]
Mg=np.array(Mg)
Pb = df["Pb"]
Pb =np.array(Pb)
Ti = df["Ti"]
Ti = np.array(Ti)
input=np.mat([Co,Cr,Mg,Pb])#测试数据数量
testnum = 24#测试数据中输入数据的归一化
inputnorm=(2*(np.array(input.T)-sampleinminmax.transpose()[0])/(sampleinminmax.transpose()[1]-sampleinminmax.transpose()[0])-1).transpose()
#隐含层、输出层的计算
hiddenout = tanh((np.dot(w1,inputnorm).transpose()+b1.transpose())).transpose()
networkout = tanh((np.dot(w2,hiddenout).transpose()+b2.transpose())).transpose()
#对输出结果进行反归一化
diff = sampleoutminmax[:,1]-sampleoutminmax[:,0]
networkout2 = (networkout+1)/2
networkout2 = networkout2*diff+sampleoutminmax[0][0]
output1=networkout2.flatten()
output1=output1.tolist()
for i in range(testnum):output1[i] = float('%.2f'%output1[i])
print("the prediction is:",output1)#将输出结果与真实值进行对比,计算误差
output=Ti
rmse = (np.sum(np.square(output-output1))/len(output))**0.5
mae = np.sum(np.abs(output-output1))/len(output)
average_loss1=np.sum(np.abs((output-output1)/output))/len(output)
mape="%.2f%%"%(average_loss1*100)
f1 = 0
for m in range(testnum):f1 = f1 + np.abs(output[m]-output1[m])/((np.abs(output[m])+np.abs(output1[m]))/2)
f2 = f1 / testnum
smape="%.2f%%"%(f2*100)
print("the MAE is :",mae)
print("the RMSE is :",rmse)
print("the MAPE is :",mape)
print("the SMAPE is :",smape)#计算预测值与真实值误差与真实值之比的分布
A=0
B=0
C=0
D=0
E=0
for m in range(testnum):y1 = np.abs(output[m]-output1[m])/np.abs(output[m])if y1 <= 0.1:A = A + 1elif y1 > 0.1 and y1 <= 0.2:B = B + 1elif y1 > 0.2 and y1 <= 0.3:C = C + 1elif y1 > 0.3 and y1 <= 0.4:D = D + 1else:E = E + 1
print("Ratio <= 0.1 :",A)
print("0.1< Ratio <= 0.2 :",B)
print("0.2< Ratio <= 0.3 :",C)
print("0.3< Ratio <= 0.4 :",D)
print("Ratio > 0.4 :",E)

3、测试结果


注:由于每次初始化生成的参数不同,因此对参数设置相同的神经网络进行多次训练和预测,测试结果不会完全一致,此外测试结果的好坏也会受到隐含层节点数、学习率、训练次数等参数的影响。

4、参考源码及实验数据集

参考源码及实验数据集

反向传播神经网络(BPNN)的实现(Python,附源码及数据集)相关推荐

  1. 径向基神经网络(RBFNN)的实现(Python,附源码及数据集)

    文章目录 一.理论基础 1.径向基神经网络结构 2.前向传播过程 3.反向传播过程 4.建模步骤 二.径向基神经网络的实现 1.训练过程(RBFNN.py) 2.测试过程(test.py) 3.测试结 ...

  2. 智能优化算法之遗传算法(GA)的实现(基于二进制编码,Python附源码)

    文章目录 一.遗传算法的实现思路 二.基于二进制编码方式的遗传算法的实现 1.库的导入 2.目标函数 3.个体编码函数 4.个体解码函数 5.选择函数 6.交叉函数 7.变异函数 8.算法主流程 一. ...

  3. 爬虫实战—轻松爬取全国40城5000+地铁站点数据!附源码和数据集

    原文链接:小一教你轻松爬取全国40城5000+地铁站点数据!附源码和数据集 大家好,我是小一 上一篇文章讲了一个失败的数据分析案例,导致失败最最主要的原因就两个字:数据 有时候,爬虫爬到的数据是很珍贵 ...

  4. 【Python机器学习】决策树、逻辑回归、神经网络等模型对电信用户流失分类实战(附源码和数据集)

    需要源码和数据集请点赞关注收藏后评论区留言私信~~~ 电信用户流失分类 该实例数据来自kaggle,它的每一条数据为一个用户的信息,共有21个有效字段,其中最后一个字段Churn标志该用户是否流失 1 ...

  5. PyTorch使用快速梯度符号攻击(FGSM)实现对抗性样本生成(附源码和数据集MNIST手写数字)

    需要源码和数据集请点赞关注收藏后评论区留言或者私信~~~ 一.威胁模型 对抗性机器学习,意思是在训练的模型中添加细微的扰动最后会导致模型性能的巨大差异,接下来我们通过一个图像分类器上的示例来进行讲解, ...

  6. 【Keras+计算机视觉+Tensorflow】DCGAN对抗生成网络在MNIST手写数据集上实战(附源码和数据集 超详细)

    需要源码和数据集请点赞关注收藏后评论区留言私信~~~ 一.生成对抗网络的概念 生成对抗网络(GANs,Generative Adversarial Nets),由Ian Goodfellow在2014 ...

  7. 反向传播神经网络 BPNN

    回顾感知器学习算法,其核心思想是梯度下降法,即以训练样本被错分的程度为目标函数,训练中每次出现错误时便使权系数朝着目标函数相对于权系数负梯度方向更新,知道目标中没有被错分的样本为止. 而多层感知器模型 ...

  8. 【模式识别】反向传播神经网络 BPNN

    回顾感知器学习算法,其核心思想是梯度下降法,即以训练样本被错分的程度为目标函数,训练中每次出现错误时便使权系数朝着目标函数相对于权系数负梯度方向更新,知道目标中没有被错分的样本为止. 而多层感知器模型 ...

  9. 【实战项目】基于BP神经网络的温度预测(附源码)

    文章目录 1. BP神经网络是什么 2. 生物神经的运作原理 3. 神经网络的基础架构 4. 运算过程:矩阵乘法 5. 如何去调参数:微积分 上面我们了解了一下概念,现在我们来看看项目: 1:搭建BP ...

最新文章

  1. c语言大整数除法思路,大整数除法
  2. 分布式服务框架 Zookeeper -- 管理分布式环境中的数据--转载
  3. Python中a和a[:]有什么区别?
  4. Apache Flink 读取本地文件,处理数据,导入ES
  5. 别等了,全面「远程办公」凉了
  6. 边缘化搭建DotNet Core 2.1 自动化构建和部署环境(上)
  7. php7如何安装swoole,PHP7如何安装Swoole?
  8. vue设置html自动跳转路由器,vue2.0项目实现路由跳转的方法详解
  9. 19 CO配置-控制-产品成本控制-产品成本计划编制-定义日期控制
  10. [前端]网页网络分析及前端网络优化
  11. C语言练习——判断位数
  12. Acrel-6000/B电气火灾监控系统在千山大厦的应用
  13. spss导入数据 error:对于当前服务器语言环境而言,文本过长
  14. python爬数据是什么意思-这python爬虫是什么意思?爬虫怎么抓取数据?
  15. WorkPlus助力“深i企”打造移动数字化底座
  16. MCU控制继电器的电路详解
  17. 01 linux 下tcl源码编译安装和tcl手册使用
  18. Steam根目录下userdata文件夹命名规则
  19. 孙陶然:创业是和平年代最靓丽的生活方式
  20. java反编译是什么_什么是Java代码的编译与反编译?

热门文章

  1. Gibbs Sampling\吉布斯采样(一)
  2. Resources文件夹
  3. Android NDK 中堆栈日志 add2line 的分析实践
  4. ERR_ABORTED 404
  5. 信息安全导论 实验一 古典密码学
  6. git切换分支报错:error: pathspec 'origin/XXX' did not match any file(s) known to git
  7. iphone html5 浏览器缓存文件,html5中localStorage 在苹果设备上总结
  8. aliyun - ddns
  9. 小程序中的axio——flyio的使用
  10. R语言绘图样式设置(符号、线条、颜色、文本属性)