一、感知机

1 神经元模型

神经网络的最基本单元为神经元,灵感来自于生物学中的神经细胞。生物神经元与其他神经元相连,当某个神经元“激活”时,就会向相连的神经元发送化学物质(或电信号),从而改变这些神经元的电位,许多神经元彼此相连构成一张庞大的神经网络。

“激活”指的是某个神经元收到的“刺激”到达一定阈值之后,就会“兴奋”,反之则不会发生任何动作。人工神经网络中的实现中,“M-P”模型沿用至今。在这个模型中, 神经元接收个其他神经元传递的信号,这些信号通过带权重的连接进行传递,神经元接收到的总输入值将与神经元的阀值进行比较,然后通过“激活函数“ 处理以产生神经元的输出。

理想的激活函数为阶跃函数:它将输入映射为0和1,0表示神经元抑制,1表示神经元兴奋。把许多个这样的神经元按一定的层次结构连接起来,就得到了神经网络。

2 感知机模型

2.1 模型建立

感知机由两层神经元组成,模型可以表示为:其中,为样本的特征向量,是感知机模型的输入;是感知机模型的参数,为权重,为阈值。在感知机模型中,可以理解为控制着输入参数的重要性,偏置则调整了神经元被激活的容易程度,举例来说,若,则表示输入信号的加权总和只需要大于即可激活该神经元,若,则加权总和需要大于

上式中的通常设为阶跃函数,那么感知机模型的公式可进一步表示为由于维空间中的超平面方程为,所以此时感知机模型公式中的可以看作是维空间中的一个超平面,通过它将维空间划分为两个子空间,落在前一个子空间的样本对应的模型输出值为1,落在后一个子空间的样本对应的模型输出值为0,以此来实现分类功能。

2.2 学习策略

现在假设给定一个线性可分的数据集,感知机的学习目标是求得能对数据集中的正负样本完全正确划分的分离超平面:假设此时误分类样本集合为,对任意一个误分类样本来说,当时,模型输出值为,样本真实标记为;反之,当时,模型输出值为,样本真实标记为。综合两种情形可知,以下公式恒成立:所以,给定数据集,其损失函数可以定义为:显然,此损失函数是非负的。如果没有误分类点,损失函数值是0。而且,误分类点越少,误分类点离超平面越近,损失函数值就越小。因此,给定数据集,损失函数是关于的连续可导函数。

2.3 学习算法

感知机模型的学习问题可以转化为求解损失函数的最优化问题,具体地,给定数据集,其中,求参数,使其为极小化损失函数的解:其中为误分类样本集合。若将阈值看作一个固定输入为的“哑节点”,将偏置吸入向量内,类似于线性回归模型:其中。根据该式,可将要求解的极小化问题进一步简化为:假设误分类样本集合固定,那么可以求得损失函数的梯度为:感知机的学习算法具体采用的是随机梯度下降法,也就是极小化过程中不是一次使中所有误分类点的梯度下降,而是一次随机选取一个误分类点使其梯度下降。所以权重的更新公式为:因此中的某个分量的更新公式为:

3 逻辑电路

简单逻辑电路主要有与门、或门、非门等,感知机可以轻松地表示与或非门,下面尝试用代码实现它们。

3.1 与门

满足与门的组合有无数种,这里只是其中的一种:

1
2
3
4
5
6
7
8
9
10
11
12
13
def And(x1, x2):
w1, w2, theta = 1, 1, 2
s = w1 * x1 + w2 * x2 - theta
if s >= 0:
return 1
else:
return 0


print(And(0, 0)) # 0
print(And(0, 1)) # 0
print(And(1, 0)) # 0
print(And(1, 1)) # 1

3.2 或门

1
2
3
4
5
6
7
8
9
10
11
12
13
def Or(x1, x2):
w1, w2, theta = 1, 1, 0.5
s = w1 * x1 + w2 * x2 - theta
if s >= 0:
return 1
else:
return 0


print(Or(0, 0)) # 0
print(Or(0, 1)) # 1
print(Or(1, 0)) # 1
print(Or(1, 1)) # 1

3.3 非门

1
2
3
4
5
6
7
8
9
10
11
def Not(x1):
w1, w2, theta = -1, 0, -0.5
s = w1 * x1 + w2 * 0 - theta
if s >= 0:
return 1
else:
return 0


print(Not(1)) # 0
print(Not(0)) # 1

3.4 感知机的局限性

