深度學習筆記——感知機
阿新 • • 發佈:2018-11-07
程式碼參考了零基礎入門深度學習(1) - 感知器這篇文章,我只對程式碼裡可能存在的一些小錯誤進行了更改。至於感知機的原理以及程式碼裡不清楚的地方可以結合該文章理解。
from functools import reduce class Perceptron: def __init__(self,input_num,activator): ''' param input_num: 初始化感知機,設定輸入引數的個數 param activator: 初始化感知機,設定啟用函式 ''' self.activator = activator # 權重向量初始化為0 self.weights = [0.0 for i in range(input_num)] # 偏置項初始化為0 self.bias = 0.0 def __str__(self): ''' 列印學習到的權重,偏置項 ''' return 'weights\t:{}\nbias\t:{}\n'.format(str(self.weights),str(self.bias)) def predict(self,input_vec): ''' 輸入向量,輸出感知機的計算結果 ''' # 把input_vec[x1,x2,x3...]和weights[w1,w2,w3,...]打包在一起 # 變成[(x1,w1),(x2,w2),(x3,w3),...] # 然後利用map函式計算[x1*w1,x2*w2,x3*w3,...] # 最後利用reduce求和 zipped = zip(input_vec,self.weights) map_result = map(lambda ele:ele[0]*ele[1],list(zipped)) sum_result = reduce(lambda a,b:a+b,map_result,0.0) return self.activator(sum_result+self.bias) def train(self,input_vecs,labels,iteration,rate): ''' :param input_vec: 一組向量 :param labels: 與每個向量對應的label :param iteration: 訓練輪數 :param rate: 學習率 :return: ''' for i in range(iteration): self._one_iteration(input_vecs,labels,rate) def _one_iteration(self, input_vecs, labels, rate): ''' 一次迭代,把所有的訓練資料過一遍 ''' # 把輸入和輸出打包在一起,成為樣本的列表[(input_vec,label),...] # 而每個訓練樣本是(input_vec,labels) samples = zip(input_vecs,labels) # 對每個樣本,按照感知機規則更新權重 for ele in list(samples): # 計算感知機在當前權重下的輸出 output = self.predict(ele[0]) # 更新權重 self._update_weights(ele[0],output,ele[1],rate) def _update_weights(self, input_vec, output, label, rate): ''' 按照感知機規則更新權重 隨機梯度下降法。 ''' # 把input_vec[x1,x2,x3,...]和weights[w1,w2,w3,...]打包在一起 # 變成[(x1,w1),(x2,w2),(x3,w3),...] # 然後利用感知機規則更新權重 delta = label - output self.weights = list(map(lambda ele:ele[1]+rate*delta*ele[0],zip(input_vec,self.weights))) # 更新bias self.bias += rate*delta def f(x): ''' 定義啟用函式f ''' return 1 if x > 0 else 0 def get_training_dataset(): ''' 基於and真值表構建訓練資料 ''' # 構建訓練資料 # 輸入向量列表 input_vecs = [[1,1],[0,0],[1,0],[0,1]] # 期望的輸出列表,注意要與輸入一一對應 # [1,1] -> 1, [0,0] -> 0, [1,0] -> 0, [0,1] -> 0 labels = [1,0,0,0] return input_vecs,labels def train_and_perception(): ''' 使用and真值表訓練感知機 ''' # 建立感知機,輸入引數個數為2(因為and是二元函式),啟用函式為f p = Perceptron(2,f) # 訓練,迭代10輪,學習速率為0.1 input_vecs,labels= get_training_dataset() p.train(input_vecs,labels,10,0.1) # 返回訓練好的感知機 return p ''' if __name__ == '__main__': # 訓練感知機 and_perception = train_and_perception() # 列印訓練獲得的權重 print(and_perception) # 測試 print('1 and 1 = %d' %and_perception.predict([1,1])) print('0 and 0 = %d' %and_perception.predict([0,0])) print('1 and 0 = %d' %and_perception.predict([1,0])) print('0 and 1 = %d' %and_perception.predict([0,1])) '''