# -*- 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
参考: