题目:

  1. 设计四层BP网络,以g(x)=sigmoid(x)为激活函数,

  2. 神经网络结构为:[4,10,6, 3],其中,输入层为4个节点,第一个隐含层神经元个数为10个节点;第二个隐含层神经元个数为6个节点,输出层为3个节点

  3. 利用训练数据iris-train.txt对BP神经网络分别进行训练,对训练后的模型统计识别正确率,并计算对测试数据iris-test.txt的正确率。

参考函数:

def show_accuracy(n, X, y):
h = n.test(X)
y_pred = np.argmax(h, axis=1)
print(classification_report(y, y_pred))

解:

首先题目已经给出了3行函数,我们可以进行如下拆解:

show_accuracy(n, X, y)n代表BP神经网络模型,采用面向对象的方式编写,X是测试数据输入特征X_testy是测试数据输出特征y_testh = n.test(X)的含义是调用训练好的BPNN的预测方法predict,将X输入进行前向传播即可获得输出层[0,1,2]分别的概率,然后通过np.argmax(h, axis=1)取输出层的最大概率,返回下标0,1,2,最后调用sklearn的分类报告方法即可打印分类准确情况。

主要代码如下:

导入包及数据

import pandas
import numpy as np
from sklearn.metrics import classification_report
# 导入txt数据
iris_train = pandas.read_table("iris/iris-train.txt", header=None)
iris_train.columns = ['SepalLengthCm', 'SepalWidthCm', 'PetalLengthCm', 'PetalWidthCm', 'Species']
iris_test = pandas.read_table("iris/iris-test.txt", header=None)
iris_test.columns = ['SepalLengthCm', 'SepalWidthCm', 'PetalLengthCm', 'PetalWidthCm', 'Species']

编写识别正确率函数

def show_accuracy(self, X, Y):
count=0
Y_pred=[]
for i in range(X.shape[0]):
h=self.update(X[i, 0:4])
y_pred=np.argmax(h)
Y_pred.append(y_pred)
if y_pred==Y[i]:
count+=1
print("准确率为:",count/X.shape[0])
print(count)
print(classification_report(Y, Y_pred))

完整程序代码

