1. 程式人生 > >感知機python2.7實現

感知機python2.7實現

# -*- coding: utf-8 -*-

class Perceptron(object):
    def __init__(self, input_num, activator):
        '''
        感知機只有一個神經元,所以權重向量W的長度等於輸入向量長度,偏置為一個標量
        '''
        self.weights = [0.0 for _ in range(input_num)]
        self.biases = 0.0
        self.activator = activator

    def __str__(self):
        '''
        列印中間結果
        '''
        return 'weights\t:%s\nbias\t:%f\n' % (self.weights, self.biases)

    def feedforward(self, input_vec):
        '''
        向前傳播,計算感知機的計算結果
        :param input_vec: 輸入向量
        :return: 感知機計算結果
        '''
        num_input_item = len(input_vec)
        #z:w*x + b
        z = 0.0
        for i in range(num_input_item):
            z += self.weights[i] * input_vec[i]
        z += self.biases
        #a:感知機的計算值
        a = self.activator(z)
        return a

    def train(self, input_vecs, labels, epoches, eta):
        '''
        訓練感知機模型
        :param input_vecs: 輸入向量
        :param labels: 輸入向量對應的標籤
        :param epoches: 迭代次數
        :param eta: 學習率
        :return: None
        '''
        for ep in range(epoches):
            for i in range(len(input_vecs)):
                a_i = self.feedforward(input_vecs[i])
                delta = eta * (labels[i] - a_i)
                for j in range(len(self.weights)):
                    self.weights[j] += delta * input_vecs[i][j]
                self.biases += delta

def activator(x):
    '''
    定義啟用函式
    '''
    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_perceptron():
    '''
    訓練"與感知機"
    '''
    p = Perceptron(2, activator)
    input_vecs, labels = get_training_dataset()
    p.train(input_vecs, labels, 10, 0.1)
    return p

if __name__ == '__main__':
    and_perception = train_and_perceptron()
    print and_perception
    # 測試
    print '1 and 1 = %d' % and_perception.feedforward([1, 1])
    print '0 and 0 = %d' % and_perception.feedforward([0, 0])
    print '1 and 0 = %d' % and_perception.feedforward([1, 0])
    print '0 and 1 = %d' % and_perception.feedforward([0, 1])

核心函式解釋:

1、feedforward(self, input_vec):

輸入一個樣本向量input_vec,進行前向傳播:首先,計算線性部分結果z = w*x + b;接著,計算經過感知機神經元的預測值a = activator(z)。

2、train(self, input_vecs, labels, epoches, eta):

輸入訓練樣本集input_vecs(包含多個訓練樣本input_vec)。在迭代次數epoches迴圈中,針對訓練樣本集input_vecs的一個訓練樣本input_vec:

首先,前向計算該樣本的預測值a_i;然後,計算delta = eta * (labels[i] - a_i);最後,基於該delta更新權重向量中的每個權重w_j和偏置b。

測試結果:

weights	:[0.1, 0.2]
bias	:-0.200000

1 and 1 = 1
0 and 0 = 0
1 and 0 = 0
0 and 1 = 0

參考:

https://zybuluo.com/hanbingtao/note/433855