感知机(perceptron)
严格地讲,本章中所说的感知机应该称为“人工神经元”或“朴素感知机”,但是因为很多基本的处理都是共通的,所以这里就简单地称为“感知机”。
2.1 感知机是什么
感知机接收多个输入信号,输出一个信号。
感知机的信号只有“流 / 不流”(1/0)两种取值。在本书中,0 对应“不传递信号”,1 对应“传递信号”。
感知机的多个输入信号都有各自固有的权重,这些权重发挥着控制各个信号的重要性的作用
权重相当于电流里所说的电阻。电阻是决定电流流动难度的参数,电阻越低,通过的电流就越大。而感知机的权重则是值越大,通过的信号就越大。
2.2 简单逻辑电路
2.2.1 与门
2.2.2 与非门和或门
只要把实现与门的参数值的符号取反,就可以实现与非门。
这里决定感知机参数的并不是计算机,而是我们人。我们看着真值表这种“训练数据”,人工考虑(想到)了参数的值。而机器学习的课题就是将这个决定参数值的工作交由计算机自动进行
学习 是确定合适的参数的过程,而人要做的是思考感知机的构造(模型),并把训练数据交给计算机。
这里重要的一点是:与门、与非门、或门的感知机构造是一样的。
实际上,3 个门电路只有参数的值(权重和阈值)不同。也就是说,相同构造的感知机,只需通过适当地调整参数的值,就可以像“变色龙演员”表演不同的角色一样,变身为与门、与非门、或门
2.3 感知机的实现
2.3.1 简单的实现
import numpy as npdef AND(x1,x2):w1,w2,theta=0.5,0.5,0.7tmp = x1*w1 + x2*w2if tmp <= theta:return 0elif tmp > theta:return 1if __name__ == '__main__':for xs in [(0, 0), (1, 0), (0, 1), (1, 1)]:y = AND(xs[0], xs[1])print(str(xs) + " -> " + str(y))
2.3.2 导入权重和偏置
首先把式(2.1)的 θ 换成 -b ,于是就可以用式(2.2)来表示感知机的行为。
此处,b 称为偏置 ,w1和 w2 称为权重
>>> import numpy as np
>>> x=np.array([0,1])
>>> w=np.array([0.5,0.5])
>>> b=-0.7
>>> w*x
array([0. , 0.5])
>>> np.sum(w*x)
0.5
>>> np.sum(w*x)+b
-0.19999999999999996
2.3.3 使用权重和偏置的实现
import numpy as npdef NAND(x1,x2):x = np.array([x1,x2])w = np.array([-0.5,-0.5])b = 0.7tmp = np.sum(w*x) + bif tmp<=0:return 0else:return 1if __name__ == '__main__':for xs in [(0, 0), (1, 0), (0, 1), (1, 1)]:y = NAND(xs[0], xs[1])print(str(xs) + " -> " + str(y))
import numpy as npdef OR(x1,x2):x = np.array([x1,x2])w = np.array([0.5,0.5])b = -0.2tmp = np.sum(w*x) + bif tmp<=0:return 0else:return 1if __name__ == '__main__':for xs in [(0,0),(1,0),(0,1),(1,1)]:y = OR(xs[0],xs[1])print(str(xs) + " -> " + str(y))
这里把 -θ 命名为偏置 b ,但是请注意,偏置和权重w1 、w2 的作用是不一样的。
具体地说,w1 和 w2 是控制输入信号的重要性的参数,而偏置是调整神经元被激活的容易程度(输出信号为 1 的程度)的参数。
比如,若 b 为 -0.1,则只要输入信号的加权总和超过 0.1,神经元就会被激活。但是如果 b 为 -20.0,则输入信号的加权总和必须超过 20.0,神经元才会被激活。
偏置的值决定了神经元被激活的容易程度.
偏置这个术语,有“穿木屐” 的效果,即在没有任何输入时(输入为 0 时),给输出穿上多高的木屐(加上多大的值)的意思。
实际上,在式 (2.2) 的b+w1x1+w2x2 的计算中,当输入 x1 和 x2 为 0 时,只输出偏置的值。
与门、与非门、或门是具有相同构造的感知机,区别只在于权重参数的值
2.4 感知机的局限性
2.4.1 异或门
仅当 x1 或 x2 中的一方为 1 时,才会输出 1(“异或”是拒绝其他的意思)
用前面介绍的感知机是无法实现这个异或门的.
感知机的局限性就在于它只能表示由一条直线分割的空间.
曲线分割而成的空间称为非线性 空间,由直线分割而成的空间称为线性 空间.
2.5 多层感知机
感知机的绝妙之处在于它可以“叠加层”(通过叠加层来表示异或门是本节的要点)
2.5.1 已有门电路的组合
2.5.2 异或门的实现
from and_gate import AND
from or_gate import OR
from nand_gate import NANDdef XOR(x1,x2):s1 = NAND(x1,x2)s2 = OR(x1,x2)y = AND(s1,s2)return yif __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 层,中间的一列称为第 1 层,最右边的一列称为第 2 层。
叠加了多层的感知机也称为多层感知机(multi-layered perceptron)
通过叠加层(加深层),感知机能进行更加灵活的表示。
2.6 从与非门到计算机
进行加法运算的加法器也可以用感知机实现。
将二进制转换为十进制的编码器、满足某些条件就输出 1 的电路(用于等价检验的电路)等也可以用感知机表示。
实际上,使用感知机甚至可以表示计算机!
说到仅通过与非门的组合就能实现计算机,大家也许一下子很难相信。建议有兴趣的读者看一下《计算机系统要素:从零开始构建现代计算机》
2 层感知机(严格地说是激活函数使用了非线性的sigmoid 函数的感知机,具体请参照下一章)可以表示任意函数
2.7 小结
感知机是具有输入和输出的算法。
给定一个输入后,将输出一个既定的值。
感知机将权重和偏置设定为参数。
使用感知机可以表示与门和或门等逻辑电路。异或门无法通过单层感知机来表示。
使用2层感知机可以表示异或门。
单层感知机只能表示线性空间,而多层感知机可以表示非线性空间。
多层感知机(在理论上)可以表示计算机。