import pandas
import numpy as np
from sklearn.metrics import classification_report
# 导入txt数据
iris_train = pandas.read_table("iris/iris-train.txt", header=None)
iris_train.columns = ['SepalLengthCm', 'SepalWidthCm', 'PetalLengthCm', 'PetalWidthCm', 'Species']
iris_test = pandas.read_table("iris/iris-test.txt", header=None)
iris_test.columns = ['SepalLengthCm', 'SepalWidthCm', 'PetalLengthCm', 'PetalWidthCm', 'Species'] #打乱顺序
array = iris_train.values#
np.random.seed(1377)
np.random.shuffle(array) #独热编码
def onehot(targets, num_out):
onehot = np.zeros((num_out, targets.shape[0]))
for idx, val in enumerate(targets.astype(int)):
onehot[val, idx] = 1.
return onehot.T #生成一个矩阵,大小为m*n,并且设置默认零矩阵
def makematrix(m, n, fill=0.0):
X_train = []
for i in range(m):
X_train.append([fill] * n)
return X_train #函数sigmoid()
def sigmoid(x):
a = 1 / (1 + np.exp(-x))
return a #函数
def derived_sigmoid(x):
return x * (1 - x)
# return 1.0 - x ** 2 #构造四层BP网络架构
class BPNN:
def __init__(self, num_in, num_hidden1, num_hidden2, num_out):
# 输入层,隐藏层,输出层的节点数
self.num_in = num_in + 1 # 增加一个偏置结点 4
self.num_hidden1 = num_hidden1 + 1 # 增加一个偏置结点 4
self.num_hidden2 = num_hidden2 + 1
self.num_out = num_out # 激活神经网络的所有节点
self.active_in = [1.0] * self.num_in
self.active_hidden1 = [1.0] * self.num_hidden1
self.active_hidden2 = [1.0] * self.num_hidden2
self.active_out = [1.0] * self.num_out # 创建权重矩阵
self.wight_in = makematrix(self.num_in, self.num_hidden1)
self.wight_h1h2 = makematrix(self.num_hidden1, self.num_hidden2)
self.wight_out = makematrix(self.num_hidden2, self.num_out) # 对权值矩阵赋初值
for i in range(self.num_in):
for j in range(self.num_hidden1):
self.wight_in[i][j] = np.random.normal(0.0, pow(self.num_hidden1, -0.5)) # 输出num_in行,num_hidden列权重矩阵,随机生成满足正态分布的权重
for i in range(self.num_hidden1):
for j in range(self.num_hidden2):
self.wight_h1h2[i][j] = np.random.normal(0.0, pow(self.num_hidden2, -0.5))
for i in range(self.num_hidden2):
for j in range(self.num_out):
self.wight_out[i][j] = np.random.normal(0.0, pow(self.num_out, -0.5)) # 最后建立动量因子(矩阵)
self.ci = makematrix(self.num_in, self.num_hidden1)
self.ch1h2 = makematrix(self.num_hidden1, self.num_hidden2)
self.co = makematrix(self.num_hidden2, self.num_out) # 信号正向传播 def update(self, inputs):
a=len(inputs)
if len(inputs) != self.num_in - 1:
raise ValueError('与输入层节点数不符') # 数据输入输入层
for i in range(self.num_in - 1):
# self.active_in[i] = sigmoid(inputs[i]) #或者先在输入层进行数据处理
self.active_in[i] = inputs[i] # active_in[]是输入数据的矩阵 # 数据在隐藏层1的处理
for i in range(self.num_hidden1):
sum = 0.0
for j in range(self.num_in):
sum = sum + self.active_in[j] * self.wight_in[j][i]
self.active_hidden1[i] = sigmoid(sum) # active_hidden[]是处理完输入数据之后存储,作为输出层的输入数据 # 数据在隐藏层2的处理
for i in range(self.num_hidden2):
sum = 0.0
for j in range(self.num_hidden1):
sum = sum + self.active_hidden1[j] * self.wight_h1h2[j][i]
self.active_hidden2[i] = sigmoid(sum) # active_hidden[]是处理完输入数据之后存储,作为输出层的输入数据 # 数据在输出层的处理
for i in range(self.num_out):
sum = 0.0
for j in range(self.num_hidden2):
sum = sum + self.active_hidden2[j] * self.wight_out[j][i]
self.active_out[i] = sigmoid(sum) # 与上同理 return self.active_out[:] # 误差反向传播
def errorbackpropagate(self, targets, lr, m): # lr是学习率, m是动量因子
if len(targets) != self.num_out:
raise ValueError('与输出层节点数不符!') # 首先计算输出层的误差
out_deltas = [0.0] * self.num_out
for i in range(self.num_out):
error = targets[i] - self.active_out[i]
out_deltas[i] = derived_sigmoid(self.active_out[i]) * error # 计算隐藏层2的误差
hidden2_deltas = [0.0] * self.num_hidden2
for i in range(self.num_hidden2):
error = 0.0
for j in range(self.num_out):
error = error + out_deltas[j] * self.wight_out[i][j]
hidden2_deltas[i] = derived_sigmoid(self.active_hidden2[i]) * error # 计算隐藏层1的误差
hidden1_deltas = [0.0] * self.num_hidden1
for i in range(self.num_hidden1):
error = 0.0
for j in range(self.num_hidden2):
error = error + hidden2_deltas[j] * self.wight_h1h2[i][j]
hidden1_deltas[i] = derived_sigmoid(self.active_hidden1[i]) * error # 更新输出层权值
for i in range(self.num_hidden2):
for j in range(self.num_out):
change = out_deltas[j] * self.active_hidden2[i]
self.wight_out[i][j] = self.wight_out[i][j] + lr * change + m * self.co[i][j]
self.co[i][j] = change # 更新隐藏层间权值
for i in range(self.num_hidden1):
for j in range(self.num_hidden2):
change = hidden2_deltas[j] * self.active_hidden1[i]
self.wight_h1h2[i][j] = self.wight_h1h2[i][j] + lr * change + m * self.ch1h2[i][j]
self.ch1h2[i][j] = change # 然后更新输入层权值
for i in range(self.num_in):
for j in range(self.num_hidden1):
change = hidden1_deltas[j] * self.active_in[i]
self.wight_in[i][j] = self.wight_in[i][j] + lr * change + m * self.ci[i][j]
self.ci[i][j] = change # 计算总误差
error = 0.0
for i in range(self.num_out):
error = error + 0.5 * (targets[i] - self.active_out[i]) ** 2
return error # 测试
def test(self, X_test):
for i in range(X_test.shape[0]):
print(X_test[i, 0:4], '->', self.update(X_test[i, 0:4])) # 权重
def weights(self):
print("输入层权重")
for i in range(self.num_in):
print(self.wight_in[i])
print("输出层权重")
for i in range(self.num_hidden2):
print(self.wight_out[i]) def train(self, train, itera=100, lr=0.1, m=0.1):
for i in range(itera):
error = 0.0
for j in range(100):#训练集的大小
inputs = train[j, 0:4]
d = onehot(train[:,4], self.num_out)
targets = d[j, :]
self.update(inputs)
error = error + self.errorbackpropagate(targets, lr, m)
if i % 100 == 0:
print('误差 %-.5f' % error) def show_accuracy(self, X, Y):
count=0
Y_pred=[]
for i in range(X.shape[0]):
h=self.update(X[i, 0:4])
y_pred=np.argmax(h)
Y_pred.append(y_pred)
if y_pred==Y[i]:
count+=1
print("准确率为:",count/X.shape[0])
print(count)
print(classification_report(Y, Y_pred)) # 实例
def Mytrain(train,X_test, Y_test):
# 创建神经网络,4个输入节点,10个隐藏层1节点,6个隐藏层2节点,3个输出层节点
n = BPNN(4, 10, 6, 3)
# 训练神经网络
print("start training\n--------------------")
n.train(train,itera=1000)
n.weights()
# n.test(X_test)
n.show_accuracy(X_test, Y_test) if __name__ == '__main__':
train = array[:, :] # 训练集
X_test = iris_test.values[:, :] # 测试集
Y_test = iris_test.values[:, 4] # 测试集的标签
Mytrain(train, X_test, Y_test)

