感知机
- 一、感知机是什么
- 二、用感知机搭建简单逻辑电路
- 2.1 与门
- 2.2 与非门
- 2.3 或门
- 三、感知机的局限性
- 3.1 异或门
- 3.2 线性和非线性
- 四、多层感知机
- 4.1 已有门电路的组合
- 4.2 Python异或门的实现
- 五、感知机模型
- 5.1 感知机模型
- 5.2 感知机损失函数
- 5.3 感知机学习算法
- 六、感知机原始形式、对偶形式算法描述
- 6.1 原始形式
- 6.2 对偶形式
- 6.3 原始形式和对偶形式的选择
一、感知机是什么
感知机接收多个信号输出一个信号。如图所示,是一个接收两个输入信号 ( x 1 、 x 2 ) (x_1、x_2) (x1、x2)的感知机的例子,y是输出信号。图中的○称为“神经元”或者“节点”。输入信号被送往神经元时,会被分别乘以固定的权重 ( w 1 x 1 、 w 2 x 2 ) (w_1x_1、 w_2x_2) (w1x1、w2x2),权重代表了该信号的重要程度。神经元会计算传送过来的信号的总和,只有当这个总和超过了某个界限值时,才会输出1。这也称为“神经元被激活” 。这里将这个界限值称为阈值,用符号 θ θ θ表示。
图1 两个输入的感知机
把上述内容用数学来表达,就是下面的公式:
y
=
{
0
if
w
1
x
1
+
w
2
x
2
≤
θ
1
if
w
1
x
1
+
w
2
x
2
>
θ
y=\begin{cases} 0 & \text{if} \ w_1x_1+w_2x_2 \leq \theta \\ 1 & \text{if} \ w_1x_1+w_2x_2 > \theta \end{cases}
y={01if w1x1+w2x2≤θif w1x1+w2x2>θ
感知机的每个输入信号都有各自的权重,表示该信号发挥重要性的作用,也就是说权重越大,对应该权重的信号越重要。
二、用感知机搭建简单逻辑电路
2.1 与门
知道了上面那些概念,那如何用感知机来解决简单的问题呢?这里首先以逻辑电路为题材来思考一下与门(AND gate)。与门是有两个输入和一个输出的门电路。下图这种输入信号和输出信号的对应表称为“真值表”。如图所示,与门仅在两个输入均为1时输出1,其他时候则输出0。
图2 与门真值表
考虑用感知机来表示这个与门,需要做的就是确定能满足图2中的真值表的 w 1 w1 w1、 w 2 w2 w2、 θ θ θ的值。那么,设定什么样的值才能制作出满足图中条件的感知机呢?实际上,满足上图条件的参数选择方法有无数多个。比如,当 ( w 1 , w 2 , θ ) = ( 0.5 , 0.5 , 0.7 ) (w1, w2, θ) = (0.5, 0.5, 0.7) (w1,w2,θ)=(0.5,0.5,0.7)时,可以满足图中条件。此外,当 ( w 1 , w 2 , θ ) (w1, w2, θ) (w1,w2,θ)为 ( 0.5 , 0.5 , 0.8 ) (0.5, 0.5, 0.8) (0.5,0.5,0.8)或者 ( 1.0 , 1.0 , 1.0 ) (1.0, 1.0, 1.0) (1.0,1.0,1.0)时,同样也满足与门的条件。设定这样的参数后,仅当x1和x2同时为1时,信号的加权总和才会超过给定的阈 θ θ θ。
事实上,图2 与门真值表在坐标轴上画出来是如图3的形式。当输入(0,0)、(0,1)、(1,0)时,输出为0;当输入(1,1)时,输出为1,这其实是一个二分类问题,即找到一个超平面,将正例负例区分,可以看到满足条件的超平面有无数多个,而超平面由参数w1,w2确定。超平面可以表示为 f ( x 1 , x 2 ) = w x 1 + w x 2 f(x_1, x_2)=wx_1+wx_2 f(x1,x2)=wx1+wx2。
图3 与门的感知机示例
感知机实现与门
def AND(x1: int, x2: int) -> int:
w1, w2, theta = 0.5, 0.5, 0.7
if w1 * x1 + w2 * x2 <= theta:
return 0
else:
return 1
def test_AND():
print(AND(0, 0))
print(AND(0, 1))
print(AND(1, 0))
print(AND(1, 1))
if __name__ == '__main__':
test_AND()
AND(0, 0) # 输出0
AND(1, 0) # 输出0
AND(0, 1) # 输出0
AND(1, 1) # 输出1
2.2 与非门
接着,我们再来考虑一下与非门(NAND gate)。NAND是Not AND的意思,与非门就是颠倒了与门的输出。用真值表表示的话,如下图所示,仅当x1和x2同时为1时输出0,其他时候则输出1。
图4 与非门真值表
要表示与非门,可以用 ( w 1 , w 2 , θ ) = ( − 0.5 , − 0.5 , − 0.7 ) (w1, w2, θ) = (−0.5, −0.5, −0.7) (w1,w2,θ)=(−0.5,−0.5,−0.7)这样的组合(其他的组合也是无限存在的)。实际上,只要把实现与门的参数值的符号取反,就可以实现与非门。
import numpy as np
def NADN(x1, x2):
# 与非门
x = np.array([x1, x2])
w = np.array([-0.5, -0.5])
b = 0.7
if np.sum(w * x) + b <= 0:
return 0
else:
return 1
def test_NAND():
print(NADN(0, 0))
print(NADN(0, 1))
print(NADN(1, 0))
print(NADN(1, 1))
if __name__ == '__main__':
test_NAND()
1
1
1
0
2.3 或门
接下来咱们再来看一下下面这张图所示的或门。或门是“只要有一个输入信号是1,输出就为1”的逻辑电路。
图4 与非门真值表
import numpy as np
def OR(x1: int, x2: int) -> int:
x = np.array([x1, x2])
w = np.array([0.5, 0.5])
b = -0.2
if np.sum(w * x) + b <= 0:
return 0
else:
return 1
def test_OR():
print(OR(0, 0))
print(OR(0, 1))
print(OR(1, 0))
print(OR(1, 1))
if __name__ == '__main__':
test_OR()
0
1
1
1
如上所示,我们已经知道使用感知机可以表示与门、与非门、或门的逻辑电路。这里重要的一点是:与门、与非门、或门的感知机构造是一样的。实际上, 3个门电路只有参数的值(权重和阈值)不同。也就是说,相同构造的感知机,只需通过适当地调整参数的值,就可以像“变色龙演员”表演不同的角色一样,变身为与门、与非门、或门。
三、感知机的局限性
3.1 异或门
到这里我们已经知道,使用感知机可以实现与门、与非门、或门三种逻辑电路。现在我们来考虑一下异或门(XOR gate)。
异或门也被称为逻辑异或电路。如图5所示,仅当 x 1 x_1 x1或 x 2 x_2 x2中的一方为1时,才会输出1(“异或”是拒绝其他的意思)。那么,要用感知机实现这个异或门的话,应该怎么设定权重参数呢?
图5 异或门真值表
实际上,用前面介绍的感知机是无法实现这个异或门的(应该是“单层感知机无法表示异或门”或者“单层感知机无法分离非线性空间”)。为什么用感知机可以实现与门、或门,却无法实现异或门呢?从坐标轴就可以看出,无法找到一条直线,将两类点区分开。
3.2 线性和非线性
图5中的 ◯ \bigcirc ◯和 △ \bigtriangleup △无法用一条直线分开,但是如果将“直线”这个限制条件去掉,就可以实现了。比如,我们可以像图3那样,作出分开○和△的空间。
感知机的局限性就在于它只能表示由一条直线分割的空间。图8这样弯曲的曲线无法用感知机表示。另外,由图8这样的曲线分割而成的空间称为非线性空间,由直线分割而成的空间称为线性空间。线性、非线性这两个术语在机器学习领域很常见,可以将其想象成图6和图8所示的直线和曲线。
四、多层感知机
感知机不能表示异或门让人深感遗憾,但也无需悲观。实际上,感知机的绝妙之处在于它可以“叠加层”(通过叠加层来表示异或门是本节的要点)。
4.1 已有门电路的组合
异或门的制作方法有很多,其中之一就是组合我们前面做好的与门、与非门、或门。
4.2 Python异或门的实现
import numpy as np
def AND(x1: int, x2: int) -> int:
w1, w2, theta = 0.5, 0.5, 0.7
if w1 * x1 + w2 * x2 <= theta:
return 0
else:
return 1
def NADN(x1, x2):
# 与非门
x = np.array([x1, x2])
w = np.array([-0.5, -0.5])
b = 0.7
if np.sum(w * x) + b <= 0:
return 0
else:
return 1
def OR(x1: int, x2: int) -> int:
x = np.array([x1, x2])
w = np.array([0.5, 0.5])
b = -0.2
if np.sum(w * x) + b <= 0:
return 0
else:
return 1
def XOR(x1, x2):
s1 = NADN(x1, x2)
s2 = OR(x1, x2)
y = AND(s1, s2)
return y
if __name__ == '__main__':
print(XOR(0, 0))
print(XOR(0, 1))
print(XOR(1, 0))
print(XOR(1, 1))
0
1
1
0
这样,异或门的实现就完成了。下面我们试着用感知机的表示方法(明
确地显示神经元)来表示这个异或门:
实际上,与门、或门是单层感知机,而异或门是2层感知机。叠加了多
层的感知机也称为多层感知机(multi-layered perceptron)。
这种2层感知机的运行过程可以比作流水线的组装作业。第1段(第1层)
的工人对传送过来的零件进行加工,完成后再传送给第2段(第2层)的工人。第2层的工人对第1层的工人传过来的零件进行加工,完成这个零件后出货(输出)。
像这样,在异或门的感知机中,工人之间不断进行零件的传送。通过这样的结构(2层结构),感知机得以实现异或门。这可以解释为“单层感知机无法表示的东西,通过增加一层就可以解决”。也就是说,通过叠加层(加深层),感知机能进行更加灵活的表示。
五、感知机模型
感知机(perceptron)是二分类的线性分类模型,属于监督学习算法。输入为实例的特征向量,输出为实例的类别(取+1和-1)。感知机旨在求出将输入空间中的实例划分为两类的分离超平面。为求得超平面,感知机导入了基于误分类的损失函数,利用梯度下降法对损失函数进行最优化求解。
5.1 感知机模型
感知器是一种简单的两类线性分类模型,给定
N
N
N个样本的训练集
{
x
i
,
y
i
}
i
=
1
N
\{x_i,y_i\}_{i=1}^N
{xi,yi}i=1N,其中
y
i
∈
{
+
1
,
−
1
}
y_i \in \{+1, -1\}
yi∈{+1,−1},感知机模型为:
y
=
sign
(
w
T
x
)
y=\text{sign}(w^{\text{T}} x)
y=sign(wTx),
其中,w为感知机模型参数,确定超平面;符号函数
sign
(
z
)
=
{
+
1
z
≥
0
−
1
z
<
0
\text {sign}(z)= \begin{cases} +1 & z \geq 0 \\ -1 & z < 0 \\ \end{cases}
sign(z)={+1−1z≥0z<0
感知机模型可以用如下图表示。
感知机模型的超平面将正负样本点分为两类,即对所有的
y
i
=
+
1
y_i=+1
yi=+1的样本
x
i
x_i
xi,都有
w
x
i
>
0
wx_i>0
wxi>0;对所有的
y
i
=
−
1
y_i=-1
yi=−1的样本
x
i
x_i
xi,都有
w
x
i
<
0
wx_i<0
wxi<0
5.2 感知机损失函数
假设训练数据集是线性可分的,为了找出一个能够将训练数据集正实例点和负实例点完全正确分开的超平面,即确定感知机模型参数w,需要确定一个学习策略,即定义(经验)损失函数,并将损失函数极小化。
损失函数的一个自然选择是误分类点的总数,但是这样的函数不是连续可导函数,不易优化。因此感知机采用的损失函数是误分类点到超平面的总距离。
假设直线方程为 A x + B y + C = 0 Ax + By + C = 0 Ax+By+C=0 ,点 P P P的坐标为 ( x 0 , y 0 ) ( x_0 , y_0 ) (x0,y0)。点到直线的距离公式为:
d = A x 0 + B y 0 + C A 2 + B 2 d=\frac{Ax_0 + By_0 + C}{\sqrt{A^2+B^2}} d=A2+B2Ax0+By0+C
假设超平面是 w T x + b w^\text Tx+b wTx+b,则样本点 x ′ x^\prime x′到超平面的距离是:
d = w T x ′ + b ∣ ∣ w ∣ ∣ d=\frac{w^\text T x^\prime +b}{||w||} d=∣∣w∣∣wTx′+b
任意一个样本点
x
i
x_i
xi到超平面
S
S
S的距离为:
∣
w
T
x
i
+
b
∣
∣
∣
w
∣
∣
\frac{|w^ \text T x_i+b|}{||w||}
∣∣w∣∣∣wTxi+b∣
对于误分类点
(
x
i
,
y
i
)
(x_i,y_i)
(xi,yi):
−
y
i
(
w
T
x
+
b
)
=
∣
w
T
x
i
+
b
∣
>
0
-y_i(w^ \text T x+b) =|w^ \text T x_i+b| > 0
−yi(wTx+b)=∣wTxi+b∣>0
因此,误分类点
x
i
x_i
xi到超平面
S
S
S的距离为:
−
1
∣
∣
w
∣
∣
y
i
(
w
T
x
+
b
)
-\frac{1}{||w||}y_i(w^ \text T x+b)
−∣∣w∣∣1yi(wTx+b)
假设误分类点集合为
M
M
M,那么所有误分类点到超平面
S
S
S的距离之和为:
−
1
∣
∣
w
∣
∣
∑
x
i
∈
M
y
i
(
w
T
x
i
+
b
)
-\frac{1}{||w||}\sum_{x_i \in M} y_i(w^\text T x_i+b)
−∣∣w∣∣1xi∈M∑yi(wTxi+b)
不考虑 1 ∣ ∣ w ∣ ∣ \frac{1}{||w||} ∣∣w∣∣1,将 b b b吸收到 w w w里面,则损失函数为 L ( w ) = ∑ x i ∈ M − y i w T x i L(w)=\sum_{x_i \in M} -y_iw ^\text Tx_i L(w)=xi∈M∑−yiwTxi
至此,感知机学习问题就转化为了求解损失函数的最优化问题。
5.3 感知机学习算法
感知器的学习算法是一种错误驱动(犯错时才更新参数,不犯错不更新)的在线学习算法(样本是流式的一个个过来的)。
由于感知机学习算法是误分类驱动的,这里基于随机梯度下降法(SGD)进行优化求解。即任意选取一个超平面 w 0 w_0 w0,然后用梯度下降法不断地极小化损失函数。极小化过程中不是一次使M MM中的所有误分类点的梯度下降,而是一次随机选取一个误分类点使其梯度下降。
这里不能使用基于所有样本的批量梯度下降(BGD)进行优化。这是因为我们的损失函数里面有限定,只有误分类的M MM集合里面的样本才能参与损失函数的优化。所以我们不能用最普通的批量梯度下降,只能采用随机梯度下降(SGD)或者小批量梯度下降(MBGD)。
损失函数
L
(
w
)
L(w)
L(w)的梯度为:
∇
L
(
w
)
=
−
∑
x
i
∈
M
y
i
x
i
\nabla L(w)=-\sum_{x_i \in M}y_ix_i
∇L(w)=−xi∈M∑yixi
随机选取一个误分类点
(
x
i
,
y
i
)
(x_i,y_i)
(xi,yi),对w进行更新:
w
←
w
+
α
y
i
x
i
w \leftarrow w+\alpha y_ix_i
w←w+αyixi
六、感知机原始形式、对偶形式算法描述
6.1 原始形式
输入:训练集
{
x
i
,
y
i
}
i
=
1
N
\{x_i,y_i\}_{i=1}^N
{xi,yi}i=1N,学习率
α
∈
(
0
,
1
)
\alpha \in (0,1)
α∈(0,1)
输出:参数w,感知机模型
f
(
x
)
=
sign
(
w
T
x
)
f(x)=\text{sign}(w^ \text{T}x)
f(x)=sign(wTx)
步骤:
- 随机选取初值 w 0 w_0 w0
- 在训练数据集中选取数据 ( x i , y i ) (x_i,y_i) (xi,yi)
- 判断该数据点是否为当前模型的误分类点,即 y i w T x i ≤ 0 y_iw^\text{T}x_i \leq 0 yiwTxi≤0,如果是误分类点则进行更新: w ← w + α y i x i w \leftarrow w+\alpha y_ix_i w←w+αyixi
- 转到第(2)步,直到训练集中没有误分类点。
【注】感知机学习算法由于采用不同的初值或选取不同的误分类点,解可以不同。
6.2 对偶形式
前面介绍了感知机算法的原始形式,下面要介绍的对偶形式是对算法执行速度的优化。
6.3 原始形式和对偶形式的选择
- 如果特征数过高,计算内积非常耗时,应选择对偶形式算法加速。
- 如果样本数过多,每次计算累计和就没有必要,应选择原始算法。
参考:
- https://blog.csdn.net/pxhdky/article/details/86360535