from sklearn import datasets
from pandas import DataFrame
import pandas as pd
x_data = datasets.load_iris().data #.data返回iris数据集中所有输入特征
y_data = datasets.load_iris().target
print("x_data from datasets:\n",x_data)
print("y_data from datasets:\n",y_data)
x_data = DataFrame(x_data,columns=['花萼长度','花萼宽度','花瓣长度','花瓣宽度'])
#为表格增加行索引(左侧)和列标签(上方)
pd.set_option('display.unicode.east_asian_width',True) #设置列名对齐
print("x_data add index:\n",x_data)
x_data['类别'] = y_data
print("x_data add s column:\n",x_data)
x_data from datasets:
[[5.1 3.5 1.4 0.2]
[4.9 3. 1.4 0.2]
[4.7 3.2 1.3 0.2]
[4.6 3.1 1.5 0.2]
[5. 3.6 1.4 0.2]
[5.4 3.9 1.7 0.4]
[4.6 3.4 1.4 0.3]
[5. 3.4 1.5 0.2]
[4.4 2.9 1.4 0.2]
[4.9 3.1 1.5 0.1]
[5.4 3.7 1.5 0.2]
[4.8 3.4 1.6 0.2]
[4.8 3. 1.4 0.1]
[4.3 3. 1.1 0.1]
[5.8 4. 1.2 0.2]
[5.7 4.4 1.5 0.4]
[5.4 3.9 1.3 0.4]
[5.1 3.5 1.4 0.3]
[5.7 3.8 1.7 0.3]
[5.1 3.8 1.5 0.3]
[5.4 3.4 1.7 0.2]
[5.1 3.7 1.5 0.4]
[4.6 3.6 1. 0.2]
[5.1 3.3 1.7 0.5]
[4.8 3.4 1.9 0.2]
[5. 3. 1.6 0.2]
[5. 3.4 1.6 0.4]
[5.2 3.5 1.5 0.2]
[5.2 3.4 1.4 0.2]
[4.7 3.2 1.6 0.2]
[4.8 3.1 1.6 0.2]
[5.4 3.4 1.5 0.4]
[5.2 4.1 1.5 0.1]
[5.5 4.2 1.4 0.2]
[4.9 3.1 1.5 0.2]
[5. 3.2 1.2 0.2]
[5.5 3.5 1.3 0.2]
[4.9 3.6 1.4 0.1]
[4.4 3. 1.3 0.2]
[5.1 3.4 1.5 0.2]
[5. 3.5 1.3 0.3]
[4.5 2.3 1.3 0.3]
[4.4 3.2 1.3 0.2]
[5. 3.5 1.6 0.6]
[5.1 3.8 1.9 0.4]
[4.8 3. 1.4 0.3]
[5.1 3.8 1.6 0.2]
[4.6 3.2 1.4 0.2]
[5.3 3.7 1.5 0.2]
[5. 3.3 1.4 0.2]
[7. 3.2 4.7 1.4]
[6.4 3.2 4.5 1.5]
[6.9 3.1 4.9 1.5]
[5.5 2.3 4. 1.3]
[6.5 2.8 4.6 1.5]
[5.7 2.8 4.5 1.3]
[6.3 3.3 4.7 1.6]
[4.9 2.4 3.3 1. ]
[6.6 2.9 4.6 1.3]
[5.2 2.7 3.9 1.4]
[5. 2. 3.5 1. ]
[5.9 3. 4.2 1.5]
[6. 2.2 4. 1. ]
[6.1 2.9 4.7 1.4]
[5.6 2.9 3.6 1.3]
[6.7 3.1 4.4 1.4]
[5.6 3. 4.5 1.5]
[5.8 2.7 4.1 1. ]
[6.2 2.2 4.5 1.5]
[5.6 2.5 3.9 1.1]
[5.9 3.2 4.8 1.8]
[6.1 2.8 4. 1.3]
[6.3 2.5 4.9 1.5]
[6.1 2.8 4.7 1.2]
[6.4 2.9 4.3 1.3]
[6.6 3. 4.4 1.4]
[6.8 2.8 4.8 1.4]
[6.7 3. 5. 1.7]
[6. 2.9 4.5 1.5]
[5.7 2.6 3.5 1. ]
[5.5 2.4 3.8 1.1]
[5.5 2.4 3.7 1. ]
[5.8 2.7 3.9 1.2]
[6. 2.7 5.1 1.6]
[5.4 3. 4.5 1.5]
[6. 3.4 4.5 1.6]
[6.7 3.1 4.7 1.5]
[6.3 2.3 4.4 1.3]
[5.6 3. 4.1 1.3]
[5.5 2.5 4. 1.3]
[5.5 2.6 4.4 1.2]
[6.1 3. 4.6 1.4]
[5.8 2.6 4. 1.2]
[5. 2.3 3.3 1. ]
[5.6 2.7 4.2 1.3]
[5.7 3. 4.2 1.2]
[5.7 2.9 4.2 1.3]
[6.2 2.9 4.3 1.3]
[5.1 2.5 3. 1.1]
[5.7 2.8 4.1 1.3]
[6.3 3.3 6. 2.5]
[5.8 2.7 5.1 1.9]
[7.1 3. 5.9 2.1]
[6.3 2.9 5.6 1.8]
[6.5 3. 5.8 2.2]
[7.6 3. 6.6 2.1]
[4.9 2.5 4.5 1.7]
[7.3 2.9 6.3 1.8]
[6.7 2.5 5.8 1.8]
[7.2 3.6 6.1 2.5]
[6.5 3.2 5.1 2. ]
[6.4 2.7 5.3 1.9]
[6.8 3. 5.5 2.1]
[5.7 2.5 5. 2. ]
[5.8 2.8 5.1 2.4]
[6.4 3.2 5.3 2.3]
[6.5 3. 5.5 1.8]
[7.7 3.8 6.7 2.2]
[7.7 2.6 6.9 2.3]
[6. 2.2 5. 1.5]
[6.9 3.2 5.7 2.3]
[5.6 2.8 4.9 2. ]
[7.7 2.8 6.7 2. ]
[6.3 2.7 4.9 1.8]
[6.7 3.3 5.7 2.1]
[7.2 3.2 6. 1.8]
[6.2 2.8 4.8 1.8]
[6.1 3. 4.9 1.8]
[6.4 2.8 5.6 2.1]
[7.2 3. 5.8 1.6]
[7.4 2.8 6.1 1.9]
[7.9 3.8 6.4 2. ]
[6.4 2.8 5.6 2.2]
[6.3 2.8 5.1 1.5]
[6.1 2.6 5.6 1.4]
[7.7 3. 6.1 2.3]
[6.3 3.4 5.6 2.4]
[6.4 3.1 5.5 1.8]
[6. 3. 4.8 1.8]
[6.9 3.1 5.4 2.1]
[6.7 3.1 5.6 2.4]
[6.9 3.1 5.1 2.3]
[5.8 2.7 5.1 1.9]
[6.8 3.2 5.9 2.3]
[6.7 3.3 5.7 2.5]
[6.7 3. 5.2 2.3]
[6.3 2.5 5. 1.9]
[6.5 3. 5.2 2. ]
[6.2 3.4 5.4 2.3]
[5.9 3. 5.1 1.8]]
y_data from datasets:
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2]
x_data add index:
花萼长度 花萼宽度 花瓣长度 花瓣宽度
0 5.1 3.5 1.4 0.2
1 4.9 3.0 1.4 0.2
2 4.7 3.2 1.3 0.2
3 4.6 3.1 1.5 0.2
4 5.0 3.6 1.4 0.2
.. ... ... ... ...
145 6.7 3.0 5.2 2.3
146 6.3 2.5 5.0 1.9
147 6.5 3.0 5.2 2.0
148 6.2 3.4 5.4 2.3
149 5.9 3.0 5.1 1.8
[150 rows x 4 columns]
x_data add s column:
花萼长度 花萼宽度 花瓣长度 花瓣宽度 类别
0 5.1 3.5 1.4 0.2 0
1 4.9 3.0 1.4 0.2 0
2 4.7 3.2 1.3 0.2 0
3 4.6 3.1 1.5 0.2 0
4 5.0 3.6 1.4 0.2 0
.. ... ... ... ... ...
145 6.7 3.0 5.2 2.3 2
146 6.3 2.5 5.0 1.9 2
147 6.5 3.0 5.2 2.0 2
148 6.2 3.4 5.4 2.3 2
149 5.9 3.0 5.1 1.8 2
[150 rows x 5 columns]
np.random.seed()的作用
seed( ) 用于指定随机数生成时所用算法开始的整数值。
1.如果使用相同的seed( )值,则每次生成的随即数都相同;
2.如果不设置这个值,则系统根据时间来自己选择这个值,生成自己的种子,此时每次生成的随机数因时间差异而不同。随机数种子的参数怎么选择?这个参数只是确定一下随机数的起始位置,可随意分配。
np.random.shuffle(x_data)x_data是一个张量,该函数用于将x_data自身打乱,注意是在原数组上进行的,不是返回一个新数组,而原张量不变。
tf.random.set_seed(116)
图级种子:tf.set_random_seed
如果不想一个一个的设置随机种子seed,那么可以使用全局设置tf.set_random_seed()函数,使用之后后面设置的随机数都不需要设置seed,而可以跨会话生成相同的随机数。
# 将打乱后的数据集分割为训练集和测试集,训练集为前120行,测试集为后30行
x_train = x_data[:-30]
y_train = y_data[:-30]
x_test = x_data[-30:]
y_test = y_data[-30:]首先,对x_data[:-30]里面参数的理解,数据集一共有150行,每一行都有特征和标签,将这150行数据集标记为0行,1行,2行,3行,4行......149行
[:-30]相当于从第0行开始算,到第-30行结束,-30行是这样理解的,数据集正向数是0,10,2,3...149,倒着数从右向左数 -150 .......-3,-2,-1
[:-30] 取数据集的前120行,是这样做到的:
我所理解的[:-30],冒号前的数字代表取数据的起始位置,冒号后的数字代表取数据的结束位置。
正着取数据时,从0开始,倒着取数据时,从-1开始
[-30:],代表从-30开始,到-1结束。
#导入模块
import tensorflow as tf
from sklearn import datasets
from matplotlib import pyplot as plt
import numpy as np
#导入数据集
x_data = datasets.load_iris().data
y_data = datasets.load_iris().target
#随机打乱数据(因为原始数据时顺序的,人类所处的世界就是乱序的,数据的顺序不打乱会影响准确率)
#seed:随机数种子,是一个整数,当设置之后,每次生成的随机数都一样
np.random.seed(116) #使用相同的seed,保证输入特征和标签一一对应
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:]
#转换x的数据类型,否则后面矩阵相乘时会因数据类型不一致报错
x_train = tf.cast(x_train,tf.float32)
x_test = tf.cast(x_test,tf.float32)
#from_tensor_slices 函数使输入特征和标签值一一对应。把数据集分批次,每个批次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)
#生成神经网络的参数,4个输入特征,所以输入层为4给输入节点;因为最后分为3类,所以输出层为3个神经元
#用tf.Variable()标记参数可训练
#使用seed使每次生成的随机数相同
w1 = tf.Variable(tf.random.truncated_normal([4,3],stddev=0.1,seed=1))#w1为4行3列
b1 = tf.Variable(tf.random.truncated_normal([3],stddev=0.1,seed=1)) #误差维度必须与w1的列数一致,为3
lr = 0.1 #学习率为0.1
train_loss_results = []
#将每轮的loss记录在此列表中,为后续画loss曲线提供数据
test_acc = []
#将每轮的acc记录在此列表中,为后续画acc曲线提供数据
epoch = 500
#循环500轮
loss_all = 0
#每轮分4个step,loss_all记录四个step生成的4个loss的和
#训练部分
for epoch in range(epoch): #数据集循环,每个epoch循环一次数据集
for step,(x_train,y_train) in enumerate(train_db): #batch级别的循环,每个step循环一个batch
with tf.GradientTape() as tape:#with结构记录梯度信息
y = tf.matmul(x_train,w1) + b1 #神经网络乘加运算
y = tf.nn.softmax(y)#使输出y符合概率分布(此操作后与独热码同量级,可相减求loss)
y_ = tf.one_hot(y_train,depth=3)#将标签值转换为独热码格式,方便计算loss和accuracy
loss = tf.reduce_mean(tf.square(y_ - y)) #采用俊芳误差损失函数 mse = mean(sum(y-out)^2)
loss_all += loss.numpy()
#将每个step计算出的loss累加,为后续求loss平均值提供数据,这样计算的loss更准确
#计算loss对各个参数的梯度
grads = tape.gradient(loss,[w1,b1])
#实现梯度更新 w1 = w1-lr*w1_grad b = b-lr*b_grad
w1.assign_sub(lr*grads[0])
b1.assign_sub(lr*grads[1])
#每个epoch,打印loss信息
print("Epoch {}, loss:{}".format(epoch, loss_all/4))
train_loss_results.append(loss_all/4)#将4个step的loss求平均记录在此变量值
loss_all = 0#loss_all归零,为记录下一个epoch的loss做准备
#测试部分
#total_correct为预测对的样本个数,total_number为测试的总样本数,将这两个变量都初始化为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)#返回y中最大值的索引,即预测的分类
#将pred转换为y_test的数据类型
pred = tf.cast(pred,dtype=y_test.dtype)
#若分类正确,则correct=1,否则为0,将bool型的结果转换为int型
correct = tf.cast(tf.equal(pred,y_test),dtype=tf.int32)
#将每个batch的correct数加起来
correct = tf.reduce_sum(correct)
#将所有batch中的correct数加起来
total_correct += int(correct)
#total_number 为测试的总样本数,也就是x_test的行数,shape[0]返回变量的行数
total_number += x_test.shape[0]
#总的准确率等于total_correct/total_number
acc = total_correct / total_number
test_acc.append(acc)
print("Test_acc:",acc)
#绘制loss曲线
plt.title('Loss Function Curve')#图片的标题
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.plot(train_loss_results,label="$Loss$")
plt.legend()#画出曲线图标
plt.show()#画出图像
#绘制Accuracy曲线
plt.title('Acc Curve')
plt.xlabel('Epoch')
plt.ylabel('Acc')
plt.plot(test_acc,label="$Accuracy$")
plt.legend()
plt.show()