美文网首页
DL01-4:感知器实现(向量版)

DL01-4:感知器实现(向量版)

作者: 杨强AT南京 | 来源:发表于2018-10-14 22:25 被阅读11次

    1.使用numpy做内积运算
    2.使用向量或者矩阵内积实现感知器

    一、向量与矩阵的内积计算

    1、向量作为矩阵的注意点

    • 向量在numpy也默认看成矩阵,根据向量在运算中的位置,可以当做行向量,或者列向量,下面使用代码说明

       \#1维向量的内积与矩阵在数据格式上有差别
      v=np.array([1,2,3,4])
      m=np.array([
          [1,2,3,4],
          [5,6,7,8],
          [9,8,7,6],
          [5,4,3,2]
      ])
      
      print(np.dot(v,m))  #v作为行向量使用
      print(np.dot(m,v))  #v作为列向量使用
      
    运行效果如下: 向量根据情况作为行向量与列向量
    • 在上面向量根据位置,自动作为行向量与列向量。如果想自己控制,就使用[[\dots]]把向量作为矩阵表示。

    2、使用向量计算加权求和

    • 因为向量或者矩阵的内积本质是加权求和,所以可以使用向量的内积运算来代替加权求和运算,numpy的内积实现的运算速度比标量的循环累加和运算速度快得多。下面使用代码说明,
    #coding=utf-8
    import  numpy as np
    #矩阵与向量的内积
    weights=np.random.uniform(-0.1,0.1,size=4)
    input_data=np.array([4.7,3.2,1.3,0.2])  #来自iris数据集
    sum=0
    
    #标量计算方式
    for idx in range(len(input_data)):
        sum += weights[idx] * input_data[idx]
    
    print(sum)
    #矩阵与向量的内积计算方式
    sum=np.dot(weights,input_data)
    print(sum)
    
    sum=np.dot(input_data,weights)
    print(sum)
    print()
    
    运行效果: 内积形式的加权求和

    二、感知器学习的向量实现

    • 向量实现核心就是感知器的forward函数与backward函数,感知器应用类主要是调用感知器来完成训练与预测。
    • 除了forward函数与backward函数,其他代码没有做修改。
    • 重要的是习惯使用ndarray来表示向量与矩阵。

    1、感知器的forward函数实现

    • 下面实现代码主要使用了向量的内积
        def forward(self,input_data):
            '''
            根据已知输入特征数据,进行加权求和与激活函数运算,得到输出。
            :param input_data:              输入的特征数据,必须与构造器指定维数大小一直
            :return:                        返回特征数据计算输出。
            '''
            #1.加权求和运算
            self.input_data=input_data      #后面计算更新梯度要使用
            self.sum=np.dot(self.input_data,self.weights)      #加权求和后面要使用
            self.sum+=self.bias             #偏置项
            #2.激活函数运算
            y=self.activation_function(self.sum)
            self.y=y                        #后面计算更新梯度要使用
            #print("输出:%f"%self.y)
            return  self.y                  #返回计算输出
    
    • 这个代码还是用了向量的函数运算,由于这里的函数是恒等函数f(x)=x,恒等函数的导数函数是常数函数f(x)=1,所以暂时不关注细节。

    2、感知器的backward函数实现

    • 下面代码主要使用了向量与矩阵的哈达马积,其他同形条件下的四则运算,标量与矩阵的四则运算,代码如下:
        def backward(self,expect_output):
            '''
            :param expect_output:           输入特征数据的期望输出值。
            :return:                        无返回值
            '''
            #1.计算每个权重更新相同的部分(delta在这儿是标量)。
            delta=(self.y-expect_output)
            delta=delta*self.activation_derivative(self.sum)
            delta=self.learn_rate * delta   #学习率
    
            #2.计算每个权重对应的更新梯度(包含偏置项)。
            self.w_delta=np.zeros(self.weights.shape,np.float32)    #向量
            self.b_delta=0
    
            #偏置项的更新梯度
            self.b_delta=delta      #标量
            #权重的更新梯度
            self.w_delta=delta*self.input_data  #向量(哈马达积)
    
            #3.更新权重
            self.bias-=self.b_delta
            self.weights-=self.w_delta      #形状相同的向量与矩阵的减法
    
    • 使用向量后,修改学习率0.00001,学习轮数1000轮,识别效果可以达到100%。下面是是运行结果截图: 1000轮,0.00001学习率的识别效果

    三、标量与向量计算的速度比较

    • 计算程序运行时间,采用CPU时间,利用time模块中的clock函数返回的cpu时间即可。
    import time
    start = time.clock()
    #......这里是需要测试运行CPU时间的代码
    end=time.clock()
    print("CPU运行时间:",end-start)
    
    • 标量运行时间 感知器标量实现运行时间
    • 向量运行时间


      感知器向量实现运行时间
    【资源】

    代码下载:

    相关文章

      网友评论

          本文标题:DL01-4:感知器实现(向量版)

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