一层神经网络实现鸢尾花数据集分类

  • 1、数据集介绍
  • 2、程序实现
    • 2.1 数据集导入
    • 2.2 数据集乱序
    • 2.3 数据集划分成永不相见的训练集和测试集
    • 3.4 配成[输入特征,标签]对,每次喂入一小撮(batch):
    • 3.5 定义神经网路中所有可训练参数
    • 3.6 超参数设置
    • 3.7 嵌套循环迭代,with 结构更新参数,显示当前 loss
    • 3.8 计算当前参数前向传播后的准确率,显示当前准确率 acc
    • 3.9 acc/loss可视化
  • 3、完整代码:

1、数据集介绍

  鸢尾花数据集,其提供了 150 组鸢尾花数据,每组包括鸢尾花的花萼 长、花萼宽、花瓣长、花瓣宽 4 个输入特征,同时还给出了这一组特征对应的 鸢尾花类别。类别包括狗尾鸢尾、杂色鸢尾、弗吉尼亚鸢尾三类, 分别用数字 0、1、2 表示。

  使用次数据集的代码如下:

from sklearn.datasets import load_iris
x_data = datasets.load_iris().data # 返回 iris 数据集所有输入特征
y_data = datasets.load_iris().target # 返回 iris 数据集所有标签

  即从 sklearn 包中导出数据集,将输入特征赋值给 x_data 变量,将对应标签赋值给 y_data 变量。

2、程序实现

  我们用神经网络实现鸢尾花分类仅需要三步:

   (1)准备数据,包括数据集读入、数据集乱序,把训练集和测试集中的数据配 成输入特征和标签对,生成 train 和 test 即永不相见的训练集和测试集;

   (2)搭建网络,定义神经网络中的所有可训练参数;

   (3)优化这些可训练的参数,利用嵌套循环在 with 结构中求得损失函数 loss 对每个可训练参数的偏导数,更改这些可训练参数,为了查看效果,程序中可以 加入每遍历一次数据集显示当前准确率,还可以画出准确率 acc 和损失函数 loss 的变化曲线图。以上部分的完整代码与解析如下:

2.1 数据集导入

from sklearn.datasets import datasets
x_data = datasets.load_iris().data # 返回 iris 数据集所有输入特征
y_data = datasets.load_iris().target # 返回 iris 数据集所有标签

2.2 数据集乱序

# 随机打乱数据(因为原始数据是顺序的,顺序不打乱会影响准确率)
# seed: 随机数种子,是一个整数,当设置之后,每次生成的随机数都一样(为方便教学,以保每位同学结果一致)
np.random.seed(116)  # 使用相同的seed,保证输入特征和标签一一对应
np.random.shuffle(x_data)
np.random.seed(116)
np.random.shuffle(y_data)
tf.random.set_seed(116)

  因为使用了同样的随机种子,所以 打乱顺序后输入特征和标签仍然是一一对应的。

2.3 数据集划分成永不相见的训练集和测试集

# 将打乱后的数据集分割为训练集和测试集,训练集为前120行,测试集为后30行
x_train = x_data[:-30]
y_train = y_data[:-30]
x_test = x_data[-30:]
y_test = y_data[-30:]

  将打乱后的前 120 个数据取出来作为训练集,后 30 个数据作为测试集,为了公正评判神经网络的效果, 训练集和测试集没有交集。

3.4 配成[输入特征,标签]对,每次喂入一小撮(batch):

# 转换x的数据类型,否则后面矩阵相乘时会因数据类型不一致报错
x_train = tf.cast(x_train, tf.float32)
x_test = tf.cast(x_test, tf.float32)# from_tensor_slices函数使输入特征和标签值一一对应。(把数据集分批次,每个批次batch组数据)
train_db = tf.data.Dataset.from_tensor_slices((x_train, y_train)).batch(32)
test_db = tf.data.Dataset.from_tensor_slices((x_test, y_test)).batch(32)

  使用 from_tensor_slices 把训练集的输入特征 和标签配对打包,将每 32 组输入特征标签对打包为一个 batch,在喂入神经网络 时会以 batch 为单位喂入。

