参考:b站的课程,北京大学的Tensorflow 2 课程
鸢尾花数据集:
150组数据,特征数量为4,分别为:花萼长、花萼宽、花瓣长、花瓣宽
标签为3:,分别为0,1,2,代表:狗尾鸢尾、杂色鸢尾、弗吉尼亚鸢尾
该数据集存在sklearn中,可以直接导入使用
程序步骤:
1 准备数据。包括:数据读入、数据乱序、将数据配成特征和标签对,生成train和test永不相见的测试集和训练集
2 搭建网络:定义神经网络中所有可训练参数。(用tf.Variable函数,可参考tensorflow笔记1)
3 优化参数:利用嵌套循环,在with结构中求得损失函数loss;对每个参数求偏导,更改这些可训练参数,同时求算每一次迭代的loss值和acc值,存于两个列表中,并绘制loss和acc曲线。
代码为:
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
from sklearn import datasets
#读取数据
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)
#分出训练集和测试集
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)
#特征数据与标签配对
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))
#参数设计
lr=0.1#定义学习率
epoch=500
loss_all=0
train_loss_results=[]
test_acc=[]
#循环迭代,更新参数,显示loss
for epoch in range(epoch):
#训练
for step,(x_train,y_train) in enumerate(train_db):
with tf.GradientTape() as tape:
# 前向传播
y = tf.matmul(x_train, w1) + b1
y = tf.nn.softmax(y)
y_ = tf.one_hot(y_train, depth=3) # 进行one_hot编码
# 反向传播
loss=tf.reduce_mean(tf.square(y_-y))
loss_all+=loss.numpy()
grads=tape.gradient(loss,[w1,b1])
w1.assign_sub(lr*grads[0])
b1.assign_sub(lr*grads[1])
print("第{}轮,loss为{}".format(epoch,loss_all/4))
train_loss_results.append(loss_all/4)
loss_all=0
#测试
total_correct,total_number=0,0
for x_test,y_test in test_db:
#前向传播
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)
correct=tf.cast(tf.equal(pred,y_test),tf.int32)
correct=tf.reduce_sum(correct)
total_correct+=int(correct)
total_number+=x_test.shape[0]
acc=total_correct/total_number
print("准确率为:{}".format(acc))
print("---------------")
test_acc.append(acc)
#绘制曲线
#loss曲线
plt.figure(figsize=(5,4))
plt.plot(train_loss_results)
plt.xlabel("epoch")
plt.ylabel("Loss")
plt.title("Loss")
#准确率曲线
plt.figure(figsize=(5,4))
plt.plot(test_acc)
plt.xlabel("epoch")
plt.ylabel("acc")
plt.title("acc")
plt.show()
整体效果如下:
迭代过程中的数据显示:
Loss曲线:
acc曲线
再将学习率调大,看看会有什么效果?
说明,参数配置的不合理会使模型变得极其不准确