1. 背景
学习传统机器学习或者深度学习往往都绕不开感知机,所以结合查阅资料和手动推导,做如下总结。
2. 名词解释
感知机是一种最简单的人工神经元模型,也是神经网络的基本构成单元之一。它由输入、权重、偏置和输出组成。感知机的输入可以是任意数量的二进制数,这些输入通过权重与偏置相加,然后通过激活函数进行非线性变换,得到一个二进制的输出结果。其中,权重用于调整每个输入的重要性,而偏置则用于调整输出的阈值。感知机的训练过程就是调整权重和偏置的过程。训练数据被送入感知机,如果感知机的输出与期望的输出不同,则通过梯度下降等优化算法来调整权重和偏置,使得感知机更准确地预测。
虽然感知机只能解决线性问题,但它为神经网络的发展奠定了基础,后来的多层神经网络(即深度学习)也是在感知机的基础上发展而来。现在,感知机已经被广泛应用于模式识别、图像处理、自然语言处理和人工智能等领域。它被认为是一种强大的工具,可以模拟人脑神经元的计算机制,对于解决大规模数据分类和预测等问题有着重要的作用。
在现代深度学习网络中,感知机的概念仍然起着重要的作用。深度学习网络通常由多个层次的神经元组成,每个神经元都有一个权重向量,用于将输入信号转换为输出信号。这种权重向量的计算方式与感知机的权重向量计算方式类似。
此外,深度学习网络中的激活函数也是感知机中激活函数的一种扩展。在深度学习中,激活函数的作用是将神经元的输入信号转换为输出信号,同时引入非线性因素,使得网络能够学习复杂的模式和规律。常见的激活函数包括ReLU、Sigmoid和Tanh等。
总之,感知机是神经网络领域的一个重要概念,它在现代深度学习网络中仍然发挥着重要的作用。深度学习网络中的许多概念和算法都是基于感知机的发展而来的。
3. 一句话概括
感知机是一个线性分类模型,其目的是在N维空间中,找一个超平面将数据集正确分类
4. 定义
已知数据集
其中
,表示x是n维的实数向量
找一张图形象描述向量,如下图红线描述了一个三维向量[a, b, c]
,表示y是x的标签,即x输入红球还是绿球
,i表示数据下标
5. 超平面公式
其中表示超平面的法向量的转置
引申:法向量表示与平面垂直的向量
推导
因为是超平面的法向量,所以和特征点x的点积表示x在各个维度的加权求和
点积指的的是向量各维度的数据相乘然后相加得到一个标量
因此超平面公式 描述的是“设置合适的w和b,使得特征x到某个面的距离为0,则认为点在超平面上,这些点组成超平面
6. 感知机是误分类驱动的
感知机是误分类驱动的解释:当对于初始参数w和b,随机选取一个实例,如果被误分类,此时应沿着梯度方向更新参数w和b(具体更新多少需要定义一个步长即学习率),来使分离超平面向误分类点移动(移动快慢与学习率有关),从而减少该误分类点与超平面间的距离。这样不断地随机取实例——判断是否误分类——是否更新参数w和b,直至超平面越过所有误分类点使数据集被完全正确分类。
一句话概括就是感知机通过不断优化,使得误分类的数量逐步减少
对于所有误分类的点,都有公式满足
其中表示对应的标签,比如 “第1号球是绿球”
表示对预测的结果,由于是误分类的点,所以和肯定异号,所以
所以误分类点到超平面的距离
推导:
是真实分类[-1, +1], 表示对预测的结果,
由于是误分类的点,所以和肯定异号,所以
然后除以表示除以超平面法向量的模,当w表示单位向量时,得到的是误分类点到超平面的距离
7. 感知机的损失函数
即所有误分类点到超平面的距离之和
可以简化为
感知机模型的损失函数推导过程中省掉分母的超平面的法向量的模,是因为误分类点到超平面的距离是计算感知机损失的关键度量。在推导过程中,为了方便计算,省去了分母中的超平面的法向量的模,这样可以简化损失函数的计算。
8. 用梯度下降法计算梯度
由于感知机的损失函数表示为
所以对损失函数进行梯度下降即是对w和b分别求偏导
9. 感知机训练过程的简单描述
1. 输入数据
其中
,表示x是n维的实数向量
,表示y是x的标签,比如x输入红球还是绿球
,i表示数据下标
2. 超参数 ,lr表示Learning rate,表示感知机每次更新参数的幅度
3. 随机选取点
4. 计算其是否是误分类点,即
5. 如果是误分类点,则更新参数
通过第8节已知
所以每次更新参数为
6. 跳转到第三步继续选点,直到误分类点为0
10. 单层感知机的Python实现
import numpy as np
import matplotlib.pyplot as plt
def main():
'''生成一个100行2列的随机数矩阵,
其中每个元素都是从标准正态分布(均值为0,方差为1)中随机采样得到的。
也可以理解为在二维空间中随机生成100个点,这些点的横坐标和纵坐标都是从标准正态分布中随机生成的。
这是用于训练单层感知机的样本特征矩阵,每行代表一个样本的特征,每列代表一种特征。'''
#X = np.random.randn(1000, 2)
X = np.random.randint(-10, 10, (100, 2))
'''根据输入数据 X 生成对应的标签 y。其中 x1 和 x2 分别表示样本的两个特征,
这里的目的是为了生成一个二分类任务的标签,使得单层感知机可以通过学习来对样本进行分类。
最终得到的 y 是一个包含100个元素的一维数组,其中每个元素是1或-1,表示对应样本的标签。'''
y = np.array([1 if x1 + x2 >= 0 else -1 for x1, x2 in X])
# 训练模型
weights, bias, mis_points = perceptron(X, y)
# 绘制决策边界和误分类点
'''决策边界就是把训练结果用函数表达出来 。
根据感知机的分类公式:w1 * x1 + w2 * x2 + b = 0
得到:x2 = (-w1 * x1 - b) / w2
这里计算的x2指的纵坐标,这样针对x1每个点计算决策值,通过plt.plot绘制结果。'''
x1 = np.arange(-10, 10, 0.1)
x2 = (-weights[0] * x1 - bias) / weights[1]
plt.plot(x1, x2, 'r', label='Decision Boundary')
for x, y, label in mis_points:
if label == 1:
plt.plot(x, y, 'bo')
else:
plt.plot(x, y, 'ro')
plt.legend()
plt.show()
return
'''将要定义一个训练函数 perceptron,使用变量n_iter表示迭代次数。
每迭代一次,感知机会用当前的权重对样本进行预测,并计算预测值与真实标签之间的误差。
然后根据误差值来调整权重,以期望能够使预测结果更加接近真实标签。
n_iter 值越大,训练时间越长,可能会使得感知机的性能提高,但也会增加过拟合的风险。
在实际应用中,我们需要根据具体情况来调整 n_iter 的值。'''
def perceptron(X, y, lr=0.1, n_iter=100):
# 获取样本数量和特征数量
n_samples, n_features = X.shape
# 初始化权重和偏置为0
weights = np.zeros(n_features)
bias = 0.0
# 记录误分类点以及迭代次数
mis_points = []
for _ in range(n_iter):
# 标记是否有误分类点
mis_flag = False
for i in range(n_samples):
# 计算预测值
y_pred = np.dot(weights, X[i]) + bias
# 根据预测值和真实值调整权重和偏置
if y_pred * y[i] <= 0:
# 根据误差进行权重和偏置的更新
weights += lr * y[i] * X[i]
bias += lr * y[i]
# 标记有误分类点
mis_flag = True
mis_points.append((X[i, 0], X[i, 1], y[i]))
# 如果没有误分类点,则提前结束迭代
if not mis_flag:
break
# 返回训练好的权重和偏置以及误分类点
return weights, bias, mis_points
if (__name__ == "__main__"):
main()
训练结果