机器学习 BP神经网络(Python实现)

2023-11-09

一个神经元即一个感知机模型,由多个神经元相互连接形成的网络,即神经网络。

这里我们只讨论单隐层前馈神经网络,其连接形式入下:
在这里插入图片描述
神经网络模型的待估参数即,每个神经元的阈值,以及神经元之间的连接权重。

对于该模型有如下定义:

训练集:D={(x1, y1), (x2, y2), …, (xm, ym)},x具有d个属性值,y具有k个可能取值

则我们的神经网络(单隐层前馈神经网络)应该是具有d个输入神经元,q个隐层神经元,k个输出层神经元的神经网络 ,我们默认输入层只是数据的输入,不对数据做处理,即输入层没有阈值。

阈值函数使用对数几率函数:
在这里插入图片描述
有如下定义:

输出层第j个神经元的阈值为:θj

隐层第h个神经元的阈值为:γh(γ是Gamma)

输入层第i个神经元与隐层第h个神经元的连接权重为:vih

隐层第h个神经元与输出层第j个神经元的连接权重为:ωhj

由上述定义我们可以得到:

隐层第h个神经元接收到输入:
在这里插入图片描述
隐层第h个神经元的输出:
在这里插入图片描述
输出层第j个神经元接收到的输入:
在这里插入图片描述
现在我们定义好了所有的参数,接下来我们要求这些模型。

对参数进行估计,需要有优化方向,我们继续使用欧式距离,或者均方误差来作为优化目标:

我们使用梯度下降的策略对参数进行迭代优化,所以任意一个参数的变化大小为(θ代表任意参数):
在这里插入图片描述
下面根据这个更新公式,我们来求各个参数的更新公式:

对数几率函数的导数如下:
在这里插入图片描述
输出层第j个神经元的阈值θj:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
隐层第h个神经元的阈值γh:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
输入层第i个神经元与隐层第h个神经元的连接权重vih :

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
隐层第h个神经元与输出层第j个神经元的连接权重ωhj:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
现在四个参数的更新规则都计算出来了,我们可以开始编码实现了。

现在有一个问题:在二分类任务中,输出层神经元有几个?

                         一个:如果只有1个,那么输出0表示反例,1表示正例

                         二个:那么输出(1,0)表示反例,(0,1)表示正例

一下实例我们使用第一种:

我们使用一个二分类数据集:马疝病数据集
horseColicTest.txt,提取码:xq88。
horseColicTraining.txt,提取码:6nmh。
数据读取:

def loaddataset(filename):
	fp = open(filename)
 
	#存放数据
	dataset = []
 
	#存放标签
	labelset = []
	for i in fp.readlines():
		a = i.strip().split()
 
		#每个数据行的最后一个是标签
		dataset.append([float(j) for j in a[:len(a)-1]])
		labelset.append(int(float(a[-1])))
	return dataset, labelset

初始化各个参数:

#x为输入层神经元个数,y为隐层神经元个数,z输出层神经元个数
def parameter_initialization(x, y, z):
 
	#隐层阈值
	value1 = np.random.randint(-5, 5, (1, y)).astype(np.float64)
 
	#输出层阈值
	value2 = np.random.randint(-5, 5, (1, z)).astype(np.float64)
 
	#输入层与隐层的连接权重
	weight1 = np.random.randint(-5, 5, (x, y)).astype(np.float64)
 
	#隐层与输出层的连接权重
	weight2 = np.random.randint(-5, 5, (y, z)).astype(np.float64)
 
	return weight1, weight2, value1, value2

初始化的各参数数值不能一样,否则无法进行学习。

对数几率函数(sigmoid函数):

def sigmoid(z):
	return 1 / (1 + np.exp(-z))
 

训练过程(参数调整过程):

'''
weight1:输入层与隐层的连接权重
weight2:隐层与输出层的连接权重
value1:隐层阈值
value2:输出层阈值
'''
def trainning(dataset, labelset, weight1, weight2, value1, value2):
	#x为步长
	x = 0.01
	for i in range(len(dataset)):
		#输入数据
		inputset = np.mat(dataset[i]).astype(np.float64)
		#数据标签
		outputset = np.mat(labelset[i]).astype(np.float64)
		#隐层输入
		input1 = np.dot(inputset, weight1).astype(np.float64)
		#隐层输出
		output2 = sigmoid(input1 - value1).astype(np.float64)
		#输出层输入
		input2 = np.dot(output2, weight2).astype(np.float64)
		#输出层输出
		output3 = sigmoid(input2 - value2).astype(np.float64)
 
		#更新公式由矩阵运算表示
		a = np.multiply(output3, 1 - output3)
		g = np.multiply(a, outputset - output3)
		b = np.dot(g, np.transpose(weight2))
		c = np.multiply(output2, 1 - output2)
		e = np.multiply(b, c)
 
		value1_change = -x * e
		value2_change = -x * g
		weight1_change = x * np.dot(np.transpose(inputset), e)
		weight2_change = x * np.dot(np.transpose(output2), g)
 
		#更新参数
		value1 += value1_change
		value2 += value2_change
		weight1 += weight1_change
		weight2 += weight2_change
	return weight1, weight2, value1, value2