输出结果:

start training
--------------------
误差 35.40337
误差 1.43231
误差 1.08501
误差 1.05931
误差 1.04053
误差 1.02761
误差 1.02126
误差 1.01507
误差 1.01000
误差 1.00646
输入层权重
[0.056033408540934464, 2.8041275894047875, 0.16855148969297182, 1.0200135486931827, -1.4263718396216152, 0.46417722366714737, 3.951369301666286, -1.68522617998046, -0.07767181609266427, -0.3263575324395308, 2.0699554193776044]
[-1.4377068931180876, 1.851234250520833, 0.15780177315246371, -0.05179352554189774, -2.3563287594546423, 1.7623583488440409, 3.091780632711021, -1.372026038986551, -1.726220905551624, -1.1669182260086637, 1.6321410768033273]
[0.9560967359135075, -4.531261602111315, -0.6120871721438043, 0.3990936425721157, 2.9004962990324032, -1.6411239366055017, -6.471695892441071, 2.6775054457912315, 1.4507421345886298, 1.962983608402704, -3.3617954044955485]
[0.9386911995204238, -2.5918217255311093, -0.19942943923868559, -0.12162074195611947, 2.299246125556896, -1.5047700193638123, -3.760625731974951, 2.069744371129818, 0.8219878214614533, 0.8239600952803267, -2.5028309920744243]
[-0.5943509557690846, 3.1298630885285528, 0.182341529267033, -0.3904817160983978, -1.477792159823391, 1.242189984057302, 3.993237791636666, -1.3449814648342135, -0.42506681041697547, -0.4405383184743436, 2.466930731983345]
输出层权重
[-0.09150582827392847, 3.142269157863363, -4.641439345864634]
[-1.4871365396516583, -0.48293082562473966, -0.20849376992641952]
[-1.8532830432907033, -6.6108611902097465, 5.752994457916077]
[3.247964863909582, -3.6518302173463195, -1.7172925811709747]
[-0.9773159253935711, -0.3682438453855819, 0.09500142611662453]
[3.513238795753454, -4.578599999073612, -1.5312361861597554]
[-3.9400826690223867, 3.100329638184805, -1.3037079300155898]
准确率为: 0.96
48
precision recall f1-score support 0.0 1.00 1.00 1.00 16
1.0 1.00 0.88 0.94 17
2.0 0.89 1.00 0.94 17 accuracy 0.96 50
macro avg 0.96 0.96 0.96 50
weighted avg 0.96 0.96 0.96 50 Process finished with exit code 0

参考文献:

[1] 四层BP网络python代码实现_odd~的博客-CSDN博客

[2] MachineLearning_Ass2/bpNetwork.py at master · wangtuntun/MachineLearning_Ass2 · GitHub

ps:参考文献[1]代码对于数据处理有严重问题,并且没有写计算正确率的函数,训练结果有严重错误,我部分参考代码[2]进行了修复,代码[2]是7年前的老代码,应该是基于python2的,并不能直接运行在python3.