无论是与或非门,感知机的构造是一样的,三个门电路的差别仅在于不同。但是并非所有的门电路都可以由上面的感知机表示,考虑异或门:当输入相同时,输出0,当输入不同时,输出1。

实际上,使用前面的即只拥有一层神经元的感知机模型无法表示异或门,这是因为异或门并非是线性可分的,参考下图:

image-20240327225842527

无法找到一个超平面(本例中是直线)使得异或门输出空间线性可分。

3.5 多层感知机

单层的感知机过于简单,无法表示异或门。但是感知机可以进行叠加,也就是需考虑多层神经元,例如,使用两层感知机就能解决异或问题。重新考虑我们之前实现的与、或、非门,通过逻辑电路的组合可以发现,异或门可以通过组合一个或门加一个与非门再加一个与门实现:

image-20240327230747810

其中,与非门可以视作与门+非门,所以异或门也可以视作是由两个与门+或门+非门构成:

image-20240327230846286

现在,尝试使用代码来实现异或门:

1
2
3
4
5
6
7
8
9
10
11
def XOR(x1, x2):
t1 = Or(x1, x2)
t2 = And(x1, x2)
nand = Not(t2)
return And(t1, nand)


print(XOR(0, 0)) # 0
print(XOR(0, 1)) # 1
print(XOR(1, 0)) # 1
print(XOR(1, 1)) # 0

如果说仅通过与、或、非门组合就能够实现一台计算机,可能会令人难以置信。但是实际上半加器就是由这些基本门电路组合而成的,这足以说明只要组合足够复杂,使用感知机也可以实现计算机。组合基本门电路的过程,就相当于将多个神经元叠加起来。

image-20240327231752817

这个多层感知机有4个输入,3个输出,其隐藏层包含5个隐藏单元。输入层不涉及任何计算,因此使用此网络产生输出只需要实现隐藏层和输出层的计算。 因此,这个多层感知机中的层数为2。 注意,这两个层都是全连接的,全连接是指每层神经元与下层神经元全互连。 每个输入都会影响隐藏层中的每个神经元, 而隐藏层中的每个神经元又会影响输出层中的每个神经元。

二、神经网络

1 非线性

激活函数一般都是非线性的。

我们通过矩阵来表示个样本的小批量, 其中每个样本具有个输入特征。 对于具有个隐藏单元的单隐藏层多层感知机, 用表示隐藏层的输出, 称为隐藏表示(hidden representations)。 在数学或代码中,也被称为隐藏层变量(hidden-layer variable) 或隐藏变量(hidden variable)。 因为隐藏层和输出层都是全连接的, 所以我们有隐藏层权重和隐藏层偏置以及输出层权重和输出层偏置

形式上,我们按如下方式计算单隐藏层多层感知机的输出在添加隐藏层之后,模型现在需要跟踪和更新额外的参数。 可我们能从中得到什么好处呢?在上面定义的模型里,我们没有好处。原因很简单:上面的隐藏单元由输入的仿射函数给出, 而输出只是隐藏单元的仿射函数。 仿射函数的仿射函数本身就是仿射函数, 但是我们之前的线性模型已经能够表示任何仿射函数。因此这本质上就是单层的感知机。我们可以证明这一等价性,即对于任意权重值, 我们只需合并隐藏层,便可产生具有参数的等价单层模型:可以看出非线性很关键,为了发挥多层架构的潜力,我们还需要在仿射变换之后对每个隐藏单元应用非线性的激活函数,一般用表示。一般来说,有了激活函数,就不可能再将我们的多层感知机退化成线性模型。

2 常用激活函数

前面提到感知机的激活函数为阶跃函数,但是它具有不连续、不光滑等不太好的数学性质,因此一般都采用其他的函数代替,这些激活函数一般具有比较好的数学性质,比如它们一般是连续可微函数,由于激活函数是深度学习的基础,下面简要介绍一些常见的激活函数。

2.1 sigmoid函数

sigmoid定义如下:sigmoid函数将输入变换为区间(0, 1)上的输出。 因此,sigmoid通常称为挤压函数(squashing function): 它将范围(-inf, inf)中的任意输入压缩到区间[0,1]中的某个值。

[1]: 周志华. 机器学习[M]. 北京: 清华大学出版社, 2016-1-1.

[2]: 阿斯顿·张(Aston Zhang) / 李沐(Mu Li) / [美] 扎卡里·C. 立顿(Zachary C. Lipton) / [德] 亚历山大·J. 斯莫拉(Alexander J. Smola) 动手学深度学习[M]. 北京: 人民邮电出版社, 2019-6.