標籤:python 機器學習 神經網路
應朋友之請寫了一份python實現單隱層BP Ann model的code,好久沒寫部落格,就順便發上來。這篇代碼比較乾淨利落,比較純粹的描述了Ann的基本原理,初學機器學習的同學可以參考。
模型中幾個比較重要的參數:
1.學習率
學習率是影響模型收斂的重要因素,一般來說要根據具體情境靈活調整,過高的學習率會使得函數快速發散。
2.隱元數量
一般來說,增加隱層中神經元的數量比直接增加隱層更加有效,這也是單隱層神經網路的特點。對於複雜程度不算太高的問題而言,單隱層的效果優於多隱層。
3.隨機種子位元
代碼中增加了這一參數,來控制初始化串連權與閾值的精度。由於神經網路中初始權重與閾值是隨機產生的,那麼其隨機精度會對結果產生一定的影響。在輸入元、隱元的數量較多時,調整隨機精度會起到減小誤差的作用。
代碼中舉了一個非常簡單的訓練樣本,筆者自擬了一個規則:
輸入兩個變數,當變數A = 變數B時,傳回型別1,矩陣化為[1,0]。當變數A != 變數B時,傳回型別2,矩陣化為[0,1]。
讓神經網路去學習這個simple的規則,並給出20條測試資料去驗證。最終使用了5000條訓練資料,就獲得了100%的正確分類能力。
#---Author:伍思磊---#---Mail:[email protected]#---2015/7/27---import randomimport math#---神經網路Model---class Ann: #建構函式 初始化模型參數 def __init__(self, i_num, h_num, o_num): #可調參數 self.learn_rate = 0.1 #學習率 self.num_long = 2 #輸出結果位元 self.random_long = 10 #隨機種子位元 #輸入參數 self.input_num = i_num #輸入層 數量 self.hidden_num = h_num #隱層 數量 self.output_num = o_num #輸出層 數量 #模型參數 self.input = [] #輸入層 self.hidden = [] #隱層 self.output = [] #輸出層 self.error = [] #誤差 self.expectation = [] #期望 self.weight_ih = self.__ini_weight(self.input_num, self.hidden_num) #輸入層->隱層 串連權 self.weight_ho = self.__ini_weight(self.hidden_num, self.output_num) #隱層->輸出層 串連權 self.threshold_h = self.__ini_threshold(self.hidden_num) #隱層 閾值 self.threshold_o = self.__ini_threshold(self.output_num) #輸出層 閾值 #初始串連權產生器 def __ini_weight(self, x, y): result = [] long = math.pow(10, self.random_long) for i in range(0, x, 1): res = [] for j in range(0, y, 1): num = round(random.randint(-1*long,long)/long, self.random_long) res.insert(j, num) result.insert(i, res) return result #初始閾值產生器 def __ini_threshold(self, n): result = [] long = pow(10, self.random_long) for i in range(0, n, 1): num = round(random.randint(-1*long,long)/long, self.random_long) result.insert(i, num) return result #激勵函數 sigma def excitation(self, value): sigma = 1/(1+(math.exp(-1*value))) return sigma #輸入資料 def input_param(self, data, expectation = []): self.input = [] for value in data: self.input.append(value) if(expectation): self.expectation = [] for value in expectation: self.expectation.append(value) #隱層計算 def count_hidden(self): self.hidden = [] for h in range(0, self.hidden_num, 1): Hval = 0 for i in range(len(self.input)): Hval += self.input[i] * self.weight_ih[i][h] Hval = self.excitation(Hval+self.threshold_h[h]) self.hidden.insert(h, Hval) #輸出層計算 def count_output(self): self.output = [] for o in range(0, self.output_num, 1): Oval = 0 for h in range(len(self.hidden)): Oval += self.hidden[h] * self.weight_ho[h][o] Oval += self.threshold_o[o] Oval = round(Oval, self.num_long) self.output.insert(o, Oval) #誤差計算 def count_error(self): self.error = [] for key in range(len(self.output)): self.error.insert(key, self.expectation[key] - self.output[key]) #串連權反饋訓練 輸入層->隱層 def train_weight_ih(self): for i in range(len(self.weight_ih)): for h in range(len(self.weight_ih[i])): tmp = 0 for o in range(0, self.output_num, 1): tmp += self.weight_ho[h][o] * self.error[o] self.weight_ih[i][h] = self.weight_ih[i][h] + self.learn_rate * self.hidden[h] * (1 - self.hidden[h]) * self.input[i] * tmp #串連權反饋訓練 隱層->輸出層 def train_weight_ho(self): for h in range(len(self.weight_ho)): for o in range(len(self.weight_ho[h])): self.weight_ho[h][o] = self.weight_ho[h][o] + self.learn_rate * self.hidden[h] * self.error[o] #閾值反饋訓練 隱層 def train_threshold_h(self): for h in range(len(self.threshold_h)): tmp = 0 for o in range(0, self.output_num, 1): tmp += self.weight_ho[h][o] * self.error[o] self.threshold_h[h] = self.threshold_h[h] + self.learn_rate * self.hidden[h] * (1 - self.hidden[h]) * tmp #閾值反饋訓練 輸出層 def train_threshold_o(self): for o in range(len(self.threshold_o)): self.threshold_o[o] = self.threshold_o[o] + self.error[o] #反饋訓練 def train(self): self.train_weight_ih() self.train_weight_ho() self.train_threshold_h() self.train_threshold_o() #歸一化函數 def normal_num(self, max, min, data): data = (data - min)/(max - min) return data #尋找集合的最大值和最小值#---業務部分(樣本)---#要訓練的規則,輸入兩個值,如果兩值相等返回[1,0],反之返回[0,1]def testFunc(val): if(val[0] == val[1]): return [1,0] else: return [0,1]#構造神經網路模型ann = Ann(2,3,2)#產生訓練資料,隨機產生5000組[0,1][1,0][1,1][0,0]隨機數組data = []for i in range(0, 10000, 1): x = random.randint(0,1) y = random.randint(0,1) data.append([x,y])#取得訓練資料中的最大值和最小值for i in range(len(data)): for j in range(len(data[i])): if(i == 0 and j == 0): max = min = data[i][j] elif(data[i][j] > max): max = data[i][j] elif(data[i][j] < min): min = data[i][j]#訓練資料歸一化dataNormal = []for i in range(len(data)): dataNormal.insert(i, []) for j in range(len(data[i])): dataNormal[i].append(ann.normal_num(max, min, data[i][j]))#計算訓練資料期望值,並進行反饋訓練for i in range(len(data)): #計算期望值 exp = testFunc(data[i]) #輸入訓練資料與期望 ann.input_param(dataNormal[i], exp) #計算隱層 ann.count_hidden() #計算輸出層 ann.count_output() #計算誤差 ann.count_error() #反饋訓練 ann.train()#產生測試資料,隨機產生20組testdata = []for i in range(0, 20, 1): x = random.randint(0,1) y = random.randint(0,1) testdata.append([x,y])#進行測試,同時輸出神經網路預測值與實際期望值for i in range(len(testdata)): exp = testFunc(testdata[i]) ann.input_param(testdata[i]) ann.count_hidden() ann.count_output() print("Ann:") print(ann.output) print("Exp:") print(exp) print("\r")
本文出自 “機器學習正在路上” 部落格,請務必保留此出處http://10574403.blog.51cto.com/10564403/1679037
python實現單隱層神經網路基本模型