1. 程式人生 > 實用技巧 >你的第一個神經網路—神經網路實現鳶尾花分類

你的第一個神經網路—神經網路實現鳶尾花分類

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()