from functools import reduce class Perceptron: def __init__(self, input_num, activator): ''' initialize the perceptron :param input_num: the number of parameters :param activator: sctivator function ''' self.activator = activator self.weights = [0.0 for _ in range(input_num)] self.bias = 0.0 def __str__(self): return 'weight\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函数计算[x1*w1,x2*w2,...] 最后利用reduce求和 :param input_vec: 输入向量 :return: ''' #python3 return self.activator(reduce(lambda a, b: a + b, list(map(lambda x: x[0] * x[1], zip(input_vec, self.weights)))) + self.bias) #or #return self.activator(reduce(lambda a, b: a + b, [x*w for x, w in zip(input_vec, self.weights)]) + self.bias) ##python2 #samples = zip(input_vec, self.weights) #return self.activator( # reduce(lambda a, b: a + b, # map(lambda x, w: x * w, samples) # , 0.0) + self.bias) def train(self, input_vecs, labels, iteration, rate): ''' 输入训练数据:一组向量、与每个向量对应的labels;以及训练轮数、学习率 :param input_vecs: :param labels: :param interation: :param rate: :return: ''' for i in range(iteration): self._one_iteration(input_vecs, labels, rate) def _one_iteration(self, input_vecs, labels, rate): for (input_vec, label) in zip(input_vecs, labels): output = self.predict(input_vec) self._update_weights(input_vec, output, label, rate) def _update_weights(self, input_vec, output, label, rate): ''' 按照感知器规则更新权重 :param input_vec: :param output: :param label: :param rate: :return: ''' delta = label - output #self.weights = map(lambda x, w: w+rate*delta*x, zip(input_vec,self.weights))##python2 self.weights = list(map( lambda x: x[1] + rate * delta * x[0], zip(input_vec, self.weights))) self.bias+=rate*delta
#####用感知器实现and函数 from perceptron import Perceptron def f(x): ''' 定义激活函数 :return: ''' return 1 if x > 0 else 0 def get_training_dataset(): ''' 基于and真值表构建训练数据 :return: ''' input_vecs = [[1, 1], [0, 0], [1, 0], [0, 1]] labels = [1, 0, 0, 0] return input_vecs, labels def train_and_perceptron(): ''' 使用and真值表训练感知器 :return: ''' # 创建感知器,输入参数个数为2,激活函数为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_perceptron = train_and_perceptron() print(and_perceptron) print('1 and 1 = %d' % and_perceptron.predict([1, 1])) print('0 and 0 = %d' % and_perceptron.predict([0, 0])) print('1 and 0 = %d' % and_perceptron.predict([1, 0])) print('0 and 1 = %d' % and_perceptron.predict([0, 1]))
py2与py3中lambda的写法不同 ,3中要用x[0],x[1]....
py2的map函数直接返回列表 ,而python3返回map对象