3.5 定义神经网路中所有可训练参数

# 生成神经网络的参数,4个输入特征故,输入层为4个输入节点;因为3分类,故输出层为3个神经元
# 用tf.Variable()标记参数可训练
# 使用seed使每次生成的随机数相同(方便教学,使大家结果都一致,在现实使用时不写seed)
w1 = tf.Variable(tf.random.truncated_normal([4, 3], stddev=0.1, seed=1))
b1 = tf.Variable(tf.random.truncated_normal([3], stddev=0.1, seed=1))

  定义了神经网络的所有可训练参数。只用了一层网络,因为输入特征是 4 个,输出节点数等于分类数,是 3 分类,故参数 w1为 4 行 3 列的张量,b1必须与 w1的维度一致,所以是 3。

3.6 超参数设置

lr = 0.1  # 学习率为0.1
train_loss_results = []  # 将每轮的loss记录在此列表中,为后续画loss曲线提供数据
test_acc = []  # 将每轮的acc记录在此列表中,为后续画acc曲线提供数据
epoch = 500  # 循环500轮
loss_all = 0  # 每轮分4个step,loss_all记录四个step生成的4个loss的和

3.7 嵌套循环迭代,with 结构更新参数,显示当前 loss

for epoch in range(epoch):  #数据集级别的循环,每个epoch循环一次数据集for step, (x_train, y_train) in enumerate(train_db):  #batch级别的循环 ,每个step循环一个batchwith tf.GradientTape() as tape:  # with结构记录梯度信息y = tf.matmul(x_train, w1) + b1  # 神经网络乘加运算y = tf.nn.softmax(y)  # 使输出y符合概率分布(此操作后与独热码同量级,可相减求loss)y_ = tf.one_hot(y_train, depth=3)  # 将标签值转换为独热码格式,方便计算loss和accuracyloss = tf.reduce_mean(tf.square(y_ - y))  # 采用均方误差损失函数mse = mean(sum(y-out)^2)loss_all += loss.numpy()  # 将每个step计算出的loss累加,为后续求loss平均值提供数据,这样计算的loss更准确# 计算loss对各个参数的梯度grads = tape.gradient(loss, [w1, b1])# 实现梯度更新 w1 = w1 - lr * w1_grad    b = b - lr * b_gradw1.assign_sub(lr * grads[0])  # 参数w1自更新b1.assign_sub(lr * grads[1])  # 参数b自更新# 每个epoch,打印loss信息print("Epoch {}, loss: {}".format(epoch, loss_all/4))train_loss_results.append(loss_all / 4)  # 将4个step的loss求平均记录在此变量中loss_all = 0  # loss_all归零,为记录下一个epoch的loss做准备

  用两层 for 循环进行更新参数:

  第一层 for 循 环是针对整个数据集进行循环,故用 epoch 表示;

  第二层 for 循环是针对 batch 的,用 step 表示。在 with 结构中计算前向传播的预测结果 y ,计算损失函数 loss 损失函数 loss,分别对参数 w1和参数b1计算偏导数,更新参数 w1和参数b1的值, 打印出这一轮 epoch 后的损失函数值。

  因为训练集有 120 组数据,batch 是 32, 每个 step 只能喂入 32 组数据,需要 batch 级别循环 4 次,所以 loss 除以 4,求得 每次 step 迭代的平均 loss

3.8 计算当前参数前向传播后的准确率,显示当前准确率 acc

     # 测试部分# total_correct为预测对的样本个数, total_number为测试的总样本数,将这两个变量都初始化为0total_correct, total_number = 0, 0for x_test, y_test in test_db:# 使用更新后的参数进行预测y = tf.matmul(x_test, w1) + b1y = tf.nn.softmax(y)pred = tf.argmax(y, axis=1)  # 返回y中最大值的索引,即预测的分类# 将pred转换为y_test的数据类型pred = tf.cast(pred, dtype=y_test.dtype)# 若分类正确,则correct=1,否则为0,将bool型的结果转换为int型correct = tf.cast(tf.equal(pred, y_test), dtype=tf.int32)# 将每个batch的correct数加起来correct = tf.reduce_sum(correct)# 将所有batch中的correct数加起来total_correct += int(correct)# total_number为测试的总样本数,也就是x_test的行数,shape[0]返回变量的行数total_number += x_test.shape[0]# 总的准确率等于total_correct/total_numberacc = total_correct / total_numbertest_acc.append(acc)print("Test_acc:", acc)

  前向传播计算出 y ,使其符合概率分布并找到最大的概率值对应的索引号,调整数据类型与标 签一致,如果预测值和标签相等则 correct 变量自加一,准确率即预测对了的数 量除以测试集中的数据总数。

