定义

感知器

xix_i:输入

ωi\omega_i:权值

ω0\omega_0:偏置项(b)

输出:y=f(ωx+b)y=f(\omega\cdot x+b)

感知器的训练算法

将权重项和偏置项初始化为0,然后利用下面的感知器规则迭代修改ωi\omega_ibb,直到训练完成:

ωiωi+Δωibb+Δb\omega_i\larr\omega_i+\Delta\omega_i\\b\larr b+\Delta b

其中:

Δωi=η(ty)xiΔb=η(ty)\Delta\omega_i=\eta(t-y)x_i\\\Delta b =\eta(t-y)

tt是训练样本的实际值,一般称之为label。而yy是感知器的输出值,η\eta是称为学习速率的常数,其作用是控制每一步调整权的幅度。

每次从训练数据中取出一个样本的输入向量xx,使用感知器计算使其输出yy,再根据上面的规则来调整权重。每处理一个样本就调整一次权重。多轮迭代后即可训练出感知器的权重,使之实现目标函数。

代码

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
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]))