BP神经网络算法学习及代码实现(含Python源码)
目录
- 1.写在前面
- 2.BP神经网络推导
- 2.1前向传播
- 2.2反向传播
- 2.2.1求解梯度矩阵
- 2.2.2梯度下降法
- 2.2.3反向传播公式推导
- 输出层误差
- 推导
- 隐藏层误差
- 参数变化率
- 参数更新
- 3.代码实现
- 3.1过程解释
- 3.1.1导入库
- 3.1.2定义sigmoid函数
- 3.1.3导入数据集
- 3.1.4初始化权重和偏倚
- 3.1.5开始训练
- 3.2完整代码
- 3.3预测结果
1.写在前面
BP神经网络算法作为作为机器学习最基础的算法,非常适合入门。透彻掌握其原理将对于今后的机器学习有很大的帮助。
2.BP神经网络推导
2.1前向传播
前向传播过程可以表示为:
O[l]=σ(w[l]I[l−1]+b[l])O^{[l]}=\sigma\left(w^{[l]} I^{[l-1]}+b^{[l]}\right) O[l]=σ(w[l]I[l−1]+b[l])
2.2反向传播
2.2.1求解梯度矩阵
假设函数 f:Rn×1→Rf:R^{n \times 1} \rightarrow Rf:Rn×1→R 将输入的列向量(shape: n×1n \times 1n×1 )映射为一个实数。那么,函数 fff 的梯度定义为:
∇xf(x)=[∂f(x)∂x1∂f(x)∂x2⋮∂f(x)∂xn]\nabla_{x} f(x)=\left[\begin{array}{c}\frac{\partial f(x)}{\partial x_{1}} \\ \frac{\partial f(x)}{\partial x_{2}} \\ \vdots \\ \frac{\partial f(x)}{\partial x_{n}}\end{array}\right]∇xf(x)=⎣⎢⎢⎢⎢⎡∂x1∂f(x)∂x2∂f(x)⋮∂xn∂f(x)⎦⎥⎥⎥⎥⎤
同理,假设函数 f:Rm×n→Rf: R^{m \times n} \rightarrow Rf:Rm×n→R 将输入的矩阵(shape: m×nm \times nm×n )映射为一个实数。函数 fff 的梯度定义为:
∇Af(A)=[∂f(A)∂A11∂f(A)∂A12…∂f(A)∂A13∂f(A)∂A21∂f(A)∂A22…∂f(A)∂A2n⋮⋮⋱⋮∂f(A)∂Am1∂f(A)∂Am2…∂f(A)∂Amn]\nabla_{A} f(A)=\left[\begin{array}{cccc}\frac{\partial f(A)}{\partial A_{11}} & \frac{\partial f(A)}{\partial A_{12}} & \dots & \frac{\partial f(A)}{\partial A_{13}} \\ \frac{\partial f(A)}{\partial A_{21}} & \frac{\partial f(A)}{\partial A_{22}} & \dots & \frac{\partial f(A)}{\partial A_{2 n}} \\ \vdots & \vdots & \ddots & \vdots \\ \frac{\partial f(A)}{\partial A_{m 1}} & \frac{\partial f(A)}{\partial A_{m 2}} & \dots & \frac{\partial f(A)}{\partial A_{m n}}\end{array}\right]∇Af(A)=⎣⎢⎢⎢⎢⎡∂A11∂f(A)∂A21∂f(A)⋮∂Am1∂f(A)∂A12∂f(A)∂A22∂f(A)⋮∂Am2∂f(A)……⋱…∂A13∂f(A)∂A2n∂f(A)⋮∂Amn∂f(A)⎦⎥⎥⎥⎥⎤
可以简化为:
(∇Af(A))ij=∂f(A)∂Aij\left(\nabla_{A} f(A)\right)_{i j}=\frac{\partial f(A)}{\partial A_{i j}}(∇Af(A))ij=∂Aij∂f(A)
2.2.2梯度下降法
从几何意义,梯度矩阵代表了函数增加最快的方向,沿着梯度相反的方向可以更快找到最小值。
反向传播的过程就是利用梯度下降法原理,逐步找到成本函数的最小值,得到最终的模型参数。
2.2.3反向传播公式推导
输出层误差
δj[L]=∂L∂aj[L]σ′(zj[L])\delta_{j}^{[L]}=\frac{\partial L}{\partial a_{j}^{[L]}} \sigma^{\prime}\left(z_{j}^{[L]}\right) δj[L]=∂aj[L]∂Lσ′(zj[L])
L表示输出层层数。以下用 ∂L\partial L∂L 表示 ∂L(a[L],y)\partial L\left(a^{[L]}, y\right)∂L(a[L],y)
推导
计算输出层的误差 δj[L]=∂L∂zj[L]\delta_{j}^{[L]}=\frac{\partial L}{\partial z_{j}^{[L]}}δj[L]=∂zj[L]∂L ,根据链式法则
δj[L]=∑k∂L∂ak[L]∂ak[L]∂zj[L]\delta_{j}^{[L]}=\sum_{k} \frac{\partial L}{\partial a_{k}^{[L]}} \frac{\partial a_{k}^{[L]}}{\partial z_{j}^{[L]}}δj[L]=∑k∂ak[L]∂L∂zj[L]∂ak[L]
输出层不一定只有一个神经元,可能有多个神经元。成本函数是每个输出神经元的损失函数之和,每个输出神经元的误差与其它神经元没有关系,所以只有k=jk=jk=j 的时候值不是0。
当k≠jk\neq jk=j 时,∂L∂zj[L]=0\frac{\partial L}{\partial z_{j}^{[L]}}=0∂zj[L]∂L=0 ,简化误差 δj[L]\delta_{j}^{[L]}δj[L] ,得到
δj[L]=∂L∂aj[L]∂aj[L]∂zj[L]\delta_{j}^{[L]}=\frac{\partial L}{\partial a_{j}^{[L]}} \frac{\partial a_{j}^{[L]}}{\partial z_{j}^{[L]}}δj[L]=∂aj[L]∂L∂zj[L]∂aj[L]
σ\sigmaσ 表示激活函数,由aj[L]=σ(zj[L])a_{j}^{[L]}=\sigma\left(z_{j}^{[L]}\right)aj[L]=σ(zj[L]),计算出 ∂aj[L]∂zj[L]=σ′(zj[L])\frac{\partial a_{j}^{[L]}}{\partial z_{j}^{[L]}}=\sigma^{\prime}\left(z_{j}^{[L]}\right)∂zj[L]∂aj[L]=σ′(zj[L]) ,代入最后得到
δj[L]=∂L∂aj[L]σ′(zj[L])\delta_{j}^{[L]}=\frac{\partial L}{\partial a_{j}^{[L]}} \sigma^{\prime}\left(z_{j}^{[L]}\right)δj[L]=∂aj[L]∂Lσ′(zj[L])
隐藏层误差
δj[l]=∑kwkj[l+1]δk[l+1]σ′(zj[l])\begin{array}{c} \delta_{j}^{[l]}=\sum_{k} w_{k j}^{[l+1]} \delta_{k}^{[l+1]} \sigma^{\prime}\left(z_{j}^{[l]}\right) \end{array} δj[l]=∑kwkj[l+1]δk[l+1]σ′(zj[l])
推导
zk[l+1]=∑jwkj[l+1]aj[l]+bk[l+1]=∑jwkj[l+1]σ(zj[l])+bk[l+1]z_{k}^{[l+1]}=\sum_{j} w_{k j}^{[l+1]} a_{j}^{[l]}+b_{k}^{[l+1]}=\sum_{j} w_{k j}^{[l+1]} \sigma\left(z_{j}^{[l]}\right)+b_{k}^{[l+1]}zk[l+1]=∑jwkj[l+1]aj[l]+bk[l+1]=∑jwkj[l+1]σ(zj[l])+bk[l+1]
对 zj[l]z_{j}^{[l]}zj[l] 求偏导
∂zk[l+1]∂zj[l]=wkj[l+1]σ′(zj[l])\frac{\partial z_{k}^{[l+1]}}{\partial z_{j}^{[l]}}=w_{k j}^{[l+1]} \sigma^{\prime}\left(z_{j}^{[l]}\right)∂zj[l]∂zk[l+1]=wkj[l+1]σ′(zj[l])
根据链式法则
δj[l]=∂L∂zj[l]=∂L∂zk[l+1]∂zk[l+1]∂zj[l]=∑kwkj[l+1]δk[l+1]σ′(zj[l])\delta_{j}^{[l]}=\frac{\partial L}{\partial z_{j}^{[l]}}=\frac{\partial L}{\partial z_{k}^{[l+1]}}\frac{\partial z_{k}^{[l+1]}}{\partial z_{j}^{[l]}}=\sum_{k} w_{k j}^{[l+1]} \delta_{k}^{[l+1]} \sigma^{\prime}\left(z_{j}^{[l]}\right)δj[l]=∂zj[l]∂L=∂zk[l+1]∂L∂zj[l]∂zk[l+1]=∑kwkj[l+1]δk[l+1]σ′(zj[l])
参数变化率
∂L∂bj[l]=δj[l]∂L∂wjk[l]=ak[l−1]δj[l]\begin{array}{c} \frac{\partial L}{\partial b_{j}^{[l]}}=\delta_{j}^{[l]} \\ \frac{\partial L}{\partial w_{j k}^{[l]}}=a_{k}^{[l-1]} \delta_{j}^{[l]} \end{array} ∂bj[l]∂L=δj[l]∂wjk[l]∂L=ak[l−1]δj[l]
推导
zj[l]=∑kwjk[l]ak[l−1]+bk[l]z_{j}^{[l]}=\sum_{k} w_{j k}^{[l]} a_{k}^{[l-1]}+b_{k}^{[l]}zj[l]=∑kwjk[l]ak[l−1]+bk[l]
L 对 bj[l]b_{j}^{[l]}bj[l] 求偏导,根据链式法则得到
∂L∂bj[l]=∂L∂zj[l]∂zj[l]bj[l]=∂L∂zj[l]∗1=δj[l]\frac{\partial L}{\partial b_{j}^{[l]}}=\frac{\partial L}{\partial z_{j}^{[l]}} \frac{\partial z_{j}^{[l]}}{b_{j}^{[l]}}= \frac{\partial L}{\partial z_{j}^{[l]}} * 1 = \delta_{j}^{[l]}∂bj[l]∂L=∂zj[l]∂Lbj[l]∂zj[l]=∂zj[l]∂L∗1=δj[l]
L 对 wjk[l]w_{j k}^{[l]}wjk[l] 求偏导,根据链式法则得到
∂L∂wjk[l]=∂L∂zj[l]∂zj[l]wjk[l]=ak[l−1]δj[l]\frac{\partial L}{\partial w_{j k}^{[l]}}=\frac{\partial L}{\partial z_{j}^{[l]}} \frac{\partial z_{j}^{[l]}}{w_{j k}^{[l]}}=a_{k}^{[l-1]} \delta_{j}^{[l]}∂wjk[l]∂L=∂zj[l]∂Lwjk[l]∂zj[l]=ak[l−1]δj[l]
参数更新
根据梯度下降法原理,朝着梯度的反方向更新参数
bj[l]←bj[l]−α∂L∂bj[l]wjk[l]←wjk[l]−α∂L∂wjk[l]\begin{array}{c} b_{j}^{[l]} \leftarrow b_{j}^{[l]}-\alpha \frac{\partial L}{\partial b_{j}^{[l]}} \\ w_{j k}^{[l]} \leftarrow w_{j k}^{[l]}-\alpha \frac{\partial L}{\partial w_{j k}^{[l]}} \end{array} bj[l]←bj[l]−α∂bj[l]∂Lwjk[l]←wjk[l]−α∂wjk[l]∂L
3.代码实现
3.1过程解释
本次代码实现决定考虑四层神经网络,即含有两个隐层。其中,有三个输入单元,一个输出单元,第一层隐层含有四个节点,第二层隐层含有二个节点。
并且,激励函数采用sigmoid函数。
3.1.1导入库
import numpy as np
3.1.2定义sigmoid函数
def sigmoid(x, deriv = False):if(deriv == True):return x*(1-x)else:return 1/(1+np.exp(-x))
当deriv为默认值False时,进行sigmoid函数的运算;
当deriv为True时,对函数求导运算。(其中,求导运算时输入的x值应为函数值而非自变量)
3.1.3导入数据集
#input dataset
X = np.array([[0,0,1],[0,1,1],[1,0,1],[1,1,1]])#output dataset
y = np.array([[0,1,1,0]]).T
3.1.4初始化权重和偏倚
权重weight01表示从第0层(即输入层)到第1层(第一隐层)的权重矩阵;
偏倚bias1表示第1层(第一隐层)的偏倚矩阵。
#初始化权重
weight01 = 2*np.random.random((3,4)) - 1
weight12 = 2*np.random.random((4,2)) - 1
weight23 = 2*np.random.random((2,1)) - 1#初始化偏倚
b1 = 2*np.random.random((1,4)) - 1
b2 = 2*np.random.random((1,2)) - 1
b3 = 2*np.random.random((1,1)) - 1
bias1=np.array([b1[0],b1[0],b1[0],b1[0]])
bias2=np.array([b2[0],b2[0],b2[0],b2[0]])
bias3=np.array([b3[0],b3[0],b3[0],b3[0]])
3.1.5开始训练
I0表示第0层输入,O0表示第0层输出。
for j in range(60000):I0 = XO0=I0I1=np.dot(O0,weight01)+bias1O1=sigmoid(I1)I2=np.dot(O1,weight12)+bias2O2=sigmoid(I2)I3=np.dot(O2,weight23)+bias3O3=sigmoid(I3)f3_error = y-O3 f3_delta = f3_error*sigmoid(O3,deriv = True)f2_error = f3_delta.dot(weight23.T)f2_delta = f2_error*sigmoid(O2,deriv = True)f1_error = f2_delta.dot(weight12.T) f1_delta = f1_error*sigmoid(O1,deriv = True)weight23 += O2.T.dot(f3_delta) #调整权重weight12 += O1.T.dot(f2_delta)weight01 += O0.T.dot(f1_delta)bias3 += f3_delta #调整偏倚bias2 += f2_deltabias1 += f1_delta
3.2完整代码
import numpy as np#定义sigmoid函数
def sigmoid(x, deriv = False):if(deriv == True):return x*(1-x)else:return 1/(1+np.exp(-x))#input dataset
X = np.array([[0,0,1],[0,1,1],[1,0,1],[1,1,1]])#output dataset
y = np.array([[0,1,1,0]]).T#初始化权重
weight01 = 2*np.random.random((3,4)) - 1
weight12 = 2*np.random.random((4,2)) - 1
weight23 = 2*np.random.random((2,1)) - 1#初始化偏倚
b1 = 2*np.random.random((1,4)) - 1
b2 = 2*np.random.random((1,2)) - 1
b3 = 2*np.random.random((1,1)) - 1
bias1=np.array([b1[0],b1[0],b1[0],b1[0]])
bias2=np.array([b2[0],b2[0],b2[0],b2[0]])
bias3=np.array([b3[0],b3[0],b3[0],b3[0]])#开始训练
for j in range(60000):I0 = XO0=I0I1=np.dot(O0,weight01)+bias1O1=sigmoid(I1)I2=np.dot(O1,weight12)+bias2O2=sigmoid(I2)I3=np.dot(O2,weight23)+bias3O3=sigmoid(I3)f3_error = y-O3 if(j%10000) == 0:print ("Error:"+str(np.mean(f3_error)))f3_delta = f3_error*sigmoid(O3,deriv = True)f2_error = f3_delta.dot(weight23.T)f2_delta = f2_error*sigmoid(O2,deriv = True)f1_error = f2_delta.dot(weight12.T) f1_delta = f1_error*sigmoid(O1,deriv = True)weight23 += O2.T.dot(f3_delta) #调整权重weight12 += O1.T.dot(f2_delta)weight01 += O0.T.dot(f1_delta)bias3 += f3_delta #调整偏倚bias2 += f2_deltabias1 += f1_deltaprint ("outout after Training:")
print (O3)
3.3预测结果
迭代次数为1000时,预测结果为:
迭代次数为5000时,预测结果为:
迭代次数为10000时,预测结果为:
迭代次数为60000时,预测结果为:
可见,已经十分逼近预期结果。
BP神经网络算法学习及代码实现(含Python源码)相关推荐
- 【语音识别】基于BP神经网络0到10数字语音识别含Matlab源码
1 简介 语音识别技术具有重要的理论价值和广阔的应用前景,近年来受到了人们的广泛重视.随着电子计算机的不断应用与发展以及人工智能的不断进步与完善,人们越来越希望让机器能够理解人类的自然语言,这种需求使 ...
- 【故障诊断分析】基于matlab BP神经网络三相逆变器故障诊断研究【含Matlab源码 1736期】
一.BP神经网络三相逆变器故障诊断简介 针对三相桥式逆变电路为研究对象,建立了仿真模型,并对逆变器主电路开关器件的开路故障进行仿 真,提出了基于BP神经网络的故障诊断方法,确定了网络的结构和参数,并以 ...
- 【故障检测问题】基于matlab免疫算法求解故障检测问题【含Matlab源码 196期】
一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[故障检测问题]基于matlab免疫算法求解故障检测问题[含Matlab源码 196期] 获取代码方式2: 通过订阅紫极神光博客付费专栏,凭 ...
- 【优化算法】灰狼优化算法(GWO)【含Matlab源码 1305期】
一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[优化算法]灰狼优化算法(GWO)[含Matlab源码 1305期] 点击上面蓝色字体,直接付费下载,即可. 获取代码方式2: 付费专栏优化 ...
- 【优化算法】改进的灰狼优化算法(IGWO)【含Matlab源码 1349期】
一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[优化算法]改进的灰狼优化算法(IGWO)[含Matlab源码 1349期] 点击上面蓝色字体,直接付费下载,即可. 获取代码方式2: 付费 ...
- 【优化算法】多目标灰狼优化算法(MOGWO)【含Matlab源码 099期】
一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[优化算法]多目标灰狼优化算法(MOGWO)[含Matlab源码 099期] 点击上面蓝色字体,直接付费下载,即可. 获取代码方式2: 付费 ...
- 【优化算法】改进的侏儒猫鼬优化算法(IDMO)【含Matlab源码 2314期】
⛄一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[优化算法]改进的侏儒猫鼬优化算法(IDMO)[含Matlab源码 2314期] 点击上面蓝色字体,直接付费下载,即可. 获取代码方式2: ...
- 【优化算法】象群游牧优化算法(EHO)【含Matlab源码 1080期】
⛄一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[优化算法]象群游牧优化算法(EHO)[含Matlab源码 1080期] 点击上面蓝色字体,直接付费下载,即可. 获取代码方式2: 付费专 ...
- 【图像增强】基于matlab萤火虫算法图像对比度增强【含Matlab源码 2142期】
⛄一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[图像增强]基于matlab萤火虫算法图像对比度增强[含Matlab源码 2142期] 点击上面蓝色字体,直接付费下载,即可. 获取代码方 ...
- 【RRT三维路径规划】基于matlab RRT_Star算法三维路径规划【含Matlab源码 1571期】
一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[三维路径规划]基于matlab RRT_Star算法三维路径规划[含Matlab源码 1571期] 点击上面蓝色字体,直接付费下载,即可. ...
最新文章
- Spark Shuffle原理解析
- 到底一台服务器能够支持多少TCP并发连接?
- 改进同步等待的网络服务端应用 (转)
- asp.net 2.0 主题中多CSS文件引用
- python生成html报表_python生成HTMl报告(unittest)
- Spark SQL(八)之基于物品的相似度公式
- 【jQuery笔记Part1】05-jQuery解决冲突
- 【sed 工具的使用】
- MySQL-第十一篇JDBC典型用法
- 匈牙利算法求最大匹配(HDU-4185 Oil Skimming)
- 别出心裁的Linux命令学习法
- YV12 and NV12
- 肖风:分布式网络是区块链机制设计的第一个层次
- Gmail邮件客户端pop3和smtp服务器配置
- dw2017不显示动画_10个创建2017年动画视频的最佳工具
- delphi异步与javascript
- 第031讲:永久存储,腌制一缸美味的泡菜 | 学习记录(小甲鱼零基础入门学习Python)
- 大二物竞金牌转北大计算机,靠竞赛进入清北的学生,都能选哪些专业?| 2019竞赛优惠专业分析...
- typora显示版本过期,请下载最新版本,可是最新版本84块钱,咋办?
- 译:WebRTC视频通信
热门文章
- 误ghost后手工修改分区表来恢复数据
- latex插入表格:三线表格、普通表格
- android ndk官网下载地址,android ndk下载
- rank 开窗函数_开窗函数(分析函数)
- WEB安全 asp+access注入
- 23数据错误循环冗余检查/无法读取源文件或磁盘 解决
- Xshell5安装 即 使用过程
- ThinkPHP(TP框架)的归纳与总结(一)----基于TP开发手册
- Javashop 7.0 前后端代码更新发布方法
- 鲜花销售管理系统jsp全部代码_基于Java的鲜花销售管理系统设计与实现.zip