鸢尾花数据集

from sklearn.datasets import load_irisX = load_iris().data
y = load_iris().target
print(f'特征空间:{X}')
print(f'目标值:{y}')

特征空间:
[[5.1 3.5 1.4 0.2]
[4.9 3. 1.4 0.2]
[4.7 3.2 1.3 0.2]
[4.6 3.1 1.5 0.2]
[5. 3.6 1.4 0.2]
[5.4 3.9 1.7 0.4]
[4.6 3.4 1.4 0.3]
[5. 3.4 1.5 0.2]
[4.4 2.9 1.4 0.2]
[4.9 3.1 1.5 0.1]
[5.4 3.7 1.5 0.2]
[4.8 3.4 1.6 0.2]
[4.8 3. 1.4 0.1]
[4.3 3. 1.1 0.1]
[5.8 4. 1.2 0.2]
[5.7 4.4 1.5 0.4]
[5.4 3.9 1.3 0.4]
[5.1 3.5 1.4 0.3]
[5.7 3.8 1.7 0.3]
[5.1 3.8 1.5 0.3]
[5.4 3.4 1.7 0.2]
[5.1 3.7 1.5 0.4]
[4.6 3.6 1. 0.2]
[5.1 3.3 1.7 0.5]
[4.8 3.4 1.9 0.2]
[5. 3. 1.6 0.2]
[5. 3.4 1.6 0.4]
[5.2 3.5 1.5 0.2]
…]
目标值:
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2]

神经网络的代码实现

import math
import numpy as np
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import minmax_scaleclass ANN:def __init__(self, hidden_num, input_node_num, print_node_num, hidden_node_num, learning_rate):self.hn = hidden_num  # 隐藏层数self.inn = input_node_num  # 输入层节点数self.pnn = print_node_num  # 输出层节点数self.hnn1 = int(hidden_node_num)  # 第一层隐藏层节点数self.lr = learning_rate  # 学习率@staticmethoddef sigmoid(w, x):  # 神经元return 1 / (1 + np.exp(-np.dot(w, x)))def one_hidden_FC(self):  # 单个隐藏层的全连接(full connected)wih, Wih, whp, Whp = [], [], [], []for i1 in range(self.hnn1):for j1 in range(self.inn):wi = np.random.rand(1)wih.append(wi[0])Wih.append(wih)  # 输入层与隐藏层之间的所有权重for p in range(self.pnn):for q in range(self.hnn1):wi = np.random.rand(1)whp.append(wi[0])Whp.append(whp)  # 隐藏层与输出层之间的所有权重Wih, Whp = np.array(Wih), np.array(Whp)return [Wih, Whp]# def more_hidden_FC(self):  # 多个隐藏层的全连接(full connected)#     pass@staticmethoddef hidden_output_output(Wih, Whp, x):  # 隐藏层与输出层的输出值A, Y = [], []for i2 in range(len(Wih)):ai = ANN.sigmoid(Wih[i2], x)A.append(ai)  # 隐藏层的输出值for j2 in range(len(Whp)):y = ANN.sigmoid(Whp[j2], A)Y.append(y)  # 输出层的输出值return [A, Y]def output_error(self, x, yi):  # 输出层的误差  yi:真实值  y:预测值error_list, y = [], ANN.hidden_output_output(ANN.one_hidden_FC(self)[0], ANN.one_hidden_FC(self)[1], x)[1]for i3 in range(self.pnn):error = y[i3] * (1 - y[i3]) * (yi - y[i3])error_list.append(error)return error_list  # len(error_list) == pnndef hidden_error(self, Whp, A, oe):  # 隐藏层的误差  oe:output_error  Whp:隐藏层与输出层之间的权值  A:隐藏层的输出error, error_list = 0, []for i4 in range(self.hnn1):for j in range(self.pnn):error_part = A[i4] * (1 - A[i4]) * Whp[i4][j] * oe[j]error += error_parterror_list.append(error)return error_listdef one_hidden_BP(self, Wih, Whp, x, lr, yi):  # 单个隐藏层-反向传播算法(Back Propagation)  lr:学习率whp_new, Whp_new, wih_new, Wih_new = [], [], [], []Whp_trans, Wih_trans = Whp.transpose(), Wih.transpose()for i5 in range(self.hnn1):for j in range(self.pnn):Whp_trans[i5][j] += lr * ANN.output_error(self, x, yi)[j] * \ANN.hidden_output_output(ANN.one_hidden_FC(self)[0],ANN.one_hidden_FC(self)[1], x)[0][i5]  # 更新隐藏层与输出层之间的权重whp_new.append(Whp_trans[i5][j])Whp_new.append(whp_new)Whp_new_arr = np.array(Whp_new)for p in range(self.inn):for q in range(self.hnn1):Wih_trans[p][q] += lr * ANN.hidden_error(self, Whp_new_arr,ANN.hidden_output_output(ANN.one_hidden_FC(self)[0],ANN.one_hidden_FC(self)[1], x)[0],ANN.output_error(self, x, yi))[q] * x[p]  # 更新输入层与隐藏层之间的权重wih_new.append(Wih_trans[p][q])Wih_new.append(wih_new)Wih_new_arr = np.array(Wih_new)return [Wih_new_arr.transpose(), Whp_new_arr.transpose()]# def more_hidden_BP(self):  # 多个隐藏层-反向传播算法(Back Propagation)#     return