测试:

def testing(dataset, labelset, weight1, weight2, value1, value2):
	#记录预测正确的个数
	rightcount = 0
	for i in range(len(dataset)):
		#计算每一个样例通过该神经网路后的预测值
		inputset = np.mat(dataset[i]).astype(np.float64)
		outputset = np.mat(labelset[i]).astype(np.float64)
		output2 = sigmoid(np.dot(inputset, weight1) - value1)
		output3 = sigmoid(np.dot(output2, weight2) - value2)
 
		#确定其预测标签
		if output3 > 0.5:
			flag = 1
		else:
			flag = 0
		if labelset[i] == flag:
			rightcount += 1
		#输出预测结果
		print("预测为%d   实际为%d"%(flag, labelset[i]))
	#返回正确率
	return rightcount / len(dataset)

主函数:

if __name__ == '__main__':
	dataset, labelset = loaddataset('基于神经网络的马疝病死亡预测/horseColicTraining.txt')
	weight1, weight2, value1, value2 = parameter_initialization(len(dataset[0]), len(dataset[0]), 1)
	for i in range(1500):
		weight1, weight2, value1, value2 = trainning(dataset, labelset, weight1, weight2, value1, value2)
	rate = testing(dataset, labelset, weight1, weight2, value1, value2)
	print("正确率为%f"%(rate))

结果:

正确率为0.769231
[Finished in 68.2s]

上述实例只是一个测试我们模型是否推导正确的实例,在数据集上的学习效果并不好,有许多的细节没有考虑。

完整代码如下:

import numpy as np
 
def loaddataset(filename):
	fp = open(filename)
 
	#存放数据
	dataset = []
 
	#存放标签
	labelset = []
	for i in fp.readlines():
		a = i.strip().split()
 
		#每个数据行的最后一个是标签
		dataset.append([float(j) for j in a[:len(a)-1]])
		labelset.append(int(float(a[-1])))
	return dataset, labelset
 
 
#x为输入层神经元个数,y为隐层神经元个数,z输出层神经元个数
def parameter_initialization(x, y, z):
 
	#隐层阈值
	value1 = np.random.randint(-5, 5, (1, y)).astype(np.float64)
 
	#输出层阈值
	value2 = np.random.randint(-5, 5, (1, z)).astype(np.float64)
 
	#输入层与隐层的连接权重
	weight1 = np.random.randint(-5, 5, (x, y)).astype(np.float64)
 
	#隐层与输出层的连接权重
	weight2 = np.random.randint(-5, 5, (y, z)).astype(np.float64)
 
	return weight1, weight2, value1, value2
 
def sigmoid(z):
	return 1 / (1 + np.exp(-z))
 
'''
weight1:输入层与隐层的连接权重
weight2:隐层与输出层的连接权重
value1:隐层阈值
value2:输出层阈值
'''
def trainning(dataset, labelset, weight1, weight2, value1, value2):
	#x为步长
	x = 0.01
	for i in range(len(dataset)):
		#输入数据
		inputset = np.mat(dataset[i]).astype(np.float64)
		#数据标签
		outputset = np.mat(labelset[i]).astype(np.float64)
		#隐层输入
		input1 = np.dot(inputset, weight1).astype(np.float64)
		#隐层输出
		output2 = sigmoid(input1 - value1).astype(np.float64)
		#输出层输入
		input2 = np.dot(output2, weight2).astype(np.float64)
		#输出层输出
		output3 = sigmoid(input2 - value2).astype(np.float64)
 
		#更新公式由矩阵运算表示
		a = np.multiply(output3, 1 - output3)
		g = np.multiply(a, outputset - output3)
		b = np.dot(g, np.transpose(weight2))
		c = np.multiply(output2, 1 - output2)
		e = np.multiply(b, c)
 
		value1_change = -x * e
		value2_change = -x * g
		weight1_change = x * np.dot(np.transpose(inputset), e)
		weight2_change = x * np.dot(np.transpose(output2), g)
 
		#更新参数
		value1 += value1_change
		value2 += value2_change
		weight1 += weight1_change
		weight2 += weight2_change
	return weight1, weight2, value1, value2
 
