深度学习笔记——感知机

代码参考了零基础入门深度学习(1) - 感知器这篇文章,我只对代码里可能存在的一些小错误进行了更改。至于感知机的原理以及代码里不清楚的地方可以结合该文章理解。

from functools import reduce


class Perceptron:

    def __init__(self,input_num,activator):
        '''
        param input_num: 初始化感知机,设置输入参数的个数
        param activator: 初始化感知机,设置激活函数
        '''
        self.activator = activator
        # 权重向量初始化为0
        self.weights = [0.0 for i in range(input_num)]
        # 偏置项初始化为0
        self.bias = 0.0

    def __str__(self):
        '''
        打印学习到的权重,偏置项
        '''
        return 'weights\t:{}\nbias\t:{}\n'.format(str(self.weights),str(self.bias))

    def predict(self,input_vec):
        '''
        输入向量,输出感知机的计算结果
        '''
        # 把input_vec[x1,x2,x3...]和weights[w1,w2,w3,...]打包在一起
        # 变成[(x1,w1),(x2,w2),(x3,w3),...]
        # 然后利用map函数计算[x1*w1,x2*w2,x3*w3,...]
        # 最后利用reduce求和
        zipped = zip(input_vec,self.weights)
        map_result = map(lambda ele:ele[0]*ele[1],list(zipped))
        sum_result = reduce(lambda a,b:a+b,map_result,0.0)
        return self.activator(sum_result+self.bias)
    
    def train(self,input_vecs,labels,iteration,rate):
        '''
        :param input_vec: 一组向量
        :param labels: 与每个向量对应的label
        :param iteration: 训练轮数
        :param rate: 学习率
        :return: 
        '''
        for i in range(iteration):
            self._one_iteration(input_vecs,labels,rate)

    def _one_iteration(self, input_vecs, labels, rate):
        '''
        一次迭代,把所有的训练数据过一遍
        '''
        # 把输入和输出打包在一起,成为样本的列表[(input_vec,label),...]
        # 而每个训练样本是(input_vec,labels)
        samples = zip(input_vecs,labels)
        # 对每个样本,按照感知机规则更新权重
        for ele in list(samples):
            # 计算感知机在当前权重下的输出
            output = self.predict(ele[0])
            # 更新权重
            self._update_weights(ele[0],output,ele[1],rate)

    def _update_weights(self, input_vec, output, label, rate):
        '''
        按照感知机规则更新权重
        随机梯度下降法。
        '''
        # 把input_vec[x1,x2,x3,...]和weights[w1,w2,w3,...]打包在一起
        # 变成[(x1,w1),(x2,w2),(x3,w3),...]
        # 然后利用感知机规则更新权重
        delta = label - output
        self.weights = list(map(lambda ele:ele[1]+rate*delta*ele[0],zip(input_vec,self.weights)))
        # 更新bias
        self.bias += rate*delta




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_perception():
    '''
    使用and真值表训练感知机
    '''
    # 创建感知机,输入参数个数为2(因为and是二元函数),激活函数为f
    p = Perceptron(2,f)
    # 训练,迭代10轮,学习速率为0.1
    input_vecs,labels= get_training_dataset()
    p.train(input_vecs,labels,10,0.1)
    # 返回训练好的感知机
    return p
'''
if __name__ == '__main__':
    # 训练感知机
    and_perception = train_and_perception()
    # 打印训练获得的权重
    print(and_perception)
    # 测试
    print('1 and 1 = %d' %and_perception.predict([1,1]))
    print('0 and 0 = %d' %and_perception.predict([0,0]))
    print('1 and 0 = %d' %and_perception.predict([1,0]))
    print('0 and 1 = %d' %and_perception.predict([0,1]))
'''

猜你喜欢

转载自blog.csdn.net/qq_36309480/article/details/83651844
今日推荐