美文网首页
12-20201013 感知机6-实例2

12-20201013 感知机6-实例2

作者: 野山羊骑士 | 来源:发表于2020-10-16 16:11 被阅读0次
    from __future__ import print_function
    from functools import reduce
    
    class VectorOp(object):
        """
        这里不用numpy,手写实现向量的基本操作
        """
        @staticmethod
        def element_multiply(x,y):
            """
            将两个向量x和y按照元素相乘
            """
            # 首先把x[x1,x2,x3...]和y[y1,y2,y3...]打包在一起
            # 变成[(x1,y1),(x2,y2),(x3,y3),...]
            # 然后利用map函数计算[x1*y1,x2*y2,x3*y3,...]
            return list(map(lambda x_y:x_y[0]*x_y[1],zip(x,y)))
        
        @staticmethod
        def dot(x,y):
            """
            计算两个向量的内积
            """
            # 首先把x[x1,x2,x3...]和y[y1,y2,y3...]按元素相乘
            # 变成[x1*y1,x2*y2,X3*y3]
            # 然后reduce求和
            return reduce(lambda a,b:a+b,VectorOp.element_multiply(x,y))
        
        @staticmethod
        def element_add(x,y):
            """
            将两个向量x和y的元素相加
            """
            # 首先把x[x1,x2,x3...]和y[y1,y2,y3...]打包在一起
            # 变成[(x1,y1),(x2,y2),(x3,y3),....]
            # 然后利用map函数计算[x1+y1,x2+y2,x3+y3,...]
            return list(map(lambda x_y:x_y[0]+x_y[1],zip(x,y)))
        
        @staticmethod
        def scala_multiply(v,s):
            """
            将向量v中的每个元素与标量s相乘
            """
            return map(lambda x:x*s,v)
        
    
    class Perceptron(object):
        def __init__(self,input_num):
            """
            初始化感知机,设置输入参数的个数
            """
            # 权重向量初始化为0
            self.weights = [0.0]*input_num
            # 偏置初始化为0
            self.bias = 0.0
            
        def __str__(self):
            """
            打印学习到的权重
            """
            str_ = "weight \t:{}\n bias:\t {}".format(self.weights,self.bias)
            return str_
        
        def predict(self,input_vec):
            """
            输入向量,输出感知机的计算结果
            """
            # 计算向量 input_vector[x1,x2,x3,...]和weights[w1,w2,w3,...]的内积
            # 然后加上bias
            value = VectorOp.dot(input_vec,self.weights)+self.bias
            if value >0:
                return 1
            else:
                return 0
        
        def train(self,input_vecs,labels,iteration,rate):
            """
            输入训练数据:一组向量与每个向量对应的label;已经训练的轮数、学习率
            """
            for i in range(iteration):
                str_ = "iterating: weight: \t{} bias:\t {}".format(self.weights,self.bias)
                print(str_)
                self._one_iteration(input_vecs,labels,rate)
    
                
        def _one_iteration(self,input_vecs,labels,rate):
            """
            一次迭代,把所有的训练数据过一遍
            """
            # 把输入和输出打包在一起,成为样本的列表[(input_vex,label),....]
            # 而每个训练样本是(input_vec,label)
            samples = zip(input_vecs,labels)
            
            # 对每个样本,按照感知机规则更新权重
            for (input_vec,label) in samples:
                # 计算感知机在当前权重下的输出
                output = self.predict(input_vec)
                # 更新权重
                self._updata_weight(input_vec,output,label,rate)
            
        def _updata_weight(self,input_vec,output,label,rate):
            """
            按照感知机的规则更新权重
            """
            # 首先计算本次更新的delta
            # 然后把input_vec[x1,x2,x3,..]向量中的每个值乘上delta,得到每个权重更新
            # 最后再把权重更新元素加到原来的weights[w1,w2,w3,..]上
            delta = label - output
            self.weights = VectorOp.element_add(self.weights,VectorOp.scala_multiply(input_vec,rate*delta))
            self.bias = self.bias + rate*delta
            
            
    
    """
    基于and真值表构建训练数据
    """
    # 构建训练数据
    # 输入向量列表
    input_vecs = [[1,1],[0,0],[1,0],[0,1]]
    
    # 期望的输出列表,注意要与输入一一对应
    labels = [1,0,0,0]
    
    # 创建感知机
    and_perception = Perceptron(2)
    and_perception.train(input_vecs,labels,10,0.1)
    
    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]))
    
    iterating: weight:  [0.0, 0.0] bias:     0.0
    iterating: weight:  [0.0, 0.1] bias:     -0.1
    iterating: weight:  [0.0, 0.1] bias:     -0.2
    iterating: weight:  [0.1, 0.1] bias:     -0.2
    iterating: weight:  [0.1, 0.2] bias:     -0.2
    iterating: weight:  [0.1, 0.2] bias:     -0.2
    iterating: weight:  [0.1, 0.2] bias:     -0.2
    iterating: weight:  [0.1, 0.2] bias:     -0.2
    iterating: weight:  [0.1, 0.2] bias:     -0.2
    iterating: weight:  [0.1, 0.2] bias:     -0.2
    weight  :[0.1, 0.2]
     bias:   -0.2
    1 and 1 = 1
    0 and 0 = 0
    1 and 0 = 0
    0 and 1 = 0
    
    """
    基于 or 真值表构建训练数据
    """
    # 构建训练数据
    # 输入向量列表
    input_vecs = [[1,1],[0,0],[1,0],[0,1]]
    
    # 期望的输出列表,注意要与输入一一对应
    labels = [1,0,1,1]
    
    # 创建感知机
    and_perception = Perceptron(2)
    and_perception.train(input_vecs,labels,10,0.1)
    
    print(and_perception)
    
    # 测试
    print('1 or 1 = %d' % and_perception.predict([1, 1]))
    print('0 or 0 = %d' % and_perception.predict([0, 0]))
    print('1 or 0 = %d' % and_perception.predict([1, 0]))
    print('0 or 1 = %d' % and_perception.predict([0, 1]))
    
    iterating: weight:  [0.0, 0.0] bias:     0.0
    iterating: weight:  [0.1, 0.1] bias:     0.0
    iterating: weight:  [0.1, 0.1] bias:     0.0
    iterating: weight:  [0.1, 0.1] bias:     0.0
    iterating: weight:  [0.1, 0.1] bias:     0.0
    iterating: weight:  [0.1, 0.1] bias:     0.0
    iterating: weight:  [0.1, 0.1] bias:     0.0
    iterating: weight:  [0.1, 0.1] bias:     0.0
    iterating: weight:  [0.1, 0.1] bias:     0.0
    iterating: weight:  [0.1, 0.1] bias:     0.0
    weight  :[0.1, 0.1]
     bias:   0.0
    1 or 1 = 1
    0 or 0 = 0
    1 or 0 = 1
    0 or 1 = 1
    
    """
    感知机解决不了的异或问题,找不到超平面
    """
    # 构建训练数据
    # 输入向量列表
    input_vecs = [[1,1],[0,0],[1,0],[0,1]]
    
    # 期望的输出列表,注意要与输入一一对应
    labels = [0,0,1,1]
    
    # 创建感知机
    and_perception = Perceptron(2)
    and_perception.train(input_vecs,labels,10,0.1)
    
    print(and_perception)
    
    # 测试
    print('1 -- 1 = %d' % and_perception.predict([1, 1]))
    print('0 -- 0 = %d' % and_perception.predict([0, 0]))
    print('1 -- 0 = %d' % and_perception.predict([1, 0]))
    print('0 -- 1 = %d' % and_perception.predict([0, 1]))
    
    iterating: weight:  [0.0, 0.0] bias:     0.0
    iterating: weight:  [0.1, 0.0] bias:     0.1
    iterating: weight:  [0.1, 0.0] bias:     0.2
    iterating: weight:  [0.1, 0.0] bias:     0.2
    iterating: weight:  [0.1, 0.0] bias:     0.2
    iterating: weight:  [0.1, 0.0] bias:     0.2
    iterating: weight:  [0.1, 0.0] bias:     0.2
    iterating: weight:  [0.1, 0.0] bias:     0.2
    iterating: weight:  [0.1, 0.0] bias:     0.2
    iterating: weight:  [0.1, 0.0] bias:     0.2
    weight  :[0.1, 0.0]
     bias:   0.2
    1 -- 1 = 1
    0 -- 0 = 1
    1 -- 0 = 1
    0 -- 1 = 1
    
    图片.png

    相关文章

      网友评论

          本文标题:12-20201013 感知机6-实例2

          本文链接:https://www.haomeiwen.com/subject/gbjvpktx.html