tensorflow实现iris分类
內容來自MOOC《人工智能實踐:Tensorflow筆記2》
 八股搭建網絡:我覺得是指按照固定模式搭建神經網絡,八股只是呆板的意思,并不是按照八個步驟搭建。我們抨擊的應該是八股取士制度,而不是八股文。
1.iris數據集
iris數據集:從sklearn包中導入iris數據集;去官網下載http://archive.ics.uci.edu/ml/datasets/Iris/
 特征數:4,sepal length in cm 花萼長,sepal width in cm 花萼寬,petal length in cm 花瓣長,petal width in cm 花瓣寬
 類別數:3,Iris Setosa狗尾鳶尾,Iris Versicolour雜色鳶尾,Iris Virginica弗吉尼亞鳶尾
 這個圖只是為了展示什么是花萼與花瓣,并不是鳶尾花
?
2.實現鳶尾花分類——方一
2.1 步驟
import模塊
 load數據集,打亂數據集順序,將打亂后的數據集分為train與test
 train與test的features與labels配對,并且給出batch大小
 初始化權重與偏置 (神經網絡為全連接, 輸入層:4個神經元,隱藏層:3個神經元,輸出層:3個神經元)
 給出學習率、epoch大小
 訓練
 計算每個epoch的訓練集損失與測試集準確率 進行繪圖
2.2 具體的訓練過程
如120組數據,90組用于訓練,30組用于測試
 batch=30,則訓練集分為3個batch,測試集為1個batch
 epoch=3,進行3次循環
 epoch1
 --train_batch1
 --train_batch2
 --train_batch3
 --test_batch1
 epoch2
 --train_batch1
 --train_batch2
 --train_batch3
 --test_batch1
 epoch3
 --train_batch1
 --train_batch2
 --train_batch3
 --test_batch1
2.3疑問
像train_db、test_db這種BatchDataset類只能通過循環展示或調用?
 反正我目前沒找到其他方法。如果直接輸出print(train_db)是顯示不出內容的。
2.4 代碼
# -*- coding: UTF-8 -*- # 利用鳶尾花數據集,實現前向傳播、反向傳播,可視化loss曲線# 導入所需模塊 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使每次生成的隨機數相同(方便教學,使大家結果都一致,在現實使用時不寫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循環一個batchwith 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和accuracyloss = 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_gradw1.assign_sub(lr * grads[0]) # 參數w1自更新b1.assign_sub(lr * grads[1]) # 參數b自更新# 每個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為測試的總樣本數,將這兩個變量都初始化為0total_correct, total_number = 0, 0for x_test, y_test in test_db:# 使用更新后的參數進行預測y = tf.matmul(x_test, w1) + b1y = 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_numberacc = total_correct / total_numbertest_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$") # 逐點畫出trian_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()?
3.實現鳶尾花分類——方二
3.1 六步法
import
 train, test
 model=tf.keras.models.Sequential
 model.compile
 model.fit
 model.summary
3.2? model=tf.keras.models.Sequential
model=tf.keras.models.Sequential([]) 定義神經層的類型、激活函數類型、正則化類型
 拉直層 tf.keras.layers.Flatten() 將輸入特征拉直變為一維數組
 全連接層 tf.keras.layers.Dense(神經元個數,activation=激活函數, kernel_regularizer=正則化)
 卷積層 tf.keras.layers.Conv2D(filters=卷積核個數,kernel_size=卷積核尺寸, strides=卷積步長,padding="valid" or "same")
 LSTM層 tf.keras.layers.LSTM()
 activation = 'relu', 'softmax', 'sigmoid', 'tanh'
 kernel_regularizer = tf.keras.regularizers.l1(), tf.keras.regularizers.l2()
3.3 model.compile
model.compile(optimizer=優化器,loss=損失函數,metrics=["準確率"])? 定義優化器 損失函數 評測指標
優化器:
 'sgd' or tf.optimizers.SGD(lr=學習率, decay=學習率衰減率, momentum=動量參數)
 'adagrad' or tf.keras.optimizers.Adagrad(lr=學習率, decay=學習率衰減率)
 'adadelta' or tf.keras.optimizers.Adadelta(lr=學習率, decay=學習率衰減率)
 'adam' or tf.keras.optimizers.Adam (lr=學習率, decay=學習率衰減率)
