python 实现感知器(一)
生活随笔
收集整理的這篇文章主要介紹了
python 实现感知器(一)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
基礎知識不再重述,可參考https://www.zybuluo.com/hanbingtao/note/433855
直接貼出文章里的代碼以供參考學習,這里主要是為了鍛煉自己的編寫代碼的能力,之前一直是過程式的編程,這里鍛煉自己面向對象的編程能力。
# -*- coding: utf-8 -*-# 這里定義一個感知器的類 class Perceptron(object):def __init__(self, input_num, activator):'''初始化感知器,設置輸入?yún)?shù)的個數(shù),以及激活函數(shù)。激活函數(shù)的類型為double -> double'''self.activator = activator# 權重向量初始化為0.0self.weights = [0.0 for _ in range(input_num)]# 偏置項初始化為0.0self.bias = 0.0def __str__(self): # __str__:類實例字符串化函數(shù)'''打印學習到的權重、偏置項'''return 'weights\t:%s\nbias\t:%f\n' % (self.weights, self.bias)def predict(self, input_vec):'''輸入向量,輸出感知器的計算結果'''# 把input_vec[x1,x2,x3...]和weights[w1,w2,w3,...]打包在一起# 變成[(x1,w1),(x2,w2),(x3,w3),...]# 然后利用map函數(shù)計算[x1*w1, x2*w2, x3*w3]# 最后利用reduce求和:reduce()還可以接收第3個可選參數(shù),作為計算的初始值xi_wi=map(lambda (x, w): x * w,zip(input_vec, self.weights))# 激活函數(shù)的輸入為w_1*x_1+w_2*x_2+biasreturn self.activator(reduce(lambda a, b: a + b,xi_wi , 0.0) + self.bias)def train(self, input_vecs, labels, iteration, rate):'''輸入訓練數(shù)據(jù):一組向量、與每個向量對應的label;以及訓練輪數(shù)、學習率'''# 每次迭代都把所有的樣本輸入for i in range(iteration):self._one_iteration(input_vecs, labels, rate)def _one_iteration(self, input_vecs, labels, rate):'''一次迭代,把所有的訓練數(shù)據(jù)過一遍'''# 把輸入和輸出打包在一起,成為樣本的列表[(input_vec, label), ...]# 而每個訓練樣本是(input_vec, label)samples = zip(input_vecs, labels)# 對每個樣本,按照感知器規(guī)則更新權重for (input_vec, label) in samples:# 計算感知器在當前權重下的輸出output = self.predict(input_vec)# 更新權重self._update_weights(input_vec, output, label, rate)def _update_weights(self, input_vec, output, label, rate):'''按照感知器規(guī)則更新權重'''# 把input_vec[x1,x2,x3,...]和weights[w1,w2,w3,...]打包在一起# 變成[(x1,w1),(x2,w2),(x3,w3),...]# 然后利用感知器規(guī)則更新權重delta = label - outputself.weights = map(lambda (x, w): w + rate * delta * x,zip(input_vec, self.weights))# 更新biasself.bias += rate * deltadef f(x):'''定義激活函數(shù)f:階躍函數(shù)'''return 1 if x > 0 else 0def get_training_dataset():'''基于and真值表構建訓練數(shù)據(jù)'''# 構建訓練數(shù)據(jù)# 輸入向量列表input_vecs = [[1,1], [0,0], [1,0], [0,1]]# 期望的輸出列表,注意要與輸入一一對應# [1,1] -> 1, [0,0] -> 0, [1,0] -> 0, [0,1] -> 0labels = [1, 0, 0, 0]return input_vecs, labels def train_and_perceptron():'''使用and真值表訓練感知器'''# 創(chuàng)建感知器,輸入?yún)?shù)個數(shù)為2(因為and是二元函數(shù)),激活函數(shù)為fp = Perceptron(2, f)# 獲得標準的訓練數(shù)據(jù)input_vecs, labels = get_training_dataset()# 訓練,迭代10輪, 學習速率為0.1p.train(input_vecs, labels, 10, 0.1)#返回訓練好的感知器return pif __name__ == '__main__': # 訓練and感知器and_perception = train_and_perceptron()# 打印訓練獲得的權重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])運行結果哦:
weights :[0.1, 0.2] bias :-0.2000001 and 1 = 1 0 and 0 = 0 1 and 0 = 0 0 and 1 = 0代碼已經(jīng)有詳細的注釋,只需注意以下幾個地方就好。
筆記
- 由于這里的感知器是訓練的簡單的與或非運算,目標輸出都是0、1值,所以激活函數(shù)用階躍函數(shù),如果目標輸出是-1、+1值,此時用符號函數(shù)(sign)作為激活函數(shù),所以激活函數(shù)的選取是要看目標輸出值的形式。
- 注意這里的權重更新為:
wi←wi+η(t?y)xib←b+η(t?y)wi←wi+η(t?y)xib←b+η(t?y)
tt是訓練樣本的實際值,一般稱之為label。而yy是感知器的輸出值 - reduce()函數(shù)也是Python內置的一個高階函數(shù)。
reduce()函數(shù)接收的參數(shù)和 map()類似,一個函數(shù) f,一個list,但行為和 map()不同,reduce()傳入的函數(shù) f 必須接收兩個參數(shù),reduce()對list的每個元素反復調用函數(shù)f,并返回最終結果值
reduce()還可以接收第3個可選參數(shù),作為計算的初始值 - __str__方法和__init__方法類似,都是一些特殊方法,所以前后都有雙下劃線,它用來返回對象的字符串表達式.事實上。__str__是被print函數(shù)調用的,一般都是return一個字符串。當打印一個類的時候,那么print首先調用的就是類里面的定義的__str__。
通過這段簡單的代碼可以看出利用對象來實現(xiàn)算法的一個流程,自己在這方面還是相對薄弱,有待以后的學習和加強。
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的python 实现感知器(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python中的self描述符__set
- 下一篇: 朋友餐饮店开业+万事俱备就差一位尊贵的老