训练与测试

if __name__ == '__main__':# 鸢尾花数据预处理X = load_iris().datay = load_iris().targetX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)a, b, c, d = np.array(X_train), np.ones(len(X_train)), np.array(X_test), np.ones(len(X_test))X_train, X_test, y_train, y_test = np.insert(a, 0, b, axis=1), np.insert(c, 0, d, axis=1), np.array(y_train), np.array(y_test)print(f'数据集目标真实值:{y_train}')print(f'测试集目标真实值:{y_test}')# BP之前的预测值与损失input_node_num, print_node_num = 5, 5inn_multi_pnn = input_node_num * print_node_numhidden_node_num1 = math.sqrt(inn_multi_pnn)ann = ANN(1, input_node_num, print_node_num, hidden_node_num1, 0.5)Wih, Whp = ann.one_hidden_FC()[0], ann.one_hidden_FC()[1]Y_pre_pre = []for x1 in range(len(X_train)):y_pre_pre = np.sum(ann.hidden_output_output(Wih, Whp, X_train[x1])[1]) / print_node_numY_pre_pre.append(y_pre_pre)Y_pre_pre = np.array(Y_pre_pre)print(f'进行BP算法之前的目标预测值:{Y_pre_pre}')Loss_pre = 0for s1 in range(len(y_train)):loss_pre = (1 / 2) * (y_train[s1] - Y_pre_pre[s1]) ** 2Loss_pre += loss_preLoss_pre_aver = Loss_pre / len(y_train)print(f'进行BP算法之前的平均损失:{Loss_pre_aver}')# 进入BP更新所有的权重,这里采用随机梯度下降法count, train_data = 1, np.append(X_train, np.array(y_train)[:, np.newaxis], axis=1)while count < 200:lr = ann.lr / count  # 缩小学习率np.random.shuffle(train_data)X_Train, y_Train = train_data[:, 0:-1], train_data[:, -1]Wih_zero, Whp_zero = np.zeros_like(Wih), np.zeros_like(Whp)for i in range(len(X_train)):Wihna, Whpna = ann.one_hidden_BP(Wih, Whp, X_Train[i], lr, y_Train[i])[0], \ann.one_hidden_BP(Wih, Whp, X_Train[i], lr, y_Train[i])[1]Wih_zero += WihnaWhp_zero += WhpnaWih, Whp = (Wih_zero / len(X_Train)), (Whp_zero / len(X_Train))count += 1# BP之后的预测值与损失Wih_new, Whp_new, Y_behind_pre = Wih, Whp, []for x2 in X_train:y_behind_pre = np.sum(ann.hidden_output_output(Wih_new, Whp_new, x2)[1]) / print_node_numY_behind_pre.append(y_behind_pre)Y_behind_pre = np.array(Y_behind_pre)print(f'进行BP算法之后的目标预测值:{Y_behind_pre}')Loss_behind = 0for s2 in range(len(y_train)):loss_behind = (1 / 2) * (y_train[s2] - Y_behind_pre[s2]) ** 2Loss_behind += loss_behindLoss_behind_aver = Loss_behind / len(y_train)print(f'进行BP算法之后的平均损失:{Loss_behind_aver}')# 测试与评估Y_test_pre = []for x3 in X_test:y_test_pre = np.sum(ann.hidden_output_output(Wih_new, Whp_new, x3)[1]) / print_node_numY_test_pre.append(y_test_pre)Y_test_pre = np.array(Y_test_pre)print(f'测试集的目标预测值:{Y_test_pre}')test_Loss = 0for s3 in range(len(y_test)):test_loss = (1 / 2) * (y_test[s3] - Y_test_pre[s3]) ** 2test_Loss += test_losstest_Loss_aver = test_Loss / len(y_test)print(f'测试集的平均损失:{test_Loss_aver}')

