【Python机器学习】神经网络中误差反向传播(BP)算法详解及代码示例(图文解释 附源码)

简介: 【Python机器学习】神经网络中误差反向传播(BP)算法详解及代码示例(图文解释 附源码)

需要全部代码请点赞关注收藏后评论留言私信~~~

误差反向传播学习算法

用神经网络来完成机器学习任务,先要设计好网络结构S,然后用训练样本去学习网络中的连接系数和阈值系数,即网络参数S,最后才能用来对测试样本进行预测。

在研究早期,没有适合多层神经网络的有效的参数学习方法是长期困扰该领域研究者的关键问题,以致于人们对人工神经网络的前途产生了怀疑,导致该领域的研究进入了低谷期。直到1986年,以Rumelhart和McCelland为首的小组发表了误差反向传播(Error Back Propagation,BP)算法,该问题才得以解决,多层神经网络从此得到快速发展。

采用BP算法来学习的、无反馈的、同层节点无连接的、多层结构的前馈神经网络称为BP神经网络。

逻辑代数中的异或运算时非线性的,它不能由单个神经元来模拟,下面用模拟异或运算的神经网络为例来说明BP学习过程

样本:

网络结构:      

要学习的参数:

BP学习算法可分为前向传播预测与反向传播学习两个过程。

为了方便求导,隐层和输出层的激励函数采用Sigmoid函数:

Sigmoid函数的导数为:

前向传播预测过程

设网络各参数初值为:

取第一个训练样本(0,0),第1隐层的输出:

用l^(1)和l^(2)表示标签值,采用各标签值的均方误差MSE作为总误差,并将总误差依次展开至输入层:

可见,总误差E是各层参数变量的函数,因此学习的目的就是通过调整各参数变量的值,使E最小。可采用梯度下降法求解。

第一个训练样本的标签值为(0,1),因此,输出产生的误差分别为0.743和−0.236。总误差:E=1/2∑_i=1^2▒(z^(i)−l^(i))^2=0.304 输出层节点的参数更新,以节点1的w_2^(1,1)和θ_2^(1)为例详细讨论。

先求偏导∂E/∂w_2^(1,1):∂E/∂w_2^(1,1)=∂E/∂y_2^(1)∙∂y_2^(1)/∂w_2^(1,1)=∂[1/2∑_i=1^2▒(y_2^(i)−l^(i))^2]/∂y_2^(1)∙∂y_2^(1)/∂w_2^(1,1)=(y_2^(1)−l^(1))∙∂y_2^(1)/∂w_2^(1,1)

式中括号(y_2^(1)−l^(1))是输出层节点1的校对误差,记为E_2^1,即E_2^1=y_2^(1)−l^(1)=0.743。因此∂E/∂w_2^(1,1)可视为该节点的校对误差乘以该节点输出对待更新参数变量的偏导:∂E/∂w_2^(1,1)=E_2^1∙∂y_2^(1)/∂w_2^(1,1)

后面求导过程过于繁杂 此处省略不表

以上给出了输入第一个训练样本后,网络的前向预测和反向学习过程。可将样本依次输入网络进行训练。一般要进行多轮训练。

运行输出结果如下

经过2000轮训练,每轮平均值总误差由0.32降维0.008

最后一轮的四个输出与相应标签值对比为下 预测输出十分接近实际标签值

部分代码如下