3.9 acc/loss可视化

# 绘制 loss 曲线
plt.title('Loss Function Curve')  # 图片标题
plt.xlabel('Epoch')  # x轴变量名称
plt.ylabel('Loss')  # y轴变量名称
plt.plot(train_loss_results, label="$Loss$")  # 逐点画出trian_loss_results值并连线,连线图标是Loss
plt.legend()  # 画出曲线图标
plt.show()  # 画出图像# 绘制 Accuracy 曲线
plt.title('Acc Curve')  # 图片标题
plt.xlabel('Epoch')  # x轴变量名称
plt.ylabel('Acc')  # y轴变量名称
plt.plot(test_acc, label="$Accuracy$")  # 逐点画出test_acc值并连线,连线图标是Accuracy
plt.legend()
plt.show()

  将计算出的准确率画成曲线图,通过设 置图标题、设置 x 轴名称、设置 y 轴名称,标出每个 epoch 时的准确率并画出曲 线,可用同样方法画出 loss 曲线。

  训练过程 loss 曲线:

  训练过程准确率曲线:

3、完整代码:

# -*- coding: UTF-8 -*-
# 利用鸢尾花数据集,实现前向传播、反向传播,可视化loss曲线# 导入所需模块
import tensorflow as tf
from sklearn import datasets
from matplotlib import pyplot as plt
import numpy as np# 导入数据,分别为输入特征和标签
x_data = datasets.load_iris().data
y_data = datasets.load_iris().target# 随机打乱数据(因为原始数据是顺序的,顺序不打乱会影响准确率)
# seed: 随机数种子,是一个整数,当设置之后,每次生成的随机数都一样(为方便教学,以保每位同学结果一致)
np.random.seed(116)  # 使用相同的seed,保证输入特征和标签一一对应
np.random.shuffle(x_data)
np.random.seed(116)
np.random.shuffle(y_data)
tf.random.set_seed(116)# 将打乱后的数据集分割为训练集和测试集,训练集为前120行,测试集为后30行
x_train = x_data[:-30]
y_train = y_data[:-30]
x_test = x_data[-30:]
y_test = y_data[-30:]# 转换x的数据类型,否则后面矩阵相乘时会因数据类型不一致报错
x_train = tf.cast(x_train, tf.float32)
x_test = tf.cast(x_test, tf.float32)# from_tensor_slices函数使输入特征和标签值一一对应。(把数据集分批次,每个批次batch组数据)
train_db = tf.data.Dataset.from_tensor_slices((x_train, y_train)).batch(32)
test_db = tf.data.Dataset.from_tensor_slices((x_test, y_test)).batch(32)# 生成神经网络的参数,4个输入特征故,输入层为4个输入节点;因为3分类,故输出层为3个神经元
# 用tf.Variable()标记参数可训练
# 使用seed使每次生成的随机数相同(方便教学,使大家结果都一致,在现实使用时不写seed)
w1 = tf.Variable(tf.random.truncated_normal([4, 3], stddev=0.1, seed=1))
b1 = tf.Variable(tf.random.truncated_normal([3], stddev=0.1, seed=1))lr = 0.1  # 学习率为0.1
train_loss_results = []  # 将每轮的loss记录在此列表中,为后续画loss曲线提供数据
test_acc = []  # 将每轮的acc记录在此列表中,为后续画acc曲线提供数据
epoch = 500  # 循环500轮
loss_all = 0  # 每轮分4个step,loss_all记录四个step生成的4个loss的和# 训练部分
for epoch in range(epoch):  #数据集级别的循环,每个epoch循环一次数据集for step, (x_train, y_train) in enumerate(train_db):  #batch级别的循环 ,每个step循环一个batchwith tf.GradientTape() as tape:  # with结构记录梯度信息y = tf.matmul(x_train, w1) + b1  # 神经网络乘加运算y = tf.nn.softmax(y)  # 使输出y符合概率分布(此操作后与独热码同量级,可相减求loss)y_ = tf.one_hot(y_train, depth=3)  # 将标签值转换为独热码格式,方便计算loss和accuracyloss = tf.reduce_mean(tf.square(y_ - y))  # 采用均方误差损失函数mse = mean(sum(y-out)^2)loss_all += loss.numpy()  # 将每个step计算出的loss累加,为后续求loss平均值提供数据,这样计算的loss更准确# 计算loss对各个参数的梯度grads = tape.gradient(loss, [w1, b1])# 实现梯度更新 w1 = w1 - lr * w1_grad    b = b - lr * b_gradw1.assign_sub(lr * grads[0])  # 参数w1自更新b1.assign_sub(lr * grads[1])  # 参数b自更新# 每个epoch,打印loss信息print("Epoch {}, loss: {}".format(epoch, loss_all/4))train_loss_results.append(loss_all / 4)  # 将4个step的loss求平均记录在此变量中loss_all = 0  # loss_all归零,为记录下一个epoch的loss做准备# 测试部分# total_correct为预测对的样本个数, total_number为测试的总样本数,将这两个变量都初始化为0total_correct, total_number = 0, 0for x_test, y_test in test_db:# 使用更新后的参数进行预测y = tf.matmul(x_test, w1) + b1y = tf.nn.softmax(y)pred = tf.argmax(y, axis=1)  # 返回y中最大值的索引,即预测的分类# 将pred转换为y_test的数据类型pred = tf.cast(pred, dtype=y_test.dtype)# 若分类正确,则correct=1,否则为0,将bool型的结果转换为int型correct = tf.cast(tf.equal(pred, y_test), dtype=tf.int32)# 将每个batch的correct数加起来correct = tf.reduce_sum(correct)# 将所有batch中的correct数加起来total_correct += int(correct)# total_number为测试的总样本数,也就是x_test的行数,shape[0]返回变量的行数total_number += x_test.shape[0]# 总的准确率等于total_correct/total_numberacc = total_correct / total_numbertest_acc.append(acc)print("Test_acc:", acc)print("--------------------------")# 绘制 loss 曲线
plt.title('Loss Function Curve')  # 图片标题
plt.xlabel('Epoch')  # x轴变量名称
plt.ylabel('Loss')  # y轴变量名称
plt.plot(train_loss_results, label="$Loss$")  # 逐点画出trian_loss_results值并连线,连线图标是Loss
plt.legend()  # 画出曲线图标
plt.show()  # 画出图像# 绘制 Accuracy 曲线
plt.title('Acc Curve')  # 图片标题
plt.xlabel('Epoch')  # x轴变量名称
plt.ylabel('Acc')  # y轴变量名称
plt.plot(test_acc, label="$Accuracy$")  # 逐点画出test_acc值并连线,连线图标是Accuracy
plt.legend()
plt.show()