运行结果

数据集目标真实值:
[2 0 2 1 0 1 1 1 1 1 1 2 2 2 0 0 0 0 2 1 0 2 2 0 1 1 0 2 0 1 0 2 2 0 0 2 01 1 2 0 1 1 2 2 1 2 2 0 0 2 2 2 2 2 1 1 2 0 2 1 0 2 2 0 2 2 2 2 0 0 2 2 21 0 1 0 0 1 0 2 1 0 2 1 1 1 1 2 2 1 1 1 2 0 2 1 1 0 0 0 0 0 0 0 2 0 2 1 10 0 1 1 2 2 2 0 2]
测试集目标真实值:
[1 0 0 1 0 2 0 2 1 1 1 2 2 0 1 0 1 2 1 0 1 1 1 0 0 1 1 1 0 0]进行BP算法之前的目标预测值:
[0.95358437 0.95293946 0.95357806 0.95357565 0.95215735 0.953499370.9535721  0.95339961 0.95336813 0.9535622  0.95338073 0.953584380.95357384 0.95358075 0.95275053 0.95326864 0.95313547 0.953170840.95357977 0.95355051 0.95247272 0.95358561 0.95357275 0.952469840.95353004 0.95346372 0.95308123 0.95358242 0.95328152 0.953552860.95297633 0.95357651 0.95358199 0.95309172 0.95276685 0.953577280.95303167 0.9535244  0.95351466 0.95358512 0.95303296 0.953477490.95357594 0.95358712 0.95357949 0.95354221 0.95355623 0.953585960.95277082 0.95284331 0.95358211 0.9535851  0.95358672 0.953588510.95358242 0.95351957 0.95353949 0.95358442 0.95333449 0.953581360.95351939 0.95317617 0.95358138 0.95358546 0.95297613 0.953581650.95358455 0.95356967 0.95357384 0.95291504 0.95284283 0.953585870.95358291 0.95356937 0.95352678 0.95262859 0.95355589 0.952759140.95258763 0.95356351 0.95293526 0.95358712 0.95356571 0.953192530.95358763 0.95356097 0.95356243 0.95353473 0.95356407 0.953584750.95356977 0.95357479 0.95357103 0.95356173 0.95358679 0.953308950.95357682 0.95356577 0.95353947 0.95272987 0.95338016 0.953032030.9529777  0.95313444 0.95258472 0.95147526 0.95357467 0.952910910.95356875 0.95356211 0.95354819 0.9525402  0.95316707 0.953555470.95336063 0.95358038 0.95358808 0.9535511  0.9530053  0.95357283]
进行BP算法之前的平均损失:0.353186539001048进行BP算法之后的目标预测值:
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
进行BP算法之后的平均损失:0.35000000003129444测试集的目标预测值:
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.1. 1. 1. 1. 1. 1.]
测试集的平均损失:0.2666666665414888

