数据集获取
- 安装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()