tensorflow2学习笔记 4鸢尾花分类

数据集获取

  • 安装sklearn包
pip3 install sklearn
  • 获取特征和标签
from sklearn import datasets
feature = datasets.load_iris().data
label = datasets.load_iris().target

训练测试数据准备

  • 训练集测试集划分
#数据集乱序
np.random.seed(1024)  #设置随机种子,随机种子相同则生成的随机数据相同
np.random.shuffle(feature)  #用于将对象按第一维度打乱
np.random.seed(1024)
np.random.shuffle(label)

#前120条记录作为训练集
x_train = feature[:-30]
y_train = label[:-30]
#后30条记录作为测试集
x_test = feature[-30:]
y_test = label[-30:]
  • 数据分批
#将特征和标签进行组合,32条数据分为一批
#注意训练集和测试集不应该有重合
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)

batch size的选取需要进行调参确认

训练过程

  • 网络结构搭建
#使用单层全连接,四个特征作为输入,三个种类作为输出
w = tf.Variable(tf.random.truncated_normal([4,3] , stddev = 0.1 , seed = 1))
b = tf.Variable(tf.random.truncated_normal([3] , stddev = 0.1 , seed = 1))
  • 通过梯度下降方法对参数进行更新
#超参数和效果统计变量
lr = 0.1                              #学习率
train_loss_result = [] #记录loss
test_acc = []                   #记录acc
epochs = 5000                   #训练轮数
loss_all = 0

for epoch in range(epochs):                     #每循环一次跑一轮数据集合
    for step,(x_train,y_train) in enumerate(train_db): #每循环一次,跑一个batch的数据
        with tf.GradientTape() as tape:
            y = tf.matmul(x_train,w) + b  #前向传播更新结果
            y = tf.nn.softmax(y)                   #使前向传播结果符合概率分布
            y_ = tf.one_hot(y_train,3)       #标签转化为独热码便于计算
            #采用均方误差作为损失函数
            loss = tf.reduce_mean(tf.square(y_ - y))
            loss_all += loss.numpy() #累加用于求均值
        #计算loss对各个参数的梯度
        grads = tape.gradient(loss,[w,b])
        #根据梯度对参数进行更新
        w.assign_sub(lr * grads[0])
        b.assign_sub(lr * grads[1])
  • 每跑完一代训练则进行loss和acc的统计
    统计loss:loss为上文代码中的loss_all/4即为该轮的平均loss
    统计acc:
 #acc统计
total_correct,total_number = 0,0
for x_test , y_test in test_db:
    y = tf.matmul(x_test,w) + b
    y = tf.nn.softmax(y)
    pred = tf.argmax(y,axis=1)    #返回行最大值,即前向传播得到的预测种类
    pred = tf.cast(pred,dtype=y_test.dtype)
    correct = tf.cast(tf.equal(pred,y_test),dtype=tf.int32)
    correct = tf.reduce_sum(correct)  #统计预测正确的个数
    total_correct += int(correct)
    total_number += x_test.shape[0]
acc = total_correct / total_number
test_acc.append(acc)
print("test acc :{}".format(acc))

性能可视化

  • 安装matplotlib
pip3 install matplotlib
  • 可视化
from matplotlib import pyplot as plt
#loss
plt.title('loss')
plt.xlabel("epoch")
plt.ylabel("loss")
plt.plot(train_loss_result,label="$loss$")
plt.legend()
plt.show()
#acc
plt.title('acc')
plt.xlabel("epoch")
plt.ylabel("acc")
plt.plot(test_acc,label="$acc$")
plt.legend()
plt.show()

执行结果

iris_loss.png

iris_acc.png

完整可执行代码

from sklearn import datasets
import numpy as np
import tensorflow as tf
from matplotlib import pyplot as plt
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
#iris数据集信息
#共150条记录,3个种类,每类各50条记录,每条记录含有四个维度的信息

#数据获取
feature = datasets.load_iris().data
label = datasets.load_iris().target

#数据集乱序
np.random.seed(1024)  #设置随机种子,随机种子相同则生成的随机数据相同
np.random.shuffle(feature)  #用于将对象按第一维度打乱
np.random.seed(1024)
np.random.shuffle(label)

#前120条记录作为训练集
x_train = feature[:-30]
y_train = label[:-30]
#后30条记录作为测试集
x_test = feature[-30:]
y_test = label[-30:]

#前向传播计算需要进行数据类型转化
x_train = tf.cast(x_train,tf.float32)
x_test = tf.cast(x_test,tf.float32)

#将特征和标签进行组合,32条数据分为一批
#注意训练集和测试集不应该有重合
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)

#定义神经网络的结构
#使用单层全连接,四个特征作为输入,三个种类作为输出
w = tf.Variable(tf.random.truncated_normal([4,3] , stddev = 0.1 , seed = 1))
b = tf.Variable(tf.random.truncated_normal([3] , stddev = 0.1 , seed = 1))

#超参数和效果统计变量
lr = 0.1                              #学习率
train_loss_result = [] #记录loss
test_acc = []                   #记录acc
epochs = 5000                   #训练轮数
loss_all = 0

for epoch in range(epochs):                     #每循环一次跑一轮数据集合
    for step,(x_train,y_train) in enumerate(train_db): #每循环一次,跑一个batch的数据
        with tf.GradientTape() as tape:
            y = tf.matmul(x_train,w) + b  #前向传播更新结果
            y = tf.nn.softmax(y)                   #使前向传播结果符合概率分布
            y_ = tf.one_hot(y_train,3)       #标签转化为独热码便于计算
            #采用均方误差作为损失函数
            loss = tf.reduce_mean(tf.square(y_ - y))
            loss_all += loss.numpy() #累加用于求均值
        #计算loss对各个参数的梯度
        grads = tape.gradient(loss,[w,b])
        #根据梯度对参数进行更新
        w.assign_sub(lr * grads[0])
        b.assign_sub(lr * grads[1])
    
    #每训练一代进行参数统计
    #loss统计
    #{}里的字符会被format替换
    print("epoch:{} loss: {}".format(epoch,loss_all/4)) #训练集120条数据,32个为1batch,一代跑4个batch
    train_loss_result.append(loss_all/4)
    loss_all = 0
    
    #acc统计
    total_correct,total_number = 0,0
    for x_test , y_test in test_db:
        y = tf.matmul(x_test,w) + b
        y = tf.nn.softmax(y)
        pred = tf.argmax(y,axis=1)    #返回行最大值,即前向传播得到的预测种类
        pred = tf.cast(pred,dtype=y_test.dtype)
        correct = tf.cast(tf.equal(pred,y_test),dtype=tf.int32)
        correct = tf.reduce_sum(correct)  #统计预测正确的个数
        total_correct += int(correct)
        total_number += x_test.shape[0]
    acc = total_correct / total_number
    test_acc.append(acc)
    print("test acc :{}".format(acc))

#性能统计可视化
#loss
plt.title('loss')
plt.xlabel("epoch")
plt.ylabel("loss")
plt.plot(train_loss_result,label="$loss$")
plt.legend()
plt.show()
#acc
plt.title('acc')
plt.xlabel("epoch")
plt.ylabel("acc")
plt.plot(test_acc,label="$acc$")
plt.legend()
plt.show()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容