一层神经网络实现鸢尾花数据集分类相关推荐

  1. 利用神经网络对鸢尾花数据集分类

    利用神经网络对鸢尾花数据集分类 详细实现代码请见:https://download.csdn.net/download/weixin_43521269/12578696 一.简介 一个人工神经元网络是 ...

  2. (决策树,朴素贝叶斯,人工神经网络)实现鸢尾花数据集分类

    from sklearn.datasets import load_iris # 导入方法类iris = load_iris() #导入数据集iris iris_feature = iris.data ...

  3. Tensorflow搭建神经网络八股及实现鸢尾花数据集分类

    tensorflow笔记系列文章均参考自中国大学Mooc上北京大学软件与微电子学院曹建老师的<Tensorflow笔记2>课程.曹建老师讲的非常棒,受益良多,强烈建议tensorflow初 ...

  4. Python实现鸢尾花数据集分类问题——基于skearn的SVM(有详细注释的)

    Python实现鸢尾花数据集分类问题--基于skearn的SVM 代码如下: 1 # !/usr/bin/env python2 # encoding: utf-83 __author__ = 'Xi ...

  5. 基于Adaboost实现鸢尾花数据集分类

    写在之前 提交内容分为两大部分: 一为Adaboost算法实现,代码在文件夹<算法实现>中,<提升方法笔记>为个人学习笔记. 二为基于Adaboost模型实现鸢尾花数据集分类, ...

  6. 二隐层的神经网络实现MNIST数据集分类

    二隐层的神经网络实现MNIST数据集分类 传统的人工神经网络包含三部分,输入层.隐藏层和输出层.对于一个神经网络模型的确定需要考虑以下几个方面: 隐藏层的层数以及各层的神经元数量 各层激活函数的选择 ...

  7. Python实现鸢尾花数据集分类问题——基于skearn的LogisticRegression

    Python实现鸢尾花数据集分类问题--基于skearn的LogisticRegression 一. 逻辑回归 逻辑回归(Logistic Regression)是用于处理因变量为分类变量的回归问题, ...

  8. 用逻辑回归实现鸢尾花数据集分类(1)

    鸢尾花数据集的分类问题指导 -- 对数几率回归(逻辑回归)问题研究 (1) 这一篇Notebook是应用对数几率回归(Logit Regression)对鸢尾花数据集进行品种分类的.首先会带大家探索一 ...

  9. 实验一:鸢尾花数据集分类

    实验一:鸢尾花数据集分类 一.问题描述 利用机器学习算法构建模型,根据鸢尾花的花萼和花瓣大小,区分鸢尾花的品种.实现一个基础的三分类问题. 二.数据集分析 Iris 鸢尾花数据集内包含 3 种类别,分 ...

