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

news2025/2/2 0:41:16

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

误差反向传播学习算法

用神经网络来完成机器学习任务,先要设计好网络结构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)

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/104255.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

智能驾驶进入新周期:从「定点量产」到「做大做强」

智能驾驶赛道已经进入一个全新的周期。 过去三年时间,中国本土供应商陆续进入乘用车前装量产赛道,部分企业实现了从0到1的量产突围,而一些领跑的本土供应商已率先进入规模化上车的新阶段。 从最初的技术突破、产品落地,到定点量…

干货 | IC模拟版图设计学习笔记,一文教你快速入门

模拟版图设计处于IC设计流程的后端,属于模拟IC设计岗位的一种。随着我国半导体行业的发展,IC模拟版图岗位的人才需求也越来越大。而每个芯片最终能够付诸于生产都离不开集成电路版图设计师的功劳,所以IC模拟版图工程师在芯片产业的发展过程中…

Nginx-反向代理

什么是反向代理 用户直接访问反向代理服务器就可以获得目标服务器的资源。这一过程叫反向代理 如何配置反向代理 修改nginx配置文件 1.切换到nginx的conf路径下操作nginx的配置文件 cd /usr/local/openresty/nginx/conf 1.1防止修改错误可以先备份一下配置文件 cp nginx.…

IO流2.0 缓冲流 序列化 字符打印 printf格式 压缩流

04 缓冲流Buffered 4.1字节缓冲流 4.2 字符缓冲流 newLine();在底层自动识别操作系统类别和换行符 其实就是输出换行符; 4.2.1 BufferedReader(字符为单位 尽量用于文本文件) 不要去操作 二进制文件[声音,视频 ], 可能造成文件损坏 throw…

三个月转行SLAM,他的心路历程

SLAM入门心路历程 来源:知乎作者—莫慢待 读了三年985的计算机硕士,做了很多项目,发现自己是一个菜鸡。c/object-c/python/java/matlab甚至还写过R,也就是项目需要什么写什么。自学能力算是很不错了,第一次创业自己写…

juc-2-锁应用/线程通信

目录 1 线程安全(库存超卖) 2 锁用法 2.1 同步方法 2.2.同步代码块 2.3 synchronized 作用于静态方法 总结 案例 静态成员变量 (synchronized锁非静态方法) 2.4ReentrantLock类是可重入、互斥、实现了Lock接口的锁 3 死锁产生与排查 4 线程间的(等待与通知…

Hadoop实训任务3:HDFS和MapReduce综合操作

目录 1、启动Hadoop服务 2、创建文本文件 3、上传文本文件 4、显示文件内容 5、完成排序任务 6、计算最大利润和平均利润 7、统计学生总成绩和平均成绩 8、总结 1、启动Hadoop服务 在master虚拟机上执行命令: start-all.sh 启动hadoop服务进程 ​ ​ ​…

【嵌入式】构建嵌入式Linux系统(uboot、内核、文件系统)

知识架构及层次 Linux内核由三部分构成: Bootloader:启动引导系统(可执行文件)Kernel:内核(可执行文件)Root File System:根文件系统嵌入式Linux系统构成及启动略析 嵌入式 Linux …

Java八股文,YYDS!字节最新秋招面试题,“死记”这些你也可以斩获字节offer

Java 一面基本上都是基础题,同样是 CURD 的活,谁更熟练要谁,比如下面这些面试题,八股文越熟练越容易通过 Java 面试。 下面会给大家详解的介绍一下每个技术点的必问问题! 一、Java 基础 1.JDK动态代理和CGLIB动态代…

C++图像的形态学操作

什么是图像的形态学操作? 使用数学形态学的基本运算,由计算机对图像进行分析,以达到所需结果的一种技术。 形态学,morphology, 形态学最初是生物学中研究动物和植物结构的一个分支,被引入图像处理领域后,图…

C语言 期末合集 pta

6-1 求最大的偶数和最小的奇数的差 分数 10 全屏浏览题目 切换布局 作者 王跃萍 单位 东北石油大学 求10个数中的最大的偶数和最小的奇数的差。 函数接口定义: int fun(int a[],int n); 函数fun中a、n是用户传入的参数,函数fun的功能是求a数组中的…

【LVGL学习笔记】(五)使用SquareLine Studio设计UI

LVGL全程LittleVGL,是一个轻量化的,开源的,用于嵌入式GUI设计的图形库。并且配合LVGL模拟器,可以在电脑对界面进行编辑显示,测试通过后再移植进嵌入式设备中,实现高效的项目开发。 LVGL中文教程手册&#…

点云地图构建及定位

点云地图构建及定位1. 回环检测1.1 基于Scan Context1.2 基于直方图2. 后端优化2.1 后端优化基本原理2.2 李群、李代数基本知识2.3 李群、李代数基本知识2.3.1 SO(3)\mathrm{SO}(3)SO(3) 对应的 BCH\mathrm{BCH}BCH 公式2.3.2 SE(3)\mathrm{SE}(3)SE(3) 对应的 BCH\mathrm{BCH}…

链式存储之:链表的引出及其简介

上篇博客,笔者讲解了一下顺序表ArrayList,对于ArrayList有想法的各位老铁可以看一下:值得思索的:ArrayList和线性表,你确定错过这次机会_念君思宁的博客-CSDN博客值得思索的:ArrayList和线性表,…

Html5 canvas创意特效合集

Canvas就像一块画布,我们可以通过调用脚本在Canvas上绘制任意形状,甚至是制作动画。本文就是收集了很多非常富有创意的一些canvas动画特效例子,这些例子都非常适合大家学习。 1.3D篝火动画特效 这款篝火特效是基于 three.js 和 canvas 制作的…

博实结将在创业板上会:计划募资25亿元,周小强为实际控制人

近日,深圳市博实结科技股份有限公司(下称“博实结”)在深圳证券交易所递交招股书(上会稿),准备在创业板上市。据贝多财经了解,博实结将于2022年12月23日接受创业板上市委审议,一同上…

Vue3----props和emit的使用

作用:父组件通过 props 向下传递数据给子组件; 用途:当有一种类型的组件需要被使用多次,每一次的调用都只是特定的地方不同,就好像一张个人简介表,每次填的人的信息都不同,但是结构都是一样的。…

Nacos学习笔记 (2)Nacos基础核心特性

内容: Nacos架构及其核心特性,包括服务注册、服务发现、发布与获取配置特性,以及Nacos Spring关键特性。 本文内容,参考 Nacos 官网与 《Nacos架构&原理》一书。 1. Nacos 架构 详情推荐参考: (1&a…

服务器取证——服务器基础知识

目录 一、服务器基本介绍 (一)概念 (二)构成 (三) 种类 (四)与pc区别 二、 磁盘阵列RAID (一)概念 (二)产生原因 &#xff0…

【Django】第二课 银行账户管理系统开发

概念 本文在上一篇文章基础之前进行构建和完善 账户信息的分页显示 用户通过点击首页的“查询账户”,进入账户信息查询页面 则点击该按钮触发点击事件,向django服务器发出请求 接着我们在urls.py中需要定义与该地址进行匹配的地址,并匹配后…