/
githubmirror
/
ailearning
Обзор
Документация
Войти
/
githubmirror
/
ailearning
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/py2.x/dl/perceptron.py
187 строк
6 KB
jiangzhonglian
修改中文符号为英文
18 май 2020, 17:12
18 май 2020, 17:12
294b3c2
Код
Авторство
О чём код?
#!/usr/bin/env python # -*- coding: UTF-8 -*- # 神经元 / 感知器 from __future__ import print_function class Perceptron(): ''' Desc: 感知器类 Args: None Returns: None ''' def __init__(self, input_num, activator): ''' Desc: 初始化感知器 Args: input_num —— 输入参数的个数 activator —— 激活函数 Returns: None ''' # 设置的激活函数 self.activator = activator # 权重向量初始化为 0 self.weights = [0.0 for _ in range(input_num)] # 偏置项初始化为 0 self.bias = 0.0 def __str__(self): ''' Desc: 将感知器信息打印出来 Args: None Returns: None ''' return('weights\t:%s\nbias\t:%f\n' % (self.weights, self.bias)) def predict(self, input_vec): ''' Desc: 输入向量,输出感知器的计算结果 Args: input_vec —— 输入向量 Returns: 感知器的计算结果 ''' # 将输入向量的计算结果返回 # 调用 激活函数 activator ,将输入向量输入,计算感知器的结果 # reduce() 函数是 python 2 的内置函数,从 python 3 开始移到了 functools 模块 # reduce() 从左到右对一个序列的项累计地应用有两个参数的函数,以此合并序列到一个单一值,例如 reduce(lambda x,y: x+y, [1,2,3,4,5]) 计算的就是 ((((1+2)+3)+4)+5) # map() 接收一个函数 f 和一个 list ,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 返回。比如我们的 f 函数是计算平方, map(f, [1,2,3,4,5]) ===> 返回 [1,4,9,16,25] # zip() 接收任意多个(包括 0 个和 1个)序列作为参数,返回一个 tuple 列表。例: x = [1,2,3] y = [4,5,6] z = [7,8,9] xyz = zip(x, y, z) ===> [(1,4,7), (2,5,8), (3,6,9)] return self.activator(reduce(lambda a, b: a + b,map(lambda (x, w): x * w, zip(input_vec, self.weights)), 0.0) + self.bias) def train(self, input_vecs, labels, iteration, rate): ''' Desc: 输入训练数据: 一组向量、与每个向量对应的 label; 以及训练轮数、学习率 Args: input_vec —— 输入向量 labels —— 数据对应的标签 iteration —— 训练的迭代轮数 rate —— 学习率 Returns: None ''' for i in range(iteration): self._one_iteration(input_vecs, labels, rate) def _one_iteration(self, input_vecs, labels, rate): ''' Desc: 训练过程的一次迭代过程 Args: input_vecs —— 输入向量 labels —— 数据对应的标签 rate —— 学习率 Returns: None ''' # zip() 接收任意多个(包括 0 个和 1个)序列作为参数,返回一个 tuple 列表。例: x = [1,2,3] y = [4,5,6] z = [7,8,9] xyz = zip(x, y, z) ===> [(1,4,7), (2,5,8), (3,6,9)] samples = zip(input_vecs, labels) # 对每个样本,按照感知器规则更新权重 for (input_vec, label) in samples: # 计算感知器在当前权重下的输出 output = self.predict(input_vec) # 更新权重 output = self._update_weights(input_vec, output, label, rate) def _update_weights(self, input_vec, output, label, rate): ''' Desc: 按照感知器规则更新权重 Args: input_vec —— 输入向量 output —— 经过感知器规则计算得到的输出 label —— 输入向量对应的标签 rate —— 学习率 Returns: None ''' # 利用感知器规则更新权重 delta = label - output # map() 接收一个函数 f 和一个 list ,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 返回。比如我们的 f 函数是计算平方, map(f, [1,2,3,4,5]) ===> 返回 [1,4,9,16,25] # zip() 接收任意多个(包括 0 个和 1个)序列作为参数,返回一个 tuple 列表。例: x = [1,2,3] y = [4,5,6] z = [7,8,9] xyz = zip(x, y, z) ===> [(1,4,7), (2,5,8), (3,6,9)] self.weights = map(lambda (x, w): w + rate * delta * x, zip(input_vec, self.weights)) # 更新 bias self.bias += rate * delta def f(x): ''' Desc: 定义激活函数 f Args: x —— 输入向量 Returns: (实现阶跃函数)大于 0 返回 1,否则返回 0 ''' return 1 if x > 0 else 0 def get_training_dataset(): ''' Desc: 基于 and 真值表来构建/获取训练数据集 Args: None Returns: input_vecs —— 输入向量 labels —— 输入向量对应的标签 ''' # 构建训练数据,输入向量的列表 input_vecs = [[1,1],[0,0],[1,0],[0,1]] # 期望的输出列表,也就是上面的输入向量的列表中数据对应的标签,是一一对应的 labels = [1, 0, 0, 0] return input_vecs, labels def train_and_perceptron(): ''' Desc: 使用 and 真值表来训练我们的感知器 Args: None Returns: p —— 返回训练好的感知器 ''' # 创建感知器,输入参数的个数是 2 个(因为 and 是个二元函数),激活函数为 f p = Perceptron(2, f) # 进行训练,迭代 10 轮,学习速率是我们设定的 rate ,为 0.1 input_vecs, labels = get_training_dataset() p.train(input_vecs, labels, 10, 0.1) # 返回训练好的感知器 return p if __name__ == '__main__': ''' Desc: 主函数,调用上面返回的训练好的感知器进行预测 Args: None Returns: None ''' # 训练 and 感知器 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]))