for j in range(2000):
    print("\n\n轮:", j)
    E = 0.0
    for i in range(4):
        print("样本:", i)
        print("实例:", XX[i])
        print("标签", L[i])
        ### 前向传播预测
        # 计算第1隐层的输出
        Y1[0] = y_1_1(W1, theta1, XX[i])
        Y1[1] = y_1_2(W1, theta1, XX[i])
        #print("第1隐层的输出:", Y1)
        # 计算第2隐层的输出
        Y2[0] = y_2_1(W2, theta2, Y1)
        Y2[1] = y_2_2(W2, theta2, Y1)
        print("第2隐层的输出:", Y2)
        ### 后向传播误差
        # 计算第2隐层的校对误差
        E2[0] = Y2[0] - L[i][0]
        E2[1] = Y2[1] - L[i][1]
        E += 0.5*(E2[0]*E2[0]+E2[1]*E2[1])
        #print("总误差", E)
        #print("第2隐层的校对误差", E2)
        # 计算第1隐层的校对误差
        E1[0] = E2[0]*Y2[0]*(1 - Y2[0])*W2[0,0] + E2[1]*Y2[1]*(1 - Y2[1])*W2[0,1]
        E1[1] = E2[0]*Y2[0]*(1 - Y2[0])*W2[1,0] + E2[1]*Y2[1]*(1 - Y2[1])*W2[1,1]
        #print("第1隐层的校对误差", E1)
        ### 更新系数
        # 更新第2隐层的系数
        W2[0,0] = W2[0,0] - a*E2[0]*Y2[0]*(1 - Y2[0])*Y1[0]
        W2[1,0] = W2[1,0] - a*E2[0]*Y2[0]*(1 - Y2[0])*Y1[1]
        theta2[0] = theta2[0] - a*E2[0]*Y2[0]*(1 - Y2[0])
        W2[0,1] = W2[0,1] - a*E2[1]*Y2[1]*(1 - Y2[1])*Y1[0]
        W2[1,1] = W2[1,1] - a*E2[1]*Y2[1]*(1 - Y2[1])*Y1[1]
        theta2[1] = theta2[1] - a*E2[1]*Y2[1]*(1 - Y2[1])
        #print("第2隐层的连接系数", W2)
        #print("第2隐层的阈值系数", theta2)
        # 更新第1隐层的系数
        W1[0,0] = W1[0,0] - a*E1[0]*Y1[0]*(1 - Y1[0])*XX[i][0]
        W1[1,0] = W1[1,0] - a*E1[0]*Y1[0]*(1 - Y1[0])*XX[i][1]
        theta1[0] = theta1[0] - a*E1[0]*Y1[0]*(1 - Y1[0])
        W1[0,1] = W1[0,1] - a*E1[1]*Y1[1]*(1 - Y1[1])*XX[i][0]
        W1[1,1] = W1[1,1] - a*E1[1]*Y1[1]*(1 - Y1[1])*XX[i][1]
        theta1[1] = theta1[1] - a*E1[1]*Y1[1]*(1 - Y1[1])
        #print("第1隐层的连接系数", W1)
        #print("第1隐层的阈值系数", theta1)
    print("平均总误差" + str(E/4.0))

下面用深度学习框架Tensorflow来模拟异或运算

训练过程如下

当采用(2,2,2)全连接层神经网络时,训练2000轮时,误差约为0.19,四个标签对应的输出为:

[0.43767142,0.56202793]→[0.,1.],

[0.5493321,0.45261452]→[1.,0.],

[0.575727,0.42299467]→[1.,0.],

[0.43716326,0.5625658 ]→[ 0.,1.]。

如果增加隐层的数量,将有效提高模拟效果,将隐层节点数量增加到4个,误差降到约0.16。

部分代码如下

import tensorflow as tf
import numpy as np
# 样本实例
XX = np.array([[0.0,0.0],
              [0.0,1.0],
              [1.0,0.0],
              [1.0,1.0]])
# 样本标签
L = np.array([[0.0,1.0],
              [1.0,0.0],
              [1.0,0.0],
              [0.0,1.0]])
tf_model = tf.keras.Sequential([
    tf.keras.layers.Dense(2, activation='sigmoid', input_shape=(2,), kernel_initializer='random_uniform', bias_initializer='zeros'),
    tf.keras.layers.Dense(2, activation='sigmoid', kernel_initializer='random_uniform', bias_initializer='zeros')
])
tf_model.compile(optimiaer=tf.keras.optimizers.SGD(), loss=tf.keras.losses.mean_squared_error, metrics=['accuracy'])
tf_model.summary()
tf_model.fit(XX, L, batch_size=4, epochs=2000, verbose=1)
tf_model.evaluate(XX, L)

创作不易 觉得有帮助请点赞关注收藏~~~

