tensorflow2.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)
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的數據類型,否則後界矩陣相乘會因數據類型不一樣報錯
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))
b1 = tf.Variable(tf.random.truncated_normal([3],stddev=0.1,seed=1))

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符合概率分佈(此操作後與獨熱編碼同量級)
            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更準確
        grads = tape.gradient(loss,[w1,b1])  #對loss函數進行求梯度
        w1.assign_sub(lr * grads[0])  #參數w1自更新
        b1.assign_sub(lr * grads[1])  #參數b1自更新
    print("Epoch {},loss: {}".format(epoch,loss_all/4))  #每個epoch,打印loss信息
    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 = tf.cast(pred,dtype=y_test.dtype)  #將pred轉換爲y_test的數據類型
        correct = tf.cast(tf.equal(pred,y_test),dtype=tf.int32)  #若分類正確,則correct=1,否則correct=0,將bool型的結果轉換爲int型
        correct = tf.reduce_sum(correct)  #將每個batch的correct數加起來
        total_correct += int(correct)  #將所有batch的correct數加起來
        total_number += x_test.shape[0]  #total_number爲測試的總樣本數,也就是x_test的行數,shape[0]返回變量的行數
    acc = total_correct / total_number  #總的正確率等於total_correct / total_number
    test_acc.append(acc)
    print("Test_acc",acc)
    print("--------------------")

# 繪製loss曲線
plt.title('loss Function Curve')  #圖片標題
plt.xlabel('epoch')  #x軸變量名稱
plt.ylabel('loss')  #y軸變量名稱
plt.plot(train_loss_results,label="$Loss$")  #逐點畫出train_loss_results值並連線,連接圖標是loss
plt.legend()  #畫出曲線座標
plt.show()  #畫出圖像

#繪製Accuracy曲線
plt.title('Acc Curve')  #圖片標題
plt.xlabel('epoch')  #x軸變量名稱
plt.ylabel('Acc')  #y軸變量名稱
plt.plot(test_acc,label="$Accuracy$")  #逐點畫出test_acc值並連線,連接圖標是Accuracy
plt.legend()  
plt.show()
下面的是筆者的微信公衆號,歡迎關注,會持續更新c++、python、tensorflow、機器學習、深度學習等系列文章

                      在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章