tensorflow04——实战:鸢尾花iris数据集分类,神经网络

简单说分四步

01准备数据
02搭建网络
03优化训练参数————(训练部分 + 测试部分)循环
04作图——loss,acc

import tensorflow as tf
import numpy as np
from sklearn import datasets
from matplotlib import pyplot as plt

#01准备数据

x_data=datasets.load_iris().data
y_data=datasets.load_iris().target

#数据集乱序

np.random.seed(116)
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:]

#统一数据类型为float32,以免后面矩阵相乘时因为数据类型不一致而报错
x_train=tf.cast(x_train,tf.float32)
x_test=tf.cast(x_test,tf.float32)

#数据配对,使用tensorflow数据切片
#使得输入数据(特征)和标签一一配对,训练集120对数据,测试集30对数据
#并分组打包,每32对数据打包为一个batch,方便后面模型训练
#所以训练集包含4个batch,测试集包含1个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)

#02 搭建网络

#定义网络的初始参数


#随机生成符合[截断式正太分布]的初始参数 w1[4*3] 和 b1[3]
#参数标要记为可训练Variable,而不是常量constant
#标准差0.1,随机数种子seed=1
#(truncated——截断式,意思就是生成的参数,在均值的上下两个标准差范围内,是为了让生成的随机数不要相差太多)

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 #学习率
epoch=500 
#迭代次数500轮,每轮都在更新参数,看能不能吧损失函数降到最低,不能的话可以再增加迭代次数
#可以看到结果,大概185次迭代后,acc就达到1了,但是loss还在降低。注意过拟合问题


#新建两个空列表
#一个记录每一轮训练后得到的损失函数值loss,一个记录每一轮测试后得到的精度acc
#两个列表后期用于作图
train_loss_results=[]
test_acc=[]

#上面说到120个训练样本组成的训练集,我们划分为4个batch来喂给模型
#所以每轮都会产生四个loss
#每轮记录的loss应该是四个loss的平均值
#设置一个变量来累加这四个loss
loss_all=0


#03 优化训练参数————(训练部分 + 测试部分)循环500次

#一:训练部分

#两层for循环,外层执行500次,内层是4个训练集的batch和1个测试集的batch


for epoch in range (epoch):
    for step , (x_train,y_train) in enumerate(train_db):
        
        #在with结构中记录梯度信息,计算每一轮batch的损失函数值
        with tf.GradientTape() as tape: 
            y=tf.matmul(x_train,w1)+ b1 #计算训练集的预测值
            y=tf.nn.softmax(y)          #使y值符合概率分布——softmax激活函数就是归一化
            y_=tf.one_hot(y_train,depth=3)#使训练集的标签转变为独热码
            
            #定义损失函数为——均方误差损失函数
            loss=tf.reduce_mean(tf.square(y_-y))
            #累计四个batch的loss值,方便后面求每次迭代里,loss的平均值
            loss_all=loss_all+loss.numpy()
        

tf.reduce_mean 函数
用于计算张量tensor沿着指定的数轴(tensor的某一维度)上的的平均值,主要用作降维或者计算tensor(图像)的平均值。

tf.reduce_mean(input_tensor, axis=None, keep_dims=False,  name=None )

第一个参数input_tensor: 输入的待降维的tensor;
第二个参数axis: 指定的轴,如果不指定,则计算所有元素的均值;
第三个参数keep_dims:是否降维度,
设置为True,输出的结果保持输入tensor的形状,设置为False,输出结果会降低维度;

     
     #进行完一次batch后更新参数
     #01求导(损失函数对各个参数),02更新
     grads =tape.gradient(loss,[w1,b1])
     
     w1.assign_sub(lr*grads[0])
     b1.assign_sub(lr*grads[1])    
     # ----------  至此,一个batch的训练结束,获得了一个损失函数值,两个参数各更新了1次
 
 
 #每结束一次epoch,打印一次loss信息(也就是四个batch,获得了四次loss累计值loss_all)
 print("Epoch{}nloss:{}".format(epoch,loss_all/4))
 
 #记录下这轮epoch的loss值 到 之前新建的空列表中,方便后面作图,同时清空loss_all
 train_loss_results.append(loss_all/4)
 loss_all=0
 
#二:测试部分 

#注意是包含在外层循环里的 也就是训练500轮,每一轮都在更新参数获得loss,每一轮最后都会测试获得acc
 
 #预测正确的样本个数,测试的总样本个数
 total_correct,total_number=0,0
 
 #遍历测试集中的所有数据,计算前想传播的预测结果
 for x_test,y_test in test_db:
 
 #使用更新后的参数进行预测,并计算分类准确度acc
     y=tf.matmul(x_test,w1)+ b1 
     y=tf.nn.softmax(y)       
     
     #返回y中最大值的索引,即预测的类别号
     pred=tf.argmax(y,axis=1) #axis=1,横向比较
     
     #将pred转换为和y_test一致的数据类型,方便比较
     pred=tf.cast(pred,dtype=y_test.dtype)
     
     #将pred 与 y_test 相比较 ,若分类正确,则令correct=1,否则为0
     #这里需要把equal的结果(bool类型)转换为int类型
     correct=tf.cast(tf.equal(pred,y_test),dtype=tf.int32)
     
     #将每个batch的correct值加起来
     correct=tf.reduce_sum(correct)
     
     #将所有batch的correct值加起来
     total_correct=total_correct+int(correct)
     
     #total_number为测试的总样本数,也就是x_test的行数,.shape[0]返回变量行数
     total_number=total_number+x_test.shape[0] #————————说实话不是很懂这里啥意思,为什么要累加
     
 #计算准确率acc,每一轮epoch计算一次
 acc=total_correct/total_number
 
 #将每一轮的acc丢到之前的空列表,方便后面作图
 test_acc.append(acc)
     
 print("Test_acc:",acc)
 print("----------------------------------")
 
     

输出结果:

Epoch0
loss:0.282131090760231
Test_acc 0.16666666666666666
----------------------------------
Epoch1
loss:0.25459615513682365
Test_acc 0.16666666666666666
----------------------------------
Epoch2
loss:0.22570250555872917
Test_acc 0.16666666666666666
----------------------------------
Epoch3
loss:0.21028400212526321
Test_acc 0.16666666666666666
----------------------------------
Epoch4
loss:0.19942264258861542
Test_acc 0.16666666666666666
----------------------------------
Epoch5
loss:0.18873638287186623
Test_acc 0.5
----------------------------------
Epoch6
loss:0.17851299792528152
Test_acc 0.5333333333333333
----------------------------------
Epoch7
loss:0.16922874748706818
Test_acc 0.5333333333333333
----------------------------------
Epoch8
loss:0.16107673197984695
Test_acc 0.5333333333333333
----------------------------------
Epoch9
loss:0.15404684096574783
Test_acc 0.5333333333333333
----------------------------------
·
·
·
·
·
·
Epoch500

#04 作图————loss,acc

#loss曲线

plt.title("Loss Function Curve")
plt.xlabel("epoch")
plt.ylabel("loss")
plt.plot(train_loss_results,label="$loss$") #这里的label是指图片上的图例名称
plt.legend() #图片上的图例
plt.show()


#accuracy曲线

plt.title("Acc Curve")
plt.xlabel("epoch")
plt.ylabel("acc")
plt.plot(test_acc,label="$acc$") #这里的label是指图片上的图例名称
plt.legend() #图片上的图例
plt.show()



在这里插入图片描述

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇

)">
下一篇>>