def testing(dataset, labelset, weight1, weight2, value1, value2):
	#记录预测正确的个数
	rightcount = 0
	for i in range(len(dataset)):
		#计算每一个样例通过该神经网路后的预测值
		inputset = np.mat(dataset[i]).astype(np.float64)
		outputset = np.mat(labelset[i]).astype(np.float64)
		output2 = sigmoid(np.dot(inputset, weight1) - value1)
		output3 = sigmoid(np.dot(output2, weight2) - value2)
 
		#确定其预测标签
		if output3 > 0.5:
			flag = 1
		else:
			flag = 0
		if labelset[i] == flag:
			rightcount += 1
		#输出预测结果
		print("预测为%d   实际为%d"%(flag, labelset[i]))
	#返回正确率
	return rightcount / len(dataset)
 
if __name__ == '__main__':
	dataset, labelset = loaddataset('基于神经网络的马疝病死亡预测/horseColicTraining.txt')
	weight1, weight2, value1, value2 = parameter_initialization(len(dataset[0]), len(dataset[0]), 1)
	for i in range(1500):
		weight1, weight2, value1, value2 = trainning(dataset, labelset, weight1, weight2, value1, value2)
	rate = testing(dataset, labelset, weight1, weight2, value1, value2)
	print("正确率为%f"%(rate))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

机器学习 BP神经网络(Python实现) 的相关文章

  • 没有名为 crypto.cipher 的模块

    我现在正在尝试加密一段时间 我最近得到了这个基于 python 的密码器 名为PythonCrypter https github com jbertman PythonCrypter 我对 Python 相当陌生 当我尝试通过终端打开 C
  • 在 python 程序中合并第三方库的最佳实践是什么?

    下午好 我正在为我的工作编写一个中小型Python程序 该任务需要我使用 Excel 库xlwt and xlrd 以及一个用于查询 Oracle 数据库的库 称为CX Oracle 我正在通过版本控制系统 即CVS 开发该项目 我想知道围
  • SQLAlchemy 通过关联对象声明式多对多自连接

    我有一个用户表和一个朋友表 它将用户映射到其他用户 因为每个用户可以有很多朋友 这个关系显然是对称的 如果用户A是用户B的朋友 那么用户B也是用户A的朋友 我只存储这个关系一次 除了两个用户 ID 之外 Friends 表还有其他字段 因此
  • 为 Anaconda Python 安装 psycopg2

    我有 Anaconda Python 3 4 但是每当我运行旧代码时 我都会通过输入 source activate python2 切换到 Anaconda Python 2 7 我的问题是我为 Anaconda Python 3 4 安
  • 使用 matplotlib 绘制时间序列数据并仅在年初显示年份

    rcParams date autoformatter month b n Y 我正在使用 matpltolib 来绘制时间序列 如果我按上述方式设置 rcParams 则生成的图会在每个刻度处标记月份名称和年份 我怎样才能将其设置为仅在每
  • 从字符串中删除识别的日期

    作为输入 我有几个包含不同格式日期的字符串 例如 彼得在16 45 我的生日是1990年7月8日 On 7 月 11 日星期六我会回家 I use dateutil parser parse识别字符串中的日期 在下一步中 我想从字符串中删除
  • 如何在 Python 中检索 for 循环中的剩余项目?

    我有一个简单的 for 循环迭代项目列表 在某些时候 我知道它会破裂 我该如何退回剩余的物品 for i in a b c d e f g try some func i except return remaining items if s
  • 使用 on_bad_lines 将 pandas.read_csv 中的无效行写入文件

    我有一个 CSV 文件 我正在使用 Python 来解析该文件 我发现文件中的某些行具有不同的列数 001 Snow Jon 19801201 002 Crom Jake 19920103 003 Wise Frank 19880303 l
  • 如何替换 pandas 数据框列中的重音符号

    我有一个数据框dataSwiss其中包含瑞士城市的信息 我想用普通字母替换带有重音符号的字母 这就是我正在做的 dataSwiss Municipality dataSwiss Municipality str encode utf 8 d
  • 如何从网页中嵌入的 Tableau 图表中抓取工具提示值

    我试图弄清楚是否有一种方法以及如何使用 python 从网页中的 Tableau 嵌入图形中抓取工具提示值 以下是当用户将鼠标悬停在条形上时带有工具提示的图表示例 我从要从中抓取的原始网页中获取了此网址 https covid19 colo
  • 以编程方式停止Python脚本的执行? [复制]

    这个问题在这里已经有答案了 是否可以使用命令在任意行停止执行 python 脚本 Like some code quit quit at this point some more code that s not executed sys e
  • 绘制方程

    我正在尝试创建一个函数 它将绘制我告诉它的任何公式 import numpy as np import matplotlib pyplot as plt def graph formula x range x np array x rang
  • BeautifulSoup 中的嵌套标签 - Python

    我在网站和 stackoverflow 上查看了许多示例 但找不到解决我的问题的通用解决方案 我正在处理一个非常混乱的网站 我想抓取一些数据 标记看起来像这样 table tbody tr tr tr td td td table tr t
  • 添加不同形状的 numpy 数组

    我想添加两个不同形状的 numpy 数组 但不进行广播 而是将 缺失 值视为零 可能最简单的例子是 1 2 3 2 gt 3 2 3 or 1 2 3 2 1 gt 3 2 3 1 0 0 我事先不知道形状 我正在弄乱每个 np shape
  • Pygame:有没有简单的方法可以找到按下的任何字母数字的字母/数字?

    我目前正在开发的游戏需要让人们以自己的名义在高分板上计时 我对如何处理按键有点熟悉 但我只处理过寻找特定的按键 有没有一种简单的方法可以按下任意键的字母 而不必执行以下操作 for event in pygame event get if
  • Pandas:merge_asof() 对多行求和/不重复

    我正在处理两个数据集 每个数据集具有不同的关联日期 我想合并它们 但因为日期不完全匹配 我相信merge asof 是最好的方法 然而 有两件事发生merge asof 不理想的 数字重复 数字丢失 以下代码是一个示例 df a pd Da
  • 为字典中的一个键附加多个值[重复]

    这个问题在这里已经有答案了 我是 python 新手 我有每年的年份和值列表 我想要做的是检查字典中是否已存在该年份 如果存在 则将该值附加到特定键的值列表中 例如 我有一个年份列表 并且每年都有一个值 2010 2 2009 4 1989
  • 类型错误:预期单个张量时的张量列表 - 将 const 与 tf.random_normal 一起使用时

    我有以下 TensorFlow 代码 tf constant tf random normal time step batch size 1 1 我正进入 状态TypeError List of Tensors when single Te
  • 导入错误:没有名为 site 的模块 - mac

    我已经有这个问题几个月了 每次我想获取一个新的 python 包并使用它时 我都会在终端中收到此错误 ImportError No module named site 我不知道为什么会出现这个错误 实际上 我无法使用任何新软件包 因为每次我
  • 如何将输入读取为数字?

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 Why are x and y下面的代码中使用字符串而不是整数 注意 在Python 2

