感知机模型
数学描述
y^=f(wTx+b)
w=w1w2⋯wn∈Rn,x=x1x2⋮xn∈Rn,b∈R
f(z)={10z≥0otherwise
训练数据集
T={(x1,y1),(x2,y2),⋯,(xN,yN)},xi∈Rn,yi∈{0,1}
损失函数
- 对于单个样本(xi,yi)∈T
Errori=21(yi−y^i)2,i=1,2,⋯,Ny^i=f(wTxi+b),i=1,2,⋯,N
Error=21i=1∑N(yi−y^i)2y^i=f(wTxi+b),i=1,2,⋯,N
参数训练
随机梯度下降
- **随机选取样本 (xi,yi)∈T **
xi=[x1i,x2i,⋯,xni]T
∂wj∂Errori∂b∂Error=∂y^i∂Errori∂wi∂y^i=−(yi−y^i)xji=∂y^i∂Error∂b∂y^i=−(yi−y^i)
如下更新参数, 其中 η 是步长(学习率)
wjb←wj+η(yi−y^i)xji,j=1,2,⋯,n←b+η(yi−y^i)
整体梯度下降
∂wj∂Error∂b∂Error=i=1∑N∂y^i∂Errori∂wj∂y^i=−i=1∑N(yi−y^i)xji,j=1,2,⋯,n=i=1∑N∂y^i∂Errori∂b∂y^i=−i=1∑N(yi−y^i)
如下更新参数, 其中 η 是步长(学习率)
wjb←wj+ηi=1∑N(yi−y^i)xji,j=1,2,⋯,n←b+ηi=1∑N(yi−y^i)
Python3实现
这里构建一个感知机, 并实现and
函数真值表训练感知机
T={([11],1),([10],0),([01],0),([00],0)}
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 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
| 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\n bias:\t %f\n' % (self.weights, self.bias)
def predict(self, input_vec): y = self.activator( reduce(lambda a, b: a+b, list( map( lambda x, w: x*w, input_vec, self.weights ) ) ) + self.bias ) return y
def train(self, input_vecs, labels, iteration, rate): ''' 循环迭代,训练感知机参数 input_vecs : 输入向量 labels : 输入向量对应的标签 iteration : 迭代轮数 rate : 学习率 ''' 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, output, label, rate)
def _update_weights(self, input_vec, output, label, rate): ''' 更新权重 ''' delta = label - output self.weights = list(map( lambda x, w: w + rate * delta * x, input_vec, self.weights )) self.bias = self.bias + rate*delta
def f(x): ''' 定义激活函数 ''' return 1.0 if x > 0 else 0.0
def get_training_dataset(): ''' 基于and真值表构建训练数据 ''' input_vecs = [[1,1],[0,0],[1,0],[0,1]] labels = [1,0,0,0] return input_vecs, labels
def train_and_perceptron(): ''' 使用and真值表训练感知机 ''' input_vecs, labels = get_training_dataset() p = Perceptron(2,f) 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]))
|
输出
1 2 3 4 5 6 7
| weights: [0.1, 0.2] bias: -0.200000
1 and 1 = 1 0 and 0 = 0 1 and 0 = 0 0 and 1 = 0
|