机器学习(四):4层BP神经网络(只用numpy不调包)用于训练鸢尾花数据集|准确率96%的更多相关文章

  1. 机器学习:python使用BP神经网络示例

    1.简介(只是简单介绍下理论内容帮助理解下面的代码,如果自己写代码实现此理论不够) 1) BP神经网络是一种多层网络算法,其核心是反向传播误差,即: 使用梯度下降法(或其他算法),通过反向传播来不断调 ...

  2. Numpy实现简单BP神经网络识别手写数字

    本文将用Numpy实现简单BP神经网络完成对手写数字图片的识别,数据集为42000张带标签的28x28像素手写数字图像.在计算机完成对手写数字图片的识别过程中,代表图片的28x28=764个像素的特征 ...

  3. 三.BP神经网络

    BP神经网络是包含多个隐含层的网络,具备处理线性不可分问题的能力.以往主要是没有适合多层神经网络的学习算法,,所以神经网络的研究一直处于低迷期. 20世纪80年代中期,Rumelhart,McClel ...

  4. Java实现BP神经网络MNIST手写数字识别

    Java实现BP神经网络MNIST手写数字识别 如果需要源码,请在下方评论区留下邮箱,我看到就会发过去 一.神经网络的构建 (1):构建神经网络层次结构 由训练集数据可知,手写输入的数据维数为784维 ...

  5. BP神经网络分类器的设计

    1.BP神经网络训练过程论述 BP网络结构有3层:输入层.隐含层.输出层,如图1所示. 图1 三层BP网络结构 3层BP神经网络学习训练过程主要由4部分组成:输入模式顺传播(输入模式由输入层经隐含层向 ...

  6. bp神经网络及matlab实现

    本文主要内容包含: (1) 介绍神经网络基本原理,(2) AForge.NET实现前向神经网络的方法,(3) Matlab实现前向神经网络的方法 . 第0节.引例  本文以Fisher的Iris数据集 ...

  7. MATLAB神经网络(2) BP神经网络的非线性系统建模——非线性函数拟合

    2.1 案例背景 在工程应用中经常会遇到一些复杂的非线性系统,这些系统状态方程复杂,难以用数学方法准确建模.在这种情况下,可以建立BP神经网络表达这些非线性系统.该方法把未知系统看成是一个黑箱,首先用 ...

  8. 机器学习:从编程的角度理解BP神经网络

    1.简介(只是简单介绍下理论内容帮助理解下面的代码,如果自己写代码实现此理论不够) 1) BP神经网络是一种多层网络算法,其核心是反向传播误差,即: 使用梯度下降法(或其他算法),通过反向传播来不断调 ...

  9. 机器学习(一):梯度下降、神经网络、BP神经网络

    这几天围绕论文A Neural Probability Language Model 看了一些周边资料,如神经网络.梯度下降算法,然后顺便又延伸温习了一下线性代数.概率论以及求导.总的来说,学到不少知 ...

  10. 【机器学习】BP神经网络实现手写数字识别

    最近用python写了一个实现手写数字识别的BP神经网络,BP的推导到处都是,但是一动手才知道,会理论推导跟实现它是两回事.关于BP神经网络的实现网上有一些代码,可惜或多或少都有各种问题,在下手写了一 ...

随机推荐

  1. 基于MassTransit.RabbitMQ的延时消息队列

    1 nuget包 <PackageReference Include="MassTransit.RabbitMQ" Version="8.0.2" /&g ...

  2. spring security添加接口白名单

    在项目中遇到的问题是要将某个接口设为白名单,无需验证即可被用户使用. 解决方法: 在nacos配置文件中ignore whites(不校验白名单)中添加对应接口,无gateway前缀即可,添加立即生效 ...

  3. Python爬虫之Scrapy制作爬虫

    前几天我有用过Scrapy架构编写了一篇爬虫的代码案例深受各位朋友们喜欢,今天趁着热乎在上一篇有关Scrapy制作的爬虫代码,相信有些基础的程序员应该能看的懂,很简单,废话不多说一起来看看. 前期准备 ...

  4. ssh问题、原理及diffie hellman算法

    1.普通用户无法使用证书登录:原因是权限设置问题 将.ssh目录设为700,authorized_keys设为600即可. 2.查看ssh支持的算法 ssh -Q help ssh -Q kex/ke ...

  5. MPC

    Just for anyone searching for code. I found it here: https://drive.google.com/drive/folders/0BzLEHBD ...

  6. 用bat文件,自动进入cmd虚拟环境

    L:cd L:\myenv\Scriptscmd /K activate.bat  这行,这样写,cmd窗口会继续保留,按任意键也不会关闭. 这个问题网上大部分说法是在批处理里面加上 cmd /k, ...

  7. 实验二 c语言中的表达式及输入输出函数编程应用

    1.    格式符%04d的作用是:在左边填充数字0,输出变量的所有数字且左对齐 #include <stdio.h>int main() { int num; scanf("% ...

  8. SQLServer数据库执行时间

    with kk AS( SELECT TOP 2000 total_worker_time/1000 AS [总消耗CPU 时间(ms)],execution_count [运行次数], qs.tot ...

  9. spring-boot项目布到tomcat容器下部署

    一.修改打包形式 在pom.xml里设置 `war` <packaging>war</packaging> 二.移除嵌入式tomcat插件 在pom.xml里找到spring- ...

  10. Mysql_5.7编译部署

    自述 - 概述:数据库是"按照数据结构来组织.存储和管理数据的仓库".是一个长期存储在计算机内的.有组织的.可共享的.统一管理的大量数据的集合:本文主要介绍mysql_5.7的部署 ...