TensorFlow实现鸢尾花分类

sherry颖 2020-05-31

准备数据

  • 数据集读入
  • 数据集乱序
  • 生成训练集和测试集
  • 特征和标签配对,每次读入一小撮(batch)

搭建网络

  • 定义神经网络中所有可训练参数

参数优化

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

测试效果

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

acc/loss可视化


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

x_data = datasets.load_iris().data # 返回iris的输入特征
y_data = datasets.load_iris().target # 返回iris的标签
# 打乱数据集
np.random.seed(20) # 使用相同的seed,使得输入特征、标签一一对应
np.random.shuffle(x_data)
np.random.seed(20)
np.random.shuffle(y_data)
tf.random.set_seed(20)
# 划分数据集
x_train = x_data[:-30]
y_train = y_data[:-30]
x_test = x_data[-30:]
y_test = y_data[-30:]
# 转换数据集内容的格式
x_train = tf.cast(x_train,tf.float32)
x_test = tf.cast(x_test,tf.float32)

# 使用form_tensor_slices使得特征和标签配对,每32个打包为一个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)

# 定义神经网络中所有可训练的参数
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))

epoch = 1000 # 对整个训练集的训练次数
loss_all = 0 # 每个epoch的整体损失
train_loss_results = [] # 训练损失结果列表,用来画图
test_acc = [] # 每一个epoch后测试时的acc列表
lr = 0.1 # 学习率

for epoch in range(epoch): 
    for step,(x_train,y_train) in enumerate(train_db): # 对打包的训练集进行batch训练
        with tf.GradientTape() as tape: # 记录计算过程
            y = tf.matmul(x_train,w1) + b1 # 计算
            y = tf.nn.softmax(y) # softmax符合概率
            y_ = tf.one_hot(y_train,depth = 3) # 对训练集的标签进行one_hot编码
            loss = tf.reduce_mean(tf.square(y_ - y)) # 计算损失
            loss_all += loss.numpy() # 累加每个batch损失

        grads = tape.gradient(loss,[w1,b1]) # 对loss中的w1,b1进行求导
        w1.assign_sub(lr*grads[0]) # 更新w1
        b1.assign_sub(lr*grads[1]) # 更新w2

    print("Epoch:{},loss:{}".format(epoch,loss_all/4)) # 平均损失 120组,一个批次32,打印的每个批次的平均损失
    train_loss_results.append(loss_all/4) # 加入训练损失列表,方便画图
    loss_all = 0 # 重置此epoch的损失

    total_correct,total_number = 0,0
    for x_test,y_test in test_db: # 遍历测试集中的batch
        y = tf.matmul(x_test,w1) + b1 # 预测
        y = tf.nn.softmax(y) # 符合概率
        pred = tf.argmax(y,axis = 1) # 取出行中最大值的索引,也就是取出其中概率最大的索引
        pred = tf.cast(pred,dtype=y_test.dtype) # 转换到y_test的类型

        correct = tf.cast(tf.equal(pred,y_test),dtype=tf.int32) # 判断与测试集的标签是否相等并且转换bool为int型
        correct = tf.reduce_sum(correct) # 沿着指定维度的和,不指定axis则默认为所有元素的和
        total_correct += int(correct) # 对每个batch的correct相加
        total_number += x_test.shape[0] # 算测试集总数
    acc = total_correct/total_number # 计算准确率
    test_acc.append(acc) # 计算每epoch的总数

    print("test_acc:",acc)
    print("----------------------")

plt.figure("figure1")
plt.title("Loss Function Curce")
plt.xlabel("Epoch")
plt.ylabel("Loss")
plt.plot(train_loss_results,label="$Loss$")
plt.legend() # 显示图例
plt.show
print("-------------")
plt.figure("figure2")
plt.title(‘Acc Curce‘)
plt.xlabel(‘Epoch‘)
plt.ylabel(‘Acc‘)
plt.plot(test_acc,label="$Accuracy$")
plt.legend()
plt.show()

相关推荐