最新文章

  1. 2.3.6 操作系统之进程同步与互斥经典问题(生产者-消费者问题、多生产者-多消费者问题、吸烟者问题、读者-写者问题、哲学家进餐问题)
  2. python中的断点是什么_python中简单的递归(断点报错的小福利)
  3. TikTok测试三分钟视频、Reddit首次公布DAU、谷歌解雇人工智能领头人、年度最受欢迎应用|Decode the Week...
  4. sigaction函数使用实例
  5. python正则匹配日期2019-03-11_都2019年了,正则表达式为啥还是这么难?这里的Python学习教程教你搞定!...
  6. 【转】HTML5第一人称射击游戏发布
  7. linux6.0 安装教程,CentOS 6.0安装步骤
  8. R循环有两个_R语言数据分析与挖掘(第九章):聚类分析(2)——层次聚类
  9. c语言二维数组每行最小值,编写一个函数,用于计算具有n行和m列的二维数组中指定列的平均值以及数组各行的和的最小值。...
  10. Unity URP 渲染管线着色器编程 104 之 镜头光晕(lensflare)的实现
  11. MB/s与Mbit/s的区别!!!
  12. 【算法复习】迭代改进
  13. 在SDLC中使用静态代码分析的最佳实践
  14. CPU卡技术学习笔记1
  15. el-tree 改变label
  16. Java中使用MultipartFile类型接收前端上传的文件过大报异常解决
  17. php数组合并多维,PHP合并多维数组
  18. 奇安信漏扫设备与堡垒机问题解析
  19. pycharm使用私钥远程连接服务器
  20. 记录一次服务器登录后提示邮件报错550

热门文章

  1. 下载链接在微信中无法打开的解决方案
  2. 数据分析师,你是车夫,还是拉车的驴子
  3. 打开新材料世界的大门:拓扑电子材料目录问世
  4. foo:function(){}与function foo(){}还有foo=function()三者间的区别
  5. 打印1000~2000年之间的闰年
  6. 2021年全球住宅电梯收入大约1534.2百万美元,预计2028年达到1957.3百万美元
  7. duration java_Java Duration类| 带示例的multipliedBy()方法
  8. Java Socket通信实现多人多端网络画板聊天室
  9. Xcode 真机调试 ineligible Devices的解决方法
  10. 指令隔离DMB,DSB,ISB