评估与总结

  1. 评估
    结合上面的运行结果,在训练阶段,将训练数据输入到BP之前和BP之后的神经网络中去,得到的预测值与真实值分别取平均误差,后者比前者略小,说明一开始的神经网络模型在经过BP算法和数据的训练之后取得了成效。但成效甚微,究其原因我认为有一下几点:
    (1)代码本身可能存在逻辑上的问题(究竟是什么逻辑问题,我也不知道。我恳请各路大神指点一二,在此评论留言,本人将不胜感激)。
    (2)训练次数较少(代码中仅训练了200次,但200次就运行了将近半小时,实在是有点慢,幸好最后的结果满足我的预期)。
    (3)因为采用了sigmoid函数,运行过程中可能出现了梯度消失

  2. 总结
    在进行全连接神经网络的编程之前,通过任老师的讲解,我对神经网络有了一个初步的认识,大致的实现流程也有了。但是,在编程的过程中,许多问题开始浮出水面。
    (1)神经网络的输入层的一个节点对应的到底是训练数据的一条数据[x1, x2, x3, x4,…]还是这一条数据[x1, x2, x3, x4,…]中的x1呢? 我的答案是后者
    (2)神经网络的输出层为什么会有怎么多节点呢?我之所以有这个疑问,是因为无论是回归还是分类,对应的输出结果都只有一个,而输出层却又怎么多节点,难道输出有多个吗? 我的答案:输出层的所有结点得出的结果求和取平均。
    (3)其他问题:权重的表示以及与隐藏层有关的问题。(我遇到的问题实在是太多了,每一个多十分费神,现在想起来都令我头大,这里就不一一列举了。如果有遇到和我类似或者不同的问题的小伙伴欢迎在评论区留言,我们共同探讨,加深理解。

    总之,解决完这些问题后,编程也慢慢地步入了正轨。虽然编程问题依旧很多,但好在有惊无险的将程序编出来了。但这仅仅是进军深度学习的第一步,后面还要跟着任老师继续学习卷积神经网络CNN、循环神经网络RNN、长短时记忆网络LSTM等等等等。往后的道路艰难且漫长,正所谓“长路漫漫,唯剑作伴”,深度学习的第一把“剑”便是赢取其他“宝剑”的开始。

参考链接

零基础入门深度学习(3) - 神经网络和反向传播算法

神经网络与BP算法(代码实现)相关推荐

  1. ML之NN:利用神经网络的BP算法解决XOR类(异或非)问题(BP solve XOR Problem)

    ML之NN:利用神经网络的BP算法解决XOR类(异或非)问题(BP solve XOR Problem) 目录 输出结果 实现代码 输出结果 实现代码 #BP solve XOR Problem im ...

  2. python bp神经网络 异或_【神经网络】BP算法解决XOR异或问题MATLAB版

    第一种 %% %用神经网络解决异或问题 clear clc close ms=4;%设置4个样本 a=[0 0;0 1;1 0;1 1];%设置输入向量 y=[0,1,1,0];%设置输出向量 n=2 ...

  3. 深度学习系列:全连接神经网络和BP算法

    前言 注:以后我的文章会写在个人博客网站上,本站文章也已被搬运.本文地址: https://xiaodongfan.com/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0%E ...

  4. 深度学习——神经网络之DNN全连接神经网络、BP算法原理

    深度学习--神经网络之DNN全连接神经网络.BP算法原理 深度学习--神经网络之DNN全连接神经网络.BP算法原理 1.啥是人工神经网络 2.神经网络的应用 3.神经网络的组成 3.1.神经元 3.2 ...

  5. bp神经网络算法的优缺点,bp神经网络与bp算法区别

    前馈神经网络.BP神经网络.卷积神经网络的区别与联系 一.计算方法不同1.前馈神经网络:一种最简单的神经网络,各神经元分层排列.每个神经元只与前一层的神经元相连.接收前一层的输出,并输出给下一层.各层 ...

  6. 全连接神经网络的BP算法(BP神经网络模型)与卷积神经网络的BP算法

    1.神经网络模型 1.1神经网络模型的演变: 神经元模型------->感知机模型------->神经网络模型 神经元模型:1943年,W.S.McCulloch和W.Pitts根据生物学 ...

  7. 从神经网络到BP算法(纯理论推导)

    作者述:之前有学习过一遍,但是一段时间过后,很多细节地方已经模糊.最近重新推导了一遍,为了尽可能保留推导思路,特地写作此博文.一方面供自己日后回忆,另一方面方便跟大家交流学习. 关于本博文,说明如下: ...

  8. 神经网络之BP算法学习记录(大多借鉴于《神经网络与机器学习——邱锡鹏》)

    神经网络之BP算法 神经网络 前馈神经网络 反向传播算法 损失函数 梯度下降法 梯度下降法在前馈神经网络中的应用 反向传播算法中的梯度下降法 反向传播算法MATLAB示例 使用newff建立神经网络 ...

  9. 机器学习——人工神经网络之BP算法编程(python二分类数据集:马疝病数据集)

    目录 一.理论知识回顾 1.神经网络模型 2.明确任务以及参数 1)待估参数: 2)超参数: 3)任务 3.神经网络数学模型定义 1)激活函数 ​ 2)各层权重.阈值定义 3)各层输入输出定义 4.优 ...

