bp神經網路 人工智慧
阿新 • • 發佈:2022-03-18
一、用BP神經網路算y=x1^2+x2^2
import numpy as np import scipy.special import pylab
import pandas as pd import numpy as np import matplotlib.pyplot as plt
def sigmoid(x): # 定義網路啟用函式 return 1/(1+np.exp(-x))
data_tr = pd.read_csv(r'D:\20信計大學學習\人工智慧\3.3 data_tr.txt') # 訓練集樣本 data_te = pd.read_csv(r'D:\20信計大學學習\人工智慧\3.3 data_te.txt') # 測試集樣本 n = len(data_tr) yita = 0.85
out_in = np.array([0, 0, 0, 0, -1]) # 輸出層的輸入,即隱層的輸出 w_mid = np.zeros([3,4]) # 隱層神經元的權值&閾值 w_out = np.zeros([5]) # 輸出層神經元的權值&閾值
delta_w_out = np.zeros([5]) # 輸出層權值&閾值的修正量 delta_w_mid = np.zeros([3,4]) # 中間層權值&閾值的修正量 Err = []
''' 模型訓練 ''' for j in range(1000): error = [] for it in range(n): #訓練集有n條記錄 net_in = np.array([data_tr.iloc[it, 0], data_tr.iloc[it, 1], -1]) # 網路輸入 real = data_tr.iloc[it, 2] #第it行第2列的值,也就是此記錄的真實值 for i in range(4): out_in[i] = sigmoid(sum(net_in * w_mid[:, i])) # 從輸入到隱層的傳輸過程 res = sigmoid(sum(out_in * w_out)) # 預測值 error.append(abs(real-res))#第一條記錄的誤差 # print(it, '個樣本的模型輸出:', res, 'real:', real) delta_w_out = yita*res*(1-res)*(real-res)*out_in # 輸出層權值的修正量 delta_w_out[4] = -yita*res*(1-res)*(real-res) # 輸出層閾值的修正量 w_out = w_out + delta_w_out # 更新,加上修正量 for i in range(4): delta_w_mid[:, i] = yita*out_in[i]*(1-out_in[i])*w_out[i]*res*(1-res)*(real-res)*net_in # 中間層神經元的權值修正量 delta_w_mid[2, i] = -yita*out_in[i]*(1-out_in[i])*w_out[i]*res*(1-res)*(real-res) # 中間層神經元的閾值修正量,第2行是閾值 w_mid = w_mid + delta_w_mid # 更新,加上修正量 # error=[error1,error2,...,error500] np.mean(error):500條記錄的平均誤差 Err.append(np.mean(error)) print(w_mid,w_out) plt.plot(Err)#訓練集上每一輪的平均誤差,對訓練集進行1000輪訓練 plt.show() plt.close()
''' 將測試集樣本放入訓練好的網路中去 ''' error_te = [] score=[] m=len(data_te) for it in range(m): #測試集有m條記錄 net_in = np.array([data_te.iloc[it, 0], data_te.iloc[it, 1], -1]) # 網路輸入 real = data_te.iloc[it, 2] for i in range(4): out_in[i] = sigmoid(sum(net_in * w_mid[:, i])) # 從輸入到隱層的傳輸過程 res = sigmoid(sum(out_in * w_out)) # 模型預測值 error_te.append(abs(real-res)) if(abs(real-res)<0.1718): score.append(1) else: score.append(0) score_array = np.asfarray(score) print("測試集進行1輪測試的正確率是:",(score_array.sum()/score_array.size)*100,'%') plt.plot(error_te)#測試集上每一輪的誤差 plt.show() err2=np.mean(error_te)
二、手工搭建神經網路
import numpy as np import scipy.special import pylab import matplotlib.pyplot as plt #%% class NeuralNetwork(): # 初始化神經網路 def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate): # 設定輸入層節點,隱藏層節點和輸出層節點的數量和學習率 self.inodes = inputnodes self.hnodes = hiddennodes self.onodes = outputnodes self.lr = learningrate #設定神經網路中的學習率 # 使用正態分佈,進行權重矩陣的初始化 self.wih = np.random.normal(0.0, pow(self.hnodes, -0.5), (self.hnodes, self.inodes)) #(mu,sigma,矩陣) self.who = np.random.normal(0.0, pow(self.onodes, -0.5), (self.onodes, self.hnodes)) self.activation_function = lambda x: scipy.special.expit(x) #啟用函式設為Sigmod()函式 pass # 定義訓練神經網路 print("************Train start******************") def train(self,input_list,target_list): # 將輸入、輸出列表轉換為二維陣列 inputs = np.array(input_list, ndmin=2).T #T:轉置 targets = np.array(target_list,ndmin= 2).T hidden_inputs = np.dot(self.wih, inputs) #計算到隱藏層的訊號,dot()返回的是兩個陣列的點積 hidden_outputs = self.activation_function(hidden_inputs) #計算隱藏層輸出的訊號 final_inputs = np.dot(self.who, hidden_outputs) #計算到輸出層的訊號 final_outputs = self.activation_function(final_inputs) output_errors = targets - final_outputs #計算輸出值與標籤值的差值 #print("*****************************") #print("output_errors:",output_errors) hidden_errors = np.dot(self.who.T,output_errors) #隱藏層和輸出層權重更新 self.who += self.lr * np.dot((output_errors*final_outputs*(1.0-final_outputs)), np.transpose(hidden_outputs))#transpose()轉置 #輸入層和隱藏層權重更新 self.wih += self.lr * np.dot((hidden_errors*hidden_outputs*(1.0-hidden_outputs)), np.transpose(inputs))#轉置 pass #查詢神經網路 def query(self, input_list): # 轉換輸入列表到二維數 inputs = np.array(input_list, ndmin=2).T #計算到隱藏層的訊號 hidden_inputs = np.dot(self.wih, inputs) #計算隱藏層輸出的訊號 hidden_outputs = self.activation_function(hidden_inputs) #計算到輸出層的訊號 final_inputs = np.dot(self.who, hidden_outputs) final_outputs = self.activation_function(final_inputs) return final_outputs #%% input_nodes = 784 #輸入層神經元個數 hidden_nodes = 100 #隱藏層神經元個數 output_nodes = 10 #輸出層神經元個數 learning_rate = 0.3 #學習率為0.3 # 建立神經網路 n = NeuralNetwork(input_nodes, hidden_nodes, output_nodes, learning_rate) #%% #讀取訓練資料集 轉化為列表 training_data_file = open(r"D:\20信計大學學習\人工智慧\mnist_train.csv",'r') training_data_list = training_data_file.readlines() #方法用於讀取所有行,並返回列表 #print("training_data_list:",training_data_list) training_data_file.close() #%% #訓練次數 i = 2 for e in range(i): #訓練神經網路 for record in training_data_list: all_values = record.split(',') #根據逗號,將文字資料進行拆分 #將文字字串轉化為實數,並建立這些數字的陣列。 inputs = (np.asfarray(all_values[1:])/255.0 * 0.99) + 0.01 #建立用零填充的陣列,陣列的長度為output_nodes,加0.01解決了0輸入造成的問題 targets = np.zeros(output_nodes) + 0.01 #10個元素都為0.01的陣列 #使用目標標籤,將正確元素設定為0.99 targets[int(all_values[0])] = 0.99#all_values[0]=='8' n.train(inputs,targets) pass pass #%% test_data_file = open(r"D:\20信計大學學習\人工智慧\mnist_test.csv",'r') test_data_list = test_data_file.readlines() test_data_file.close() all_values = test_data_list[2].split(',') #第3條資料,首元素為1 # print(all_values) # print(len(all_values)) # print(all_values[0]) #輸出目標值 #%% score = [] print("***************Test start!**********************") for record in test_data_list: #用逗號分割將資料進行拆分 all_values = record.split(',') #正確的答案是第一個值 correct_values = int(all_values[0]) # print(correct_values,"是正確的期望值") #做輸入 inputs = (np.asfarray(all_values[1:])/255.0 * 0.99) + 0.01 #測試網路 作輸入 outputs= n.query(inputs)#10行一列的矩陣 #找出輸出的最大值的索引 label = np.argmax(outputs) # print(label,"是網路的輸出值\n") #如果期望值和網路的輸出值正確 則往score 數組裡面加1 否則新增0 if(label == correct_values): score.append(1) else: score.append(0) pass pass print(outputs) #%% # print(score) score_array = np.asfarray(score) #%% print("正確率是:",(score_array.sum()/score_array.size)*100,'%')