損失函數:
 'mse' or tf.keras.losses.MeanSquaredError()
 'sparse_categorical_crossentropy' or tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False)
 from_logits:原始輸出是否經過概率分布, from_logits=False表示經過概率分布,from_logits=True表示原始輸出
評測指標:
 'accuracy':y_和y 都是數值,如y_=[1] y=[1]。
 'categorical_accuracy':y_和y 是以獨熱碼和概率分布表示。 如y_=[0, 1, 0], y=[0.256, 0.695, 0.048]
 'sparse_ categorical_accuracy':y_和y是以數值和概率分布表示。如y_=[1], y=[0.256, 0.695, 0.048]
3.4 疑問
以下是我百度到的,可能不對
 binary_crossentropy 二分類交叉熵,使用sigmoid激活函數
 categorical_crossentropy 多分類交叉熵,使用softmax激活函數得到輸出的概率分布,y_和y 以獨熱碼和概率分布表示
 sparse_categorical_crossentrop 稀疏多分類交叉熵,使用softmax激活函數得到輸出的概率分布,y_和y是以數值和概率分布表示
3.5 model.fit
進行訓練與測試,定義batch,epoch
 model.fit(訓練集的輸入特征,訓練集的標簽,batch_size= ,epochs= ,validation_data = (測試集的輸入特征,測試集的標簽),validataion_split = 從測試集劃分多少比例給訓練集,validation_freq = 多少次epoch測試一次)
validation_data與validataion_split都是定義測試集,只能選擇一個
3.6 model.summary
model.summary()? 打印網絡結構與參數統計
3.7 代碼
import tensorflow as tf from sklearn import datasets import numpy as npx_train = datasets.load_iris().data y_train = datasets.load_iris().targetnp.random.seed(116) np.random.shuffle(x_train) np.random.seed(116) np.random.shuffle(y_train) tf.random.set_seed(116)model = tf.keras.models.Sequential([tf.keras.layers.Dense(3, activation='softmax', kernel_regularizer=tf.keras.regularizers.l2())])model.compile(optimizer=tf.keras.optimizers.SGD(lr=0.1),loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),metrics=['sparse_categorical_accuracy'])model.fit(x_train, y_train, batch_size=32, epochs=500, validation_split=0.2, validation_freq=20)model.summary()?
4.實現鳶尾花分類——方三
同方二,只是方法三使用繼承自Model的類來定義神經網絡,而方法二使用了Sequential函數來定義神經網絡
4.1? 步驟
class IrisModel(Model):def __init__(self):#定義網絡結構super(IrisModel, self).__init__()self.d1 = Dense(3, activation='sigmoid', kernel_regularizer=tf.keras.regularizers.l2())def call(self, x):#調用網絡結構塊,實現前向傳播y = self.d1(x)return y model = IrisModel()4.2 代碼
import tensorflow as tf from tensorflow.keras.layers import Dense from tensorflow.keras import Model from sklearn import datasets import numpy as npx_train = datasets.load_iris().data y_train = datasets.load_iris().targetnp.random.seed(116) np.random.shuffle(x_train) np.random.seed(116) np.random.shuffle(y_train) tf.random.set_seed(116)class IrisModel(Model):def __init__(self):super(IrisModel, self).__init__()self.d1 = Dense(3, activation='softmax', kernel_regularizer=tf.keras.regularizers.l2())def call(self, x):y = self.d1(x)return ymodel = IrisModel()model.compile(optimizer=tf.keras.optimizers.SGD(lr=0.1),loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),metrics=['sparse_categorical_accuracy'])model.fit(x_train, y_train, batch_size=32, epochs=500, validation_split=0.2, validation_freq=20) model.summary()?
5. 對比
5.1 方二與方三
方二
 model = tf.keras.models.Sequential()
 方三
 定義繼承自tf.keras.Model的irisModel類
 實例化 model = IrisModel()
5.2 三種方法對比
三種方法都調用了tensorflow框架,方一代碼雖多,但展示了神經網絡學習的比較詳細過程。方二 方三進一步使用了封裝好的函數,使得代碼很少,但沒有體現神經網絡學習的比較詳細過程。
當然如果要更詳細的過程,我就不用tensorflow了,使用numpy自己寫代碼。
?
總結
以上是生活随笔為你收集整理的tensorflow实现iris分类的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 多级LC滤波器级联问题
- 下一篇: C语言入门(一)——程序的基本概念
