一层神经网络实现鸢尾花数据集分类
一层神经网络实现鸢尾花数据集分类
- 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()
一层神经网络实现鸢尾花数据集分类相关推荐
- 利用神经网络对鸢尾花数据集分类
利用神经网络对鸢尾花数据集分类 详细实现代码请见:https://download.csdn.net/download/weixin_43521269/12578696 一.简介 一个人工神经元网络是 ...
- (决策树,朴素贝叶斯,人工神经网络)实现鸢尾花数据集分类
from sklearn.datasets import load_iris # 导入方法类iris = load_iris() #导入数据集iris iris_feature = iris.data ...
- Tensorflow搭建神经网络八股及实现鸢尾花数据集分类
tensorflow笔记系列文章均参考自中国大学Mooc上北京大学软件与微电子学院曹建老师的<Tensorflow笔记2>课程.曹建老师讲的非常棒,受益良多,强烈建议tensorflow初 ...
- Python实现鸢尾花数据集分类问题——基于skearn的SVM(有详细注释的)
Python实现鸢尾花数据集分类问题--基于skearn的SVM 代码如下: 1 # !/usr/bin/env python2 # encoding: utf-83 __author__ = 'Xi ...
- 基于Adaboost实现鸢尾花数据集分类
写在之前 提交内容分为两大部分: 一为Adaboost算法实现,代码在文件夹<算法实现>中,<提升方法笔记>为个人学习笔记. 二为基于Adaboost模型实现鸢尾花数据集分类, ...
- 二隐层的神经网络实现MNIST数据集分类
二隐层的神经网络实现MNIST数据集分类 传统的人工神经网络包含三部分,输入层.隐藏层和输出层.对于一个神经网络模型的确定需要考虑以下几个方面: 隐藏层的层数以及各层的神经元数量 各层激活函数的选择 ...
- Python实现鸢尾花数据集分类问题——基于skearn的LogisticRegression
Python实现鸢尾花数据集分类问题--基于skearn的LogisticRegression 一. 逻辑回归 逻辑回归(Logistic Regression)是用于处理因变量为分类变量的回归问题, ...
- 用逻辑回归实现鸢尾花数据集分类(1)
鸢尾花数据集的分类问题指导 -- 对数几率回归(逻辑回归)问题研究 (1) 这一篇Notebook是应用对数几率回归(Logit Regression)对鸢尾花数据集进行品种分类的.首先会带大家探索一 ...
- 实验一:鸢尾花数据集分类
实验一:鸢尾花数据集分类 一.问题描述 利用机器学习算法构建模型,根据鸢尾花的花萼和花瓣大小,区分鸢尾花的品种.实现一个基础的三分类问题. 二.数据集分析 Iris 鸢尾花数据集内包含 3 种类别,分 ...
最新文章
- 2.3.6 操作系统之进程同步与互斥经典问题(生产者-消费者问题、多生产者-多消费者问题、吸烟者问题、读者-写者问题、哲学家进餐问题)
- python中的断点是什么_python中简单的递归(断点报错的小福利)
- TikTok测试三分钟视频、Reddit首次公布DAU、谷歌解雇人工智能领头人、年度最受欢迎应用|Decode the Week...
- sigaction函数使用实例
- python正则匹配日期2019-03-11_都2019年了,正则表达式为啥还是这么难?这里的Python学习教程教你搞定!...
- 【转】HTML5第一人称射击游戏发布
- linux6.0 安装教程,CentOS 6.0安装步骤
- R循环有两个_R语言数据分析与挖掘(第九章):聚类分析(2)——层次聚类
- c语言二维数组每行最小值,编写一个函数,用于计算具有n行和m列的二维数组中指定列的平均值以及数组各行的和的最小值。...
- Unity URP 渲染管线着色器编程 104 之 镜头光晕(lensflare)的实现
- MB/s与Mbit/s的区别!!!
- 【算法复习】迭代改进
- 在SDLC中使用静态代码分析的最佳实践
- CPU卡技术学习笔记1
- el-tree 改变label
- Java中使用MultipartFile类型接收前端上传的文件过大报异常解决
- php数组合并多维,PHP合并多维数组
- 奇安信漏扫设备与堡垒机问题解析
- pycharm使用私钥远程连接服务器
- 记录一次服务器登录后提示邮件报错550
热门文章
- 下载链接在微信中无法打开的解决方案
- 数据分析师,你是车夫,还是拉车的驴子
- 打开新材料世界的大门:拓扑电子材料目录问世
- foo:function(){}与function foo(){}还有foo=function()三者间的区别
- 打印1000~2000年之间的闰年
- 2021年全球住宅电梯收入大约1534.2百万美元,预计2028年达到1957.3百万美元
- duration java_Java Duration类| 带示例的multipliedBy()方法
- Java Socket通信实现多人多端网络画板聊天室
- Xcode 真机调试 ineligible Devices的解决方法
- 指令隔离DMB,DSB,ISB