python 使用Tensorflow訓練BP神經網絡實現鳶尾花分類
Hello,兄弟們,開始搞深度學習了,今天出第一篇博客,小白一枚,如果發現錯誤請及時指正,萬分感謝。
使用軟件Python 3.8,Tensorflow2.0
問題描述鳶尾花主要分為狗尾草鳶尾(0)、雜色鳶尾(1)、弗吉尼亞鳶尾(2)。人們發現通過計算鳶尾花的花萼長、花萼寬、花瓣長、花瓣寬可以將鳶尾花分類。所以只要給出足夠多的鳶尾花花萼、花瓣數據,以及對應種類,使用合適的神經網絡訓練,就可以實現鳶尾花分類。
搭建神經網絡輸入數據是花萼長、花萼寬、花瓣長、花瓣寬,是n行四列的矩陣。而輸出的是每個種類的概率,是n行三列的矩陣。我們采用BP神經網絡,設X為輸入數據,Y為輸出數據,W為權重,B偏置。有
y=x∗w+b
因為x為n行四列的矩陣,y為n行三列的矩陣,所以w必須為四行三列的矩陣,每個神經元對應一個b,所以b為一行三列的的矩陣。神經網絡如下圖。
所以,只要找到合適的w和b,就能準確判斷鳶尾花的種類。下面就開始對這兩個參數進行訓練。
訓練參數損失函數損失函數表達的是預測值(y*)和真實值(y)的差距,我們采用均方誤差公式作為損失函數。
損失函數值越小,說明預測值和真實值越接近,w和b就越合適。如果人來一組一組試,那肯定是不行的。所以我們采用梯度下降算法來找到損失函數最小值。梯度:對函數求偏導的向量。梯度下降的方向就是函數減少的方向。
其中a為學習率,即梯度下降的步長,如果a太大,就可能錯過最優值,如果a太小,則就需要更多步才能找到最優值。所以選擇合適的學習率很關鍵。
通過反向傳播來優化參數。反向傳播:從后向前,逐層求損失函數對每層神經元參數的偏導數,迭代更新所有參數。比如
可以看到w會逐漸趨向于loss的最小值0。以上就是我們訓練的全部關鍵點。
代碼數據集我們使用sklearn包提供的鳶尾花數據集。共150組數據。打亂保證數據的隨機性,取前120個為訓練集,后30個為測試集。
# 導入數據,分別為輸入特征和標簽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()標記參數可訓練w1 = tf.Variable(tf.random.truncated_normal([4, 3], stddev=0.1)) # 四行三列,方差為0.1b1 = tf.Variable(tf.random.truncated_normal([3], stddev=0.1)) # 一行三列,方差為0.1訓練
a = 0.1 # 學習率為0.1epoch = 500 # 循環500輪# 訓練部分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符合概率分布 y_ = tf.one_hot(y_train, depth=3) # 將標簽值轉換為獨熱碼格式,方便計算loss loss = tf.reduce_mean(tf.square(y_ - y)) # 采用均方誤差損失函數mse = mean(sum(y-y*)^2)# 計算loss對w, b的梯度grads = tape.gradient(loss, [w1, b1])# 實現梯度更新 w1 = w1 - lr * w1_grad b = b - lr * b_gradw1.assign_sub(a * grads[0]) # 參數w1自更新b1.assign_sub(a * grads[1]) # 參數b自更新測試
# 測試部分total_correct, total_number = 0, 0for 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轉換為y_test的數據類型 predict = tf.cast(predict, dtype=y_test.dtype) # 若分類正確,則correct=1,否則為0,將bool型的結果轉換為int型 correct = tf.cast(tf.equal(predict, 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_numberprint('測試準確率 = %.2f %%' % (acc * 100.0))my_test = np.array([[5.9, 3.0, 5.1, 1.8]])print('輸入 5.9 3.0 5.1 1.8')my_test = tf.convert_to_tensor(my_test)my_test = tf.cast(my_test, tf.float32)y = tf.matmul(my_test, w1) + b1y = tf.nn.softmax(y)species = {0: '狗尾鳶尾', 1: '雜色鳶尾', 2: '弗吉尼亞鳶尾'}predict = np.array(tf.argmax(y, axis=1))[0] # 返回y中最大值的索引,即預測的分類print('該鳶尾花為:' + species.get(predict))
結果:
以上就是全部內容,鳶尾花分類作為經典案例,應該重點掌握理解。有一起學習的伙伴可以把想法打在評論區,大家多多交流,我也會及時回復的!
以上就是python 使用Tensorflow訓練BP神經網絡實現鳶尾花分類的詳細內容,更多關于python 訓練BP神經網絡實現鳶尾花分類的資料請關注好吧啦網其它相關文章!
相關文章:
