深度学习感知机简介

感知机作为神经网络的起源算法,在1957年是由美国学者Frank Rosenblatt 提出来的。其实,感知机也被称为“人工神经元”或“朴素感知机”,因为在一般情况下的处理都是共通的,所以就被统称为“感知机”了。

更多:深度学习

那么,感知机到底是什么呢?

下图是有两个输入信号的感知机的例子: \(x_1\) \(x_2\) 是输入信号,y 是输出信号,其中 \(w_1\) \(w_2\) 分别是 \(x_1\) \(x_2\) 的权重。图中符号“ ○” 表示的是“神经元”或“节点”。当输入信号 \(x_1\) \(x_2\) 被输入至神经元时,会分别乘以各自的权重 \(w_1\) \(w_2\) ,最后这两个信号的总和就是神经元传送的值,只有当这个总和大于某个阈值 \(\theta\) (界限值)时,才会输出1,否者输出0。这一操作也被称为“神经元被激活”。

综上述,感知机的运行原理可以用下面的数学公式表达:

 感知机的多个输入信号都有各自固有的权重,这些权重发挥着控制各个信号的重要性的作用。也就是说,权重越大,对应该权重的信号的重要性就越高。

感知机的简单实现 
现在让我们考虑用感知机来解决简单的逻辑电路问题。

1、与门

# coding: utf-8
#在这里,我们选择一个符合上述与门的真值表的参数例子
#ai8py.com

import numpy as np
 
def AND(x1, x2):
    x = np.array([x1, x2]) #输入
    w = np.array([0.5, 0.5]) #权重
    b = -0.7  #偏置参数,用于控制神经元被激活的容易程度
    tmp = np.sum(w*x) + b
    if tmp <= 0:
        return 0
    else:
        return 1
 
if __name__ == '__main__':
    for xs in [(0, 0), (1, 0), (0, 1), (1, 1)]:
        y = AND(xs[0], xs[1])
        print(str(xs) + " -> " + str(y))

结果显示: 

(0, 0) -> 0
(1, 0) -> 0
(0, 1) -> 0
(1, 1) -> 1
 
Process finished with exit code 0

2、与非门

# coding: utf-8
#ai8py.com

import numpy as np
 
def NAND(x1, x2):
    x = np.array([x1, x2])
    w = np.array([-0.5, -0.5])
    b = 0.7
    tmp = np.sum(w*x) + b
    if tmp <= 0:
        return 0
    else:
        return 1
 
if __name__ == '__main__':
    for xs in [(0, 0), (1, 0), (0, 1), (1, 1)]:
        y = NAND(xs[0], xs[1])
        print(str(xs) + " -> " + str(y))

结果显示:

(0, 0) -> 1
(1, 0) -> 1
(0, 1) -> 1
(1, 1) -> 0
 
Process finished with exit code 0

3、或门

# coding: utf-8
#ai8py.com

import numpy as np
 
def OR(x1, x2):
    x = np.array([x1, x2])
    w = np.array([0.5, 0.5])
    b = -0.2
    tmp = np.sum(w*x) + b
    if tmp <= 0:
        return 0
    else:
        return 1
 
if __name__ == '__main__':
    for xs in [(0, 0), (1, 0), (0, 1), (1, 1)]:
        y = OR(xs[0], xs[1])
        print(str(xs) + " -> " + str(y))

结果显示:

(0, 0) -> 0
(1, 0) -> 1
(0, 1) -> 1
(1, 1) -> 1
 
Process finished with exit code 0

4、异或门

# coding: utf-8
# ai8py.com

from and_gate import AND
from or_gate import OR
from nand_gate import NAND
 
 
def XOR(x1, x2):
    s1 = NAND(x1, x2)
    s2 = OR(x1, x2)
    y = AND(s1, s2)
    return y
 
if __name__ == '__main__':
    for xs in [(0, 0), (1, 0), (0, 1), (1, 1)]:
        y = XOR(xs[0], xs[1])
        print(str(xs) + " -> " + str(y))

结果显示:

(0, 0) -> 0
(1, 0) -> 1
(0, 1) -> 1
(1, 1) -> 0
 
Process finished with exit code 0

实际上,异或门的实现在上述代码中,用到了与门、与非门和或门,那为什么不能够单独的使用其中一种的方法实现呢?我们将简单的图示来解释其中原因。

首先,我们将或门可视化,在这里,我们将权重参数设置为 \((b, w_1, w_2)=(-0.5, 1.0 ,1.0)\) 时, 可满足或门的真值表条件。此时,感知机可用下列公式表达:

上式中,感知机的生成是由 \(-0.5+x_1+x_2=0\) 分割而成的两个空间。其中一个空间输出1,一个输出0。或门在 \((x_1, x_2)=(0,0)\) 时输出0,在 \((x_1, x_2)\) \((0, 1)、(1, 0)、(1, 1)\) 时输出1.下图中,“○” 表示0,“△”表示1。如下图所示:

 上图中,用一条直线就可以将“○”和“△”分割开来了。那么异或门就不可如此分割。像下图这样的情况下,不可能用一条直线分割。

此时,只能使用一条曲线将“○”和“△”分割开来。而这,也正是感知机的局限性(它只能表示由一条直线分割的空间)。像下图弯曲的曲线无法用感知机表示。而,这样的曲线分割而成的空间称为非线性空间,由直线分割而成的空间称为线性空间。如下图:

 上述讲到了,单层的感知机不能表示异或门,但是感知机是可以叠加的(是指通过叠加层来表示异或门),在异或门的代码中可以得到验证。

 总结
• 感知机是具有输入和输出的算法。给定一个输入后,将输出一个既定的值。
• 感知机将权重和偏置设定为参数。
• 使用感知机可以表示与门和或门等逻辑电路。
• 异或门无法通过单层感知机来表示。
• 使用2层感知机可以表示异或门。
• 单层感知机只能表示线性空间,而多层感知机可以表示非线性空间。

发表评论

电子邮件地址不会被公开。 必填项已用*标注