相关文章
|
23天前
|
存储 缓存 Java
Python高性能编程:五种核心优化技术的原理与Python代码
Python在高性能应用场景中常因执行速度不及C、C++等编译型语言而受质疑,但通过合理利用标准库的优化特性,如`__slots__`机制、列表推导式、`@lru_cache`装饰器和生成器等,可以显著提升代码效率。本文详细介绍了这些实用的性能优化技术,帮助开发者在不牺牲代码质量的前提下提高程序性能。实验数据表明,这些优化方法能在内存使用和计算效率方面带来显著改进,适用于大规模数据处理、递归计算等场景。
58 5
Python高性能编程:五种核心优化技术的原理与Python代码
|
2月前
|
Python
课程设计项目之基于Python实现围棋游戏代码
游戏进去默认为九路玩法,当然也可以选择十三路或是十九路玩法 使用pycharam打开项目,pip安装模块并引用,然后运行即可, 代码每行都有详细的注释,可以做课程设计或者毕业设计项目参考
78 33
|
2月前
|
机器学习/深度学习 算法
基于遗传优化的双BP神经网络金融序列预测算法matlab仿真
本项目基于遗传优化的双BP神经网络实现金融序列预测,使用MATLAB2022A进行仿真。算法通过两个初始学习率不同的BP神经网络(e1, e2)协同工作,结合遗传算法优化,提高预测精度。实验展示了三个算法的误差对比结果,验证了该方法的有效性。
|
2月前
|
JavaScript API C#
【Azure Developer】Python代码调用Graph API将外部用户添加到组,结果无效,也无错误信息
根据Graph API文档,在单个请求中将多个成员添加到组时,Python代码示例中的`members@odata.bind`被错误写为`members@odata_bind`,导致用户未成功添加。
52 10
|
2月前
|
机器学习/深度学习 算法
基于改进遗传优化的BP神经网络金融序列预测算法matlab仿真
本项目基于改进遗传优化的BP神经网络进行金融序列预测,使用MATLAB2022A实现。通过对比BP神经网络、遗传优化BP神经网络及改进遗传优化BP神经网络,展示了三者的误差和预测曲线差异。核心程序结合遗传算法(GA)与BP神经网络,利用GA优化BP网络的初始权重和阈值,提高预测精度。GA通过选择、交叉、变异操作迭代优化,防止局部收敛,增强模型对金融市场复杂性和不确定性的适应能力。
208 80
|
2月前
|
数据可视化 Python
以下是一些常用的图表类型及其Python代码示例,使用Matplotlib和Seaborn库。
通过这些思维导图和分析说明表,您可以更直观地理解和选择适合的数据可视化图表类型,帮助更有效地展示和分析数据。
105 8
|
2月前
|
Python
探索Python中的装饰器:简化代码,增强功能
在Python的世界里,装饰器就像是给函数穿上了一件神奇的外套,让它们拥有了超能力。本文将通过浅显易懂的语言和生动的比喻,带你了解装饰器的基本概念、使用方法以及它们如何让你的代码变得更加简洁高效。让我们一起揭开装饰器的神秘面纱,看看它是如何在不改变函数核心逻辑的情况下,为函数增添新功能的吧!
|
2月前
|
程序员 测试技术 数据安全/隐私保护
深入理解Python装饰器:提升代码重用与可读性
本文旨在为中高级Python开发者提供一份关于装饰器的深度解析。通过探讨装饰器的基本原理、类型以及在实际项目中的应用案例,帮助读者更好地理解并运用这一强大的语言特性。不同于常规摘要,本文将以一个实际的软件开发场景引入,逐步揭示装饰器如何优化代码结构,提高开发效率和代码质量。
74 6
|
2月前
|
开发框架 数据建模 中间件
Python中的装饰器:简化代码,增强功能
在Python的世界里,装饰器是那些静悄悄的幕后英雄。它们不张扬,却能默默地为函数或类增添强大的功能。本文将带你了解装饰器的魅力所在,从基础概念到实际应用,我们一步步揭开装饰器的神秘面纱。准备好了吗?让我们开始这段简洁而富有启发性的旅程吧!
56 6
|
2月前
|
API Python
【Azure Developer】分享一段Python代码调用Graph API创建用户的示例
分享一段Python代码调用Graph API创建用户的示例
68 11

推荐镜像

更多