感知机是美国学者Frank Rosenblatt在1957年提出的,是学习神经网络和深度学习的一个重要思想。感知机是模拟神经元的工作,有多个输入信号,一个输出信号,信号只有通和不通两种(即1和0),其结构如下图。
其中x1和x2为输入信号,w1和w2为权重,y为输出信号,抽象成数学表达式就是
其中θ称为阈值,当带权输入信号到达阈值时,感知机被激活,输出1,否则输出0。感知机的各个输入信号都有自己对应的权重,权重发挥着控制各输入信号的重要性的作用,显然权重越大,信号重要性越高。
感知机的简单应用
感知机的一个简单应用是实现逻辑中的与门,与非门,或门。
由与、或、非的真值表和感知机的数学表达式可知,只要选取合适的权重和阈值,就可以实现这三个逻辑。我实现时选取的参数如下(不唯一):
与门:w1 = 1, w2 = 1, θ = 1.5
与非门:w1 = -1, w2 = -1, θ = -1.5
或门:w1 = 1, w2 = 1, θ = 0.5
代码如下:
# 简单实现
# 与
def AND(x1, x2):
w1, w2, theat = 1, 1, 1.5
t = x1 * w1 + x2 * w2
if t <= theat:
return 0
else:
return 1
# 或
def OR(x1, x2):
w1, w2, theat = 1, 1, 0.5
t = x1 * w1 + x2 * w2
if t <= theat:
return 0
else:
return 1
# 与非
def NAND(x1, x2):
w1, w2, theat = -1, -1, -1.5
t = x1 * w1 + x2 * w2
if t <= theat:
return 0
else:
return 1
# 与
print('and:')
print('x1 x2 y')
print('0 0 {}'.format(AND(0, 0)))
print('0 1 {}'.format(AND(0, 1)))
print('1 0 {}'.format(AND(1, 0)))
print('1 1 {}'.format(AND(1, 1)))
print('\n')
# 或
print('or:')
print('x1 x2 y')
print('0 0 {}'.format(OR(0, 0)))
print('0 1 {}'.format(OR(0, 1)))
print('1 0 {}'.format(OR(1, 0)))
print('1 1 {}'.format(OR(1, 1)))
print('\n')
# 与非
print('not and:')
print('x1 x2 y')
print('0 0 {}'.format(NAND(0, 0)))
print('0 1 {}'.format(NAND(0, 1)))
print('1 0 {}'.format(NAND(1, 0)))
print('1 1 {}'.format(NAND(1, 1)))
print('\n')
运行结果如下:
and:
x1 x2 y
0 0 0
0 1 0
1 0 0
1 1 1
or:
x1 x2 y
0 0 0
0 1 1
1 0 1
1 1 1
not and:
x1 x2 y
0 0 1
0 1 1
1 0 1
1 1 0
以上是感知机的简单实现,简单的实现很方便理解,但有些时候不够灵活,为了使以后构造神经网络更加灵活,将原来的θ用偏置来代替,本文偏置用字母b表示,b = -θ。
引入偏置后,感知机数学表达式如下:
偏置也并非所有情况下都要引入,一般情况下,偏置对网络的影响并不显著(除非网络特别小,拟合很差),还有些时候偏置并不会影响到网络,引入偏置反而会导致训练时显卡显存的浪费。
引入偏置后感知机的实现如下
# 引入偏置,使用numpy实现
# 偏置 b = -theta
import numpy as np
# 与
def AND(x1, x2):
x = np.array([x1, x2])
w = np.array([0.5, 0.5])
b = -0.7
t = np.sum(x*w)+ b
if t <= 0:
return 0
else:
return 1
# 与非
def NAND(x1, x2):
x = np.array([x1, x2])
w = np.array([-0.5, -0.5])
b = 0.7
t = np.sum(x*w)+ b
if t <= 0:
return 0
else:
return 1
# 或
def OR(x1, x2):
x = np.array([x1, x2])
w = np.array([0.5, 0.5])
b = -0.2
t = np.sum(x*w)+ b
if t <= 0:
return 0
else:
return 1
感知机的局限性
感知机可以表示与门,或门,与非门,但如果表示异或门,就出现问题了,权重等参数根本没有符合条件的取值。
一个感知机可以轻松地实现与门,或门,与非门,是因为这些都是简单的线性结构,而异或门是非线性的,如下图,以或门为例,绿色标注的是输出为1的地方,黄色为输出为0的地方,一条直线可以轻松分开两种结果:
而异或,只能用曲线来划分开两种结果(绿色为1,黄色为0):
但根据逻辑代数,我们可以对异或进行转化,用与门、与非门和或门来实现异或,化简结果如下:
可以先让两个输入信号通过与非门,得到结果s1,再通过或门,得到结果s2,最后让s1和s2通过与门,就实现了异或门。
异或门实现:
# 异或,依赖已实现的与门、与非门、或门
def XOR(x1, x2):
s1 = NAND(x1, x2)
s2 = OR(x1, x2)
y = AND(s1, s2)
return y
print('xor:')
print('x1 x2 y')
print('0 0 {}'.format(XOR(0, 0)))
print('0 1 {}'.format(XOR(0, 1)))
print('1 0 {}'.format(XOR(1, 0)))
print('1 1 {}'.format(XOR(1, 1)))
运行结果
xor:
x1 x2 y
0 0 0
0 1 1
1 0 1
1 1 0
异或门通过多个感知机叠加实现,这种叠加了多层的感知机,称为多层感知机。可见,单层感知机虽有局限性,但可以通过叠加来灵活地表示单层感知机不方便表示地东西,感知机地灵活性还是很高的。
理论上,用感知机可以模拟一台计算机的运行,因为感知机可以表示出与或非等逻辑门,而计算机就是基于逻辑电路与运行的。
Comments | NOTHING