1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| from functools import reduce
class Perceptron(object): def __init__(self, input_num, activator): """ 初始化感知器,设定输入参数个数,激活函数 """ self.activator = activator self.weights = [0.0 for _ in range(input_num)] self.bias = 0.0
def __str__(self): return 'weights\t:%s\nbias\t:%f\n' % (self.weights, self.bias)
def predict(self, input_vec): """ 输入向量,输出感知器计算结果 zip(iter1, iter2, ...)将多个可迭代对象打包在一起,成对组合成元组 map(function, iterable)把 function 应用到 iterable里的每一个元素上 reduce(function, iterable[, initializer])对 iterable 中的元素进行两两归约处理,最终返回一个值 """ return self.activator( reduce(lambda a, b: a + b, map(lambda x_w: x_w[0] * x_w[1], zip(input_vec, self.weights)) , 0.0) + self.bias)
def train(self, input_vecs, labels, iteration, rate): """ 输入训练数据:向量,label,训练轮数,学习率 """ for i in range(iteration): self._one_iteration(input_vecs, labels, rate)
def _one_iteration(self, input_vecs, labels, rate): """ 一次迭代 """ samples = zip(input_vecs, labels) for (input_vec, label) in samples: output = self.predict(input_vec) self._update_weights(input_vec, label, output, rate)
def _update_weights(self, input_vec, label, output, rate): """ 更新权重 """ delta = label - output self.weights = [w + rate * delta * x for x, w in zip(input_vec, self.weights)] self.bias += rate * delta
def f(x): """ 激活函数f """ return 1 if x > 0 else 0
def get_training_dataset(): input_vecs = [[1, 1], [0, 0], [1, 0], [0, 1]] labels = [1, 0, 0, 0] return input_vecs, labels
def train_and_perceptron(): """ 进行训练 """ p = Perceptron(2, f) input_vecs, labels = get_training_dataset() p.train(input_vecs, labels, 10, 0.1) return p
if __name__ == '__main__': perceptron = train_and_perceptron() print(perceptron)
print('predict(1, 1) = %d' % perceptron.predict([1, 1])) print('predict(0, 0) = %d' % perceptron.predict([0, 0])) print('predict(1, 0) = %d' % perceptron.predict([1, 0])) print('predict(0, 1) = %d' % perceptron.predict([0, 1]))
|