最新文章

  1. python笔记基础-python基础学习笔记(一)
  2. Day02-深度学习原理与使用方法
  3. R语言chorolayer_R语言空间可视化:绘制英国脱欧投票地图
  4. 用函数计算工龄_还在加班熬夜求年龄,算工龄,学会这招让你分分钟钟搞定这些!...
  5. 幼儿编程学java不_《终于有人说出来了——Java不适合于作为主要编程教学语言》我的看法...
  6. 新款iPhone SE并未搭载U1超宽带芯片,后续恐不支持AirTag
  7. oracle 手动添加分区,如何在oracle中创建子分区?
  8. Go语言标准库之fmt.Print
  9. java 各组件单击总数_java 获取面板上有多少个组件
  10. arm linux下交叉编译valgrind工具进行内存泄露检测和性能分析
  11. hive insert into语句 和 insert overwrite语句
  12. 页面加载速度缓慢时,如何优化?
  13. 构建最基础的Spring项目及所需要的jar包
  14. Luogu1514 引水入城
  15. 2018年了,Windows2000还能用吗?
  16. 动力电池系统介绍(八)——继电器
  17. 红米开发版刷机教程_红米K20开发版刷机包(官方系统最新完整固件升级包V20.1.9MIUI开发版)...
  18. 论文阅读:染色归一化
  19. ubuntu16.10+cuda8.0+cudnn+caffe+opencv3.2+anaconda2
  20. wordpress网站单页模板主题开发制作

热门文章

  1. Linux中xxd的简单应用
  2. Python使用try...except...输出详细错误
  3. 基础数论算法(4) 中国剩余定理
  4. vue - 下拉列表
  5. 20154312 曾林 EXP9 Web安全基础
  6. [Android UI] graphics
  7. Stay Hungry, Stay Foolish(求知若饥,虚心若愚)
  8. Linux文件权限:特殊权限、权限属性、权限掩码
  9. 数据结构之前序遍历,中序遍历,后序遍历
  10. php 两种递归方法