随机推荐

  • 使用invoke方法解决跨线程访问的问题

    C 中禁止跨线程直接访问控件 InvokeRequired是为了解决这个问题而产生的 当一个控件的InvokeRequired属性值为真时 说明有一个创建它以外的线程想访问它 获取一个值 该值指示调用方在对控件进行方法调用时是否必须调用 I
  • js+bootstrap+jquery+vue实现房贷计算器

    代码链接 loan 使用vue js html css实现房贷的计算 版权声明 本文为CSDN博主 小样还想跑 的原创文章 遵循CC 4 0 BY SA版权协议 转载请附上原文出处链接及本声明
  • 23 种设计模式详解(全23种)

    设计模式的分类 总体来说设计模式分为三大类 创建型模式 共五种 工厂方法模式 抽象工厂模式 单例模式 建造者模式 原型模式 结构型模式 共七种 适配器模式 装饰器模式 代理模式 外观模式 桥接模式 组合模式 享元模式 行为型模式 共十一种
  • 人手一份核武器:Android手机装Kali Linux

    首先这是安卓手机的专属工具 因为Android基于Linux 所以就有了得天独厚的优势 1 先下载好Linux Deploy 前提是本手机已root 2 按下图配置 不过有地方需要说明 Distribute Suite已经改为sana 但无
  • Windows Server 2012 R2 设置 smtp 服务器

    Windows Server 2012 2012 R2 安装和配置 SMTP 服务器 安装 SMTP 服务器 以下是安装 SMTP 服务器功能的步骤 打开 服务器管理器 单击键盘上的 Windows 按钮 输入 服务器管理器 在 结果 窗口
  • FW-1设备配置命令

    DCFW 1800 config hostname FW 1 FW 1 config ip vrouter trust vr FW 1 config vrouter ip route 0 0 0 0 0 202 11 33 26 FW 1
  • cmd创建用户并初始化新用户桌面

    author skate time 2013 12 20 功能 在win2003上创建用户 并初始化新用户的桌面 echo InternetShortcut gt gt MysqlTool url echo URL C Program Fi
  • Qt之pro配置多个子工程/子模块

    简述 进行Qt项目开发的时候 尤其是大型项目 经常涉及多工程 多模块问题 其主要思想还是模块化 目的是为了降低程序复杂度 使程序设计 调试和维护等操作简单化 简述 配置 效果 多工程 多模块 更多参考 配置 效果 多工程 如果需要管理多工程
  • JavaMap集合&Stream流

    1 Map集合 1 1Map集合概述和特点 Map集合概述 interface Map
  • Python-Thread(通俗易懂)

    此类表示在单独的控制线程中运行的活动 有两种方法可以指定该活动 一是将可调用对象传递给构造函数 二是通过覆盖子类中的run 方法 如果你对线程不太理解 我们可以打个比方 把线程数看作车辆数 我们来完成一个简单的客运运输工作 以下为了方便理解
  • 第8届Python编程挑战赛初赛真题剖析-2022年全国青少年信息素养大赛

    导读 超平老师计划推出 全国青少年信息素养大赛Python编程真题解析 50讲 这是超平老师解读Python编程挑战赛系列的第1讲 全国青少年信息素养大赛 原全国青少年电子信息智能创新大赛 是 世界机器人大会青少年机器人设计与信息素养大赛
  • VC++ MapWinGis篇(二)

    添加高德图层 ArcGisProvider h pragma once include BaseProvider h class ArcGisBaseProvider public BaseProvider public ArcGisBas
  • Java RMI 远程代码执行漏洞

    0x01 漏洞描述 Java RMI 远程代码执行漏洞 Java RMI服务是远程方法调用 是J2SE的一部分 能够让程序员开发出基于JAVA的分布式应用 一个RMI对象是一个远程Java对象 可以从另一个Java虚拟机上 甚至跨过网络 调
  • 这篇文章带你了解sql语句是怎么执行的

    一条sql语句是怎么执行的 一 mysql架构分析 二 语句分析 2 1 查询语句 2 2 更新语句 三 总结 mysql有各种版本的架构图 但基本上都可以分为Server层和存储引擎层 一 mysql架构分析 下面是mysql的一个简要架
  • web压测工具http_load原理分析

    01 前言 http load是一款测试web服务器性能的开源工具 从下面的网址可以下载到最新版本的http load http www acme com software http load 这个软件一直在保持着更新 不像webbench
  • el-tree组件展示节点过多时造成页面卡顿、奔溃的解决办法

    解决el tree组件展示节点过多时造成页面卡顿 奔溃 前几天测试提了个BUG 文件列表展示5w个文件页面会卡顿甚至奔溃 项目用的是vue element ui框架 我是使用el tree进行渲染文件列表的 参考网上使用virtual sc
  • Log4j2注入漏洞万字剖析-汇总收藏版(攻击步骤、漏洞原理、2.15.0-RC1绕过原理以及2.15.0、2.16.0修复原理)

    系列文章 2 15 0之前版漏洞相关文章 Log4j2注入漏洞 CVE 2021 44228 万字深度剖析 一 开篇与基础知识 Log4j2注入漏洞 CVE 2021 44228 万字深度剖析 二 漏洞原理 Log4j2注入漏洞 CVE 2
  • ILRuntime(二)整合Hotfix到Unity中,脚本生成dll文件

    如果开发的时候按之前的一个Hotfix工程 一个Unity工程 开发会很麻烦 因此我们可以把Hotfix部分的代码放入到Unity当中 并增加一个标记 到时候把这些代码整合成一个dll文件即可 具体思路 ILRuntime的原理就是热更代码
  • nginx中root和alias指令的解释

    1 基本信息 功能均为将url映射为文件路径 返回静态文件内容 格式 alias path root path 2 区别 root会映射完整url 会将location匹配的部分 追加到path后面 即 root指定web的家目录 在定义l
  • 机器学习 BP神经网络(Python实现)

    一个神经元即一个感知机模型 由多个神经元相互连接形成的网络 即神经网络 这里我们只讨论单隐层前馈神经网络 其连接形式入下 神经网络模型的待估参数即 每个神经元的阈值 以及神经元之间的连接权重 对于该模型有如下定义 训练集 D x1 y1 x