目录

  • 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]∇x​f(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]∇A​f(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}}(∇A​f(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]​=∑k​wkj[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]​=∑j​wkj[l+1]​aj[l]​+bk[l+1]​=∑j​wkj[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]​​=∑k​wkj[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]​=∑k​wjk[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]​∂L​bj[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]​∂L​wjk[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]​∂L​wjk[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源码)相关推荐

  1. 【语音识别】基于BP神经网络0到10数字语音识别含Matlab源码

    1 简介 语音识别技术具有重要的理论价值和广阔的应用前景,近年来受到了人们的广泛重视.随着电子计算机的不断应用与发展以及人工智能的不断进步与完善,人们越来越希望让机器能够理解人类的自然语言,这种需求使 ...

  2. 【故障诊断分析】基于matlab BP神经网络三相逆变器故障诊断研究【含Matlab源码 1736期】

    一.BP神经网络三相逆变器故障诊断简介 针对三相桥式逆变电路为研究对象,建立了仿真模型,并对逆变器主电路开关器件的开路故障进行仿 真,提出了基于BP神经网络的故障诊断方法,确定了网络的结构和参数,并以 ...

  3. 【故障检测问题】基于matlab免疫算法求解故障检测问题【含Matlab源码 196期】

    一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[故障检测问题]基于matlab免疫算法求解故障检测问题[含Matlab源码 196期] 获取代码方式2: 通过订阅紫极神光博客付费专栏,凭 ...

  4. 【优化算法】灰狼优化算法(GWO)【含Matlab源码 1305期】

    一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[优化算法]灰狼优化算法(GWO)[含Matlab源码 1305期] 点击上面蓝色字体,直接付费下载,即可. 获取代码方式2: 付费专栏优化 ...

  5. 【优化算法】改进的灰狼优化算法(IGWO)【含Matlab源码 1349期】

    一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[优化算法]改进的灰狼优化算法(IGWO)[含Matlab源码 1349期] 点击上面蓝色字体,直接付费下载,即可. 获取代码方式2: 付费 ...

  6. 【优化算法】多目标灰狼优化算法(MOGWO)【含Matlab源码 099期】

    一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[优化算法]多目标灰狼优化算法(MOGWO)[含Matlab源码 099期] 点击上面蓝色字体,直接付费下载,即可. 获取代码方式2: 付费 ...

  7. 【优化算法】改进的侏儒猫鼬优化算法(IDMO)【含Matlab源码 2314期】

    ⛄一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[优化算法]改进的侏儒猫鼬优化算法(IDMO)[含Matlab源码 2314期] 点击上面蓝色字体,直接付费下载,即可. 获取代码方式2: ...

  8. 【优化算法】象群游牧优化算法(EHO)【含Matlab源码 1080期】

    ⛄一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[优化算法]象群游牧优化算法(EHO)[含Matlab源码 1080期] 点击上面蓝色字体,直接付费下载,即可. 获取代码方式2: 付费专 ...

  9. 【图像增强】基于matlab萤火虫算法图像对比度增强【含Matlab源码 2142期】

    ⛄一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[图像增强]基于matlab萤火虫算法图像对比度增强[含Matlab源码 2142期] 点击上面蓝色字体,直接付费下载,即可. 获取代码方 ...

  10. 【RRT三维路径规划】基于matlab RRT_Star算法三维路径规划【含Matlab源码 1571期】

    一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[三维路径规划]基于matlab RRT_Star算法三维路径规划[含Matlab源码 1571期] 点击上面蓝色字体,直接付费下载,即可. ...

最新文章

  1. Spark Shuffle原理解析
  2. 到底一台服务器能够支持多少TCP并发连接?
  3. 改进同步等待的网络服务端应用 (转)
  4. asp.net 2.0 主题中多CSS文件引用
  5. python生成html报表_python生成HTMl报告(unittest)
  6. Spark SQL(八)之基于物品的相似度公式
  7. 【jQuery笔记Part1】05-jQuery解决冲突
  8. 【sed 工具的使用】
  9. MySQL-第十一篇JDBC典型用法
  10. 匈牙利算法求最大匹配(HDU-4185 Oil Skimming)
  11. 别出心裁的Linux命令学习法
  12. YV12 and NV12
  13. 肖风:分布式网络是区块链机制设计的第一个层次
  14. Gmail邮件客户端pop3和smtp服务器配置
  15. dw2017不显示动画_10个创建2017年动画视频的最佳工具
  16. delphi异步与javascript
  17. 第031讲:永久存储,腌制一缸美味的泡菜 | 学习记录(小甲鱼零基础入门学习Python)
  18. 大二物竞金牌转北大计算机,靠竞赛进入清北的学生,都能选哪些专业?| 2019竞赛优惠专业分析...
  19. typora显示版本过期,请下载最新版本,可是最新版本84块钱,咋办?
  20. 译:WebRTC视频通信

热门文章

  1. 误ghost后手工修改分区表来恢复数据
  2. latex插入表格:三线表格、普通表格
  3. android ndk官网下载地址,android ndk下载
  4. rank 开窗函数_开窗函数(分析函数)
  5. WEB安全 asp+access注入
  6. 23数据错误循环冗余检查/无法读取源文件或磁盘 解决
  7. Xshell5安装 即 使用过程
  8. ThinkPHP(TP框架)的归纳与总结(一)----基于TP开发手册
  9. Javashop 7.0 前后端代码更新发布方法
  10. 鲜花销售管理系统jsp全部代码_基于Java的鲜花销售管理系统设计与实现.zip