#coding=utf-8
__author__ = 'zhangxiaozi'
'''
编写面向对象的代码,需要有一个清晰的思路,知道要干什么,知道要哪几步骤,每个步骤的输入输出是什么?
比如在编写 感知器
1.首先要懂感知器的每个步骤讲的是什么,不知道这个,根本编不了程序
2.以感知器为例,说一下编程的思路:
****************************************
我的目的是训练出一个感知器模型
1.感知器需要训练数据,训练每一个数据,并且需要迭代很多轮
2.首先需要写一个训练函数,train(),这个函数的输入有哪些呢?需要迭代的,所以需要迭代次数iterations;需要训练的对象,也就是数据集,input_vecs;
训练数据的labels;还有学习速率learningRate
3.train函数里面需要一次一次迭代,所以需要一个每次迭代的函数
4.每次迭代的函数 one_iteration(),每次迭代需要的参数有,input_vecs,labels,learningRate
5.每次迭代中需要干的事,是预测prediction,和更新权重update()。先对一个样本预测出label,再根据label进行权重的更新
output=prediction(input_vec); 更新权重的函数是update(input_vec,label,learningRate)
'''
class perceptron(object):
def __init__(self,para_num,activator):
#参数的数目(也就是数据样本的维数),激活函数
self.para_num=para_num
#激活函数
self.activator=activator
#设置初始权重
self.weights=[0.0 for i in range(self.para_num)]
#设置偏置项
self.bias=0.0
def __str__(self):
#输出参数,进行测试
return 'weights\t:%s\nbias\t:%f\n' % (self.weights, self.bias)
#训练函数
def trainProcess(self,input_vecs,labels,iterations,learningRate):
for i in range(iterations):
self.one_iteration(input_vecs,labels,learningRate)
#每一次迭代函数
def one_iteration(self,input_vecs,labels,learningRate):
#zip操作方便
samples=zip(input_vecs,labels)
for (input_vec,label) in samples:
#得到预测的label
output=self.prediction(input_vec)
#得到output,然后去更新
self.update(input_vec,label,output,learningRate)
#预测函数
def prediction(self,input_vec):
#输入一个向量,得到输出
resulst=sum([input_vec[i]*self.weights[i] for i in range(self.para_num)])+self.bias
#通过激活函数
output=self.activator(resulst)
return output
#更新权重
def update(self,input_vec,label,output,learningRate):
#每学习一个样本,就更新一次权值
self.bias+=learningRate*(label-output)
self.weights=[self.weights[i]+learningRate*(label-output)*input_vec[i] for i in range(self.para_num)]
def f(x):
'''
定义激活函数f
'''
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():
'''
使用and真值表训练感知器
'''
# 创建感知器,输入参数个数为2(因为and是二元函数),激活函数为f
p = perceptron(2, f)
# 训练,迭代10轮, 学习速率为0.1
input_vecs, labels = get_training_dataset()
p.trainProcess(input_vecs, labels, 100, 0.1)
#返回训练好的感知器
return p
if __name__ == '__main__':
# 训练and感知器
and_perception = train_and_perceptron()
# 打印训练获得的权重
print (and_perception)