《深度学习之图像识别:核心技术与案例实战》 ——1.1.2 感知机

举报
华章计算机 发表于 2020/02/23 10:42:31 2020/02/23
【摘要】 本节书摘来自华章计算机《深度学习之图像识别:核心技术与案例实战》 —— 书中第1章,第1.1.2节,作者是言有三   。

1.1.2  感知机

  感知机(Perceptron)是Frank Rosenblatt在1957年提出的概念,其结构与MP模型类似,一般被视为最简单的人工神经网络,也作为二元线性分类器被广泛使用。

  通常情况下感知机指单层人工神经网络,以区别于多层感知机(Multilayer Perceptron)。尽管感知机结构简单,但能够学习并解决较复杂的问题,其结构如图1.1所示。

  假设我们有一个n维输入的单层感知机,x1至xn为n维输入向量的各个分量,w1至wn为各个输入分量连接到感知机的权量(或称权值),θ为阈值,f为激活函数(又称为激励函数或传递函数),y为标量输出。理想的激活函数f (·)通常为阶跃函数或者sigmoid函数。感知机的输出是输入向量X与权重向量W求得内积后,经激活函数f所得到的标量:

               image.png(1.1)

 image.png

图1.1  感知机模型

  权重W的初始值一般随机设置,往往达不到较好的拟合结果,那么如何更改权重数值使标量输出y逼近实际值呢?这时就需要简单介绍下感知器的学习过程。首先通过计算得到输出值,然后将实际输出值和理论输出值做差,由此来调整每一个输出端上的权值。学习规则是用来计算新的权值矩阵W及新的偏差B的算法。

  举个实际例子来说明。中国通用长度计量单位为厘米(cm),美国通用长度单位为英寸(in),两者之间有一个固定的转化公式。假设我们并不知道该公式,在单层感知机(目前考虑为单输入)的输入端输入以英寸为单位的数值,希望输出端输出相应的厘米计量数值。

  首先,先设定输入值为10英寸,并随机生成连接权值,现在假设w为1,此时单层感知机的输出为:

  厘米=10×1=10

  但我们知道正确输出应该为25.4厘米,这时可以计算出输出值与真实值之间的差:

  误差值=真实值-输入值

                                     =25.4-10

                                     =14.4

  然后用这个误差值对权重w进行调整。例如,将w由1调整至2,可以得到新的结果:厘米=10×2=20,这个结果明显优于上一个,误差值为5.4。

  再次重复上述过程,将w调整至3,结果为:厘米=10×3=30,明显超过真实值,误差为-4.6,这个负号不是意味着不足,而是调超了。

  此时可以看出,w=2的结果要优于w=3的结果,如果误差达到可接受的范围,就可以停止训练,或者是w在[2,3]之间继续微调。

  上述例子是将感知机接受一个输入,并作出对应的输出,也可以称之为预测器。接下来给出一个单层感知机应用于分类问题的Python应用实例。

  1.输入数据集与其对应标签

  示例代码如下:

 

#5组输入数据

X = np.array ([[1,1,2,3],

                  [1,1,4,7],

                  [1,1,1,3],

                  [1,1,5,3],

                  [1,1,0,1]])

# 标签

Y = np.array([1,1,-1,1,-1])

 

  外界输入是4个值,后两个值确定平面上某个点的位置,前两个数值相当于偏置值,与阈值的意义相同,这里输入了5组数值。Y存储每组值对应的正负标签。现在需要做的就是找到一条直线,将正负值区域区分开。

  2.权重的初始化

  示例代码如下:

 

# 权重初始化,取值范围为-1~1

W = (np.random.random(X.shape[1])-0.5)*2

 

  随机生成范围在(-1,1)的权重,权重的个数与输入向量维度相同。

  3.更新权重函数

  示例代码如下:

 

#更新权值函数

def get_update():

    global X,Y,W,lr,n

    n += 1

    #输出:X与W的转置相乘,得到的结果再由阶跃函数处理

    new_output = np.sign(np.dot(X,W.T))

    #调整权重: 新权重 = 旧权重 + 改变权重

    new_W = W + lr*((Y-new_output.T).dot(X))/int(X.shape[0])

    W = new_W

 

  若随机生成的权重W不能合理区分正负值区域,就要根据当前输出标签和原有标签差值的大小进行权重调整,将二者的差乘以输入向量Xi,再与学习率lr相乘得到权重改变值,与原有权重相加后得到新权重。

  完整代码如下:

 

import numpy as np

import matplotlib.pyplot as plt

n = 0                                                  #迭代次数

lr = 0.10                                         #学习速率

# 输入数据

X = np.array([[1,1,2,3],

              [1,1,4,5],

              [1,1,1,1],

              [1,1,5,3],

              [1,1,0,1]])

# 标签

Y = np.array([1,1,-1,1,-1])

# 权重初始化,取值范围为-1~1

W = (np.random.random(X.shape[1])-0.5)*2

def get_show():

    # 正样本

    all_x = X[:, 2]

    all_y = X[:, 3]

   

    # 负样本

    all_negative_x = [1, 0]

    all_negative_y = [1, 1]

   

    # 计算分界线斜率与截距

    k = -W[2] / W[3]

    b = -(W[0] +W[1])/ W[3]

    # 生成x刻度

    xdata = np.linspace(0, 5)

    plt.figure()

    plt.plot(xdata,xdata*k+b,'r')

    plt.plot(all_x, all_y,'bo')

    plt.plot(all_negative_x, all_negative_y, 'yo')

    plt.show()

   

#更新权值函数

def get_update():

    #定义所有全局变量

    global X,Y,W,lr,n

    n += 1

    #计算符号函数输出

    new_output = np.sign(np.dot(X,W.T))

    #更新权重

    new_W = W + lr*((Y-new_output.T).dot(X))/int(X.shape[0])

    W = new_W

def main():

    for _ in range(100):

        get_update()

        new_output = np.sign(np.dot(X, W.T))

        if (new_output == Y.T).all():

            print("迭代次数:", n)

            break

    get_show()

if __name__ == "__main__":

    main()

 

  最后分割结果如图1.2所示。

  单层感知器结构简单,权重更新计算快速,能够实现逻辑计算中的NOT、OR和AND等简单计算,但是对于稍微复杂的NOR异或问题就无法解决,其本质缺陷是不能处理线性不可分问题,而在此基础上提出的多层感知器就能解决此类问题。

 image.png

图1.2  感知机模型分割结果示意图


【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。