【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)

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

相关文章
|
3月前
|
机器学习/深度学习 算法 数据挖掘
K-means聚类算法是机器学习中常用的一种聚类方法,通过将数据集划分为K个簇来简化数据结构
K-means聚类算法是机器学习中常用的一种聚类方法,通过将数据集划分为K个簇来简化数据结构。本文介绍了K-means算法的基本原理,包括初始化、数据点分配与簇中心更新等步骤,以及如何在Python中实现该算法,最后讨论了其优缺点及应用场景。
193 6
|
4天前
|
机器学习/深度学习 存储 算法
近端策略优化(PPO)算法的理论基础与PyTorch代码详解
近端策略优化(PPO)是深度强化学习中高效的策略优化方法,广泛应用于大语言模型的RLHF训练。PPO通过引入策略更新约束机制,平衡了更新幅度,提升了训练稳定性。其核心思想是在优势演员-评论家方法的基础上,采用裁剪和非裁剪项组成的替代目标函数,限制策略比率在[1-ϵ, 1+ϵ]区间内,防止过大的策略更新。本文详细探讨了PPO的基本原理、损失函数设计及PyTorch实现流程,提供了完整的代码示例。
106 10
近端策略优化(PPO)算法的理论基础与PyTorch代码详解
|
1月前
|
机器学习/深度学习 人工智能 算法
机器学习算法的优化与改进:提升模型性能的策略与方法
机器学习算法的优化与改进:提升模型性能的策略与方法
266 13
机器学习算法的优化与改进:提升模型性能的策略与方法
|
1月前
|
机器学习/深度学习 算法 网络安全
CCS 2024:如何严格衡量机器学习算法的隐私泄露? ETH有了新发现
在2024年CCS会议上,苏黎世联邦理工学院的研究人员提出,当前对机器学习隐私保护措施的评估可能存在严重误导。研究通过LiRA攻击评估了五种经验性隐私保护措施(HAMP、RelaxLoss、SELENA、DFKD和SSL),发现现有方法忽视最脆弱数据点、使用较弱攻击且未与实际差分隐私基线比较。结果表明这些措施在更强攻击下表现不佳,而强大的差分隐私基线则提供了更好的隐私-效用权衡。
52 14
|
2月前
|
存储 算法 程序员
C 语言递归算法:以简洁代码驾驭复杂逻辑
C语言递归算法简介:通过简洁的代码实现复杂的逻辑处理,递归函数自我调用解决分层问题,高效而优雅。适用于树形结构遍历、数学计算等领域。
|
3月前
|
机器学习/深度学习 算法 数据挖掘
C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出
本文探讨了C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出。文章还介绍了C语言在知名机器学习库中的作用,以及与Python等语言结合使用的案例,展望了其未来发展的挑战与机遇。
77 1
|
3月前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
99 1
|
3月前
|
存储 缓存 算法
通过优化算法和代码结构来提升易语言程序的执行效率
通过优化算法和代码结构来提升易语言程序的执行效率
|
3月前
|
机器学习/深度学习 自然语言处理 算法
深入理解机器学习算法:从线性回归到神经网络
深入理解机器学习算法:从线性回归到神经网络
|
3月前
|
机器学习/深度学习 数据可视化 数据处理
掌握Python数据科学基础——从数据处理到机器学习
掌握Python数据科学基础——从数据处理到机器学习
69 0