from sklearn import datasets import numpy as np import tensorflow as tf import pandas as pd from pandas import DataFrame from sklearn.datasets import load_iris from matplotlib import pyplot as plt x_data=datasets.load_iris().data #獲取iris數據集數據 y_data=datasets.load_iris().target #獲取iris數據標簽 # 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 column:\n',x_data) #隨機打亂數據(因為原始數據是順序的,順序不打亂會影響准確率) #seed:隨機數種子,是一個整數,當設置后,每次生成的隨機數都一樣 np.random.seed(116) 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) #把數據集分批次,每個批次batch組數據 #from_tensor_sices函數使輸入特征和標簽值一一對應 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.Vairable()標記參數可訓練 #使用seed使每次生成的隨機數相同 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 train_loss_results=[] #將每次的loss記錄在此列表中,為后續畫loss曲線提供依據 test_acc=[] #將每次的精確率記錄在此列表中,為后續畫acc曲線提供依據 epoch=500 #循環500次 loss_all=0 #每輪分為4個step,loss_all記錄4個step生成的4個loss的和 #訓練部分 for epoch in range(epoch): #大循環,循環一次數據集 for step,(x_train,y_train) in enumerate(train_db): #小循環,循環取一個batch(32個數據集) with tf.GradientTape() as tape: #with結構記錄梯度信息 y=tf.matmul(x_train,w1)+b1 #神經網絡記錄乘加運算 y=tf.nn.softmax(y) #使y滿足概率分布 y_=tf.one_hot(y_train,depth=3) #3分類 loss=tf.reduce_mean(tf.square(y_-y)) #預測值-真實值 loss_all+=loss.numpy() #求導 grads=tape.gradient(loss,[w1,b1]) #梯度自更新 w1=w1-lr*w1_grad b1=b1-lr*b1_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) loss_all=0 total_corret,total_number=0,0 for x_test,y_test in test_db: y=tf.matmul(x_test,w1)+b1 y=tf.nn.softmax(y) predict=tf.argmax(y,axis=1) #返回y中最大值的索引,即預測的分類 predict=tf.cast(predict,dtype=y_test.dtype) correct=tf.cast(tf.equal(predict,y_test),dtype=tf.int32) correct=tf.reduce_sum(correct) #將每個batch中的correct數加起來 total_corret+=int(correct) total_number+=x_test.shape[0] #x_test.shape[0]代表樣本個數 acc=total_corret/total_number test_acc.append(acc) print('test_acc:',acc) print('------------------') #繪制loss曲線 plt.title('loss function curve') plt.xlabel('epoch') plt.ylabel('loss') plt.plot(train_loss_results,label='$loss$') plt.legend() plt.show() #繪制acc曲線 plt.title('acc curve') plt.xlabel('epoch') plt.ylabel('loss') plt.plot(test_acc,label='$accuracy$') plt.legend() plt.show()