感知机 简介

感知机 简介一 感知机模型感知机 perceptron 是一种二分类的线性分类模型 它是一种监督式学习算法 感知机的输入为实例的特征向量 输出为实例的类别 取 1 和 1 感知机对应于输入空间中将实例划分为两类的分离超平面 S 感知机旨在求出该超平面 S 为求得超平面导入了基于误分类的损失函数 利用梯度下降法对损失函数进行最优化 最优化 感知机也是 NeuralNetwor 神经网络 和 S

一、感知机模型

感知机(perceptron)是一种二分类的线性分类模型,它是一种监督式学习算法。感知机的输入为实例的特征向量,输出为实例的类别(取+1和-1)。感知机对应于输入空间中将实例划分为两类的分离超平面 S。感知机旨在求出该超平面 S,为求得超平面导入了基于误分类的损失函数,利用梯度下降法对损失函数进行最优化(最优化)。

感知机也是 Neural Networks(神经网络)SVM(支持向量机) 的基础,它是一个单层神经网络。

感知机的模型如下:

f ( x ) = s i g n ( w ⋅ x + b ) f(x)=sign(w \cdot x+b) f(x)=sign(wx+b)

其中 w 叫做权值(weight)或权值向量(weight vector),b 叫做偏置(bias),sign 是符号函数,即:

sign ⁡ ( x ) = { + 1 x ≥ 0 − 1 x < 0 . \operatorname{sign}(x) = \begin{cases} +1 & x \geq 0 \\ -1 & x < 0 \end{cases}. sign(x)={
+11x0x<0
.

而分割超平面则为:

w ⋅ x + b = 0 w \cdot x+b = 0 wx+b=0

二、感知机的损失函数

1.这个损失函数怎么得到呢?

我们先考虑一下,正常最直接的想法就是损失函数嘛,直接用误分类的点的个数来表示不就好了吗,这样误分类的点越少,损失函数的值不就越小嘛。但是这样的函数显然是离散的,不是参数w和b的可导函数,不易优化。

然后再考虑一下所有误分类的点到分割超平面的距离之和作为损失函数,这样的函数貌似是连续可导的。那可行吗?实际上,确实感知机也是采用的这种损失函数。

(1)为此,我们先考察任意某一点到超平面的距离:

1 ∣ ∣ w ∣ ∣ ∣ w ⋅ x 0 + b ∣ (2.1) \frac{1}{||w||}|w \cdot x_0+b| \tag{2.1} w1wx0+b(2.1)

这里的 ∣ ∣ w ∣ ∣ ||w|| w 是 w 的 L 2 L_2 L2 范式, ∣ w ⋅ x 0 + b ∣ |w \cdot x_0+b| wx0+b表示绝对值。

(2)其次,对于任意一个误分类的点 ( x i , y i ) (x_i,y_i) (xi,yi) 来说,

− y i ( w ⋅ x i + b ) < 0 -y_i(w \cdot x_i+b) < 0 yi(wxi+b)<0

(3)因此,误分类的点 x i x_i xi 到超平面的距离可以写作:

− 1 ∣ ∣ w ∣ ∣ y i ( w ⋅ x i + b ) -\frac{1}{||w||}y_i(w \cdot x_i+b) w1yi(wxi+b)

这样就把公式2.1的绝对值去掉了,而 y i y_i yi 的取值只有 +1 或 -1,也不影响最终结果大小。

(4)最终,设误分类点得集合为 M ,则所有误分类的点到超平面的距离之和为:

− 1 ∣ ∣ w ∣ ∣ ∑ x i ∈ M y i ( w ⋅ x i + b ) -\frac{1}{||w||} \sum_{x_i \in M}{y_i(w \cdot x_i+b)} w1xiMyi(wxi+b)

不考虑 − 1 ∣ ∣ w ∣ ∣ -\frac{1}{||w||} w1 ,就可以得到感知机的损失函数了:

L ( w , b ) = − ∑ i = 1 M y i ( w ∗ x i + b ) L(w,b)=-\sum_{i=1}^{M} {y_i(w*x_i+b)} L(w,b)=i=1Myi(wxi+b)

显然,损失函数L(w,b)是非负的。如果没有误分类点,那么L(w,b)为0,误分类点数越少,L(w,b)值越小。一个特定的损失函数:在误分类时是参数w,b的线性函数,在正确分类时,是0。

2. 感知机学习算法

感知机学习的过程也就是它的损失函数不断优化达到最小值的过程。具体就是采用随机梯度下降法(SGD)。损失函数L(w,b)的梯度为:

∇ w L ( w , b ) = − ∑ i = 1 M y i   x i \nabla_w L(w,b)=-\sum_{i=1}^{M}y_i\:x_i wL(w,b)=i=1Myixi

∇ b L ( w , b ) = − ∑ i = 1 M y i \nabla_b L(w,b)=-\sum_{i=1}^{M}y_i bL(w,b)=i=1Myi

随机选出一个误分类点 ( x i , y i ) (x_i,y_i) (xi,yi),对参数 w,b进行更新:

w + η y i x i → w w+ \eta y_i x_i \rightarrow w w+ηyixiw
b + η y i → b b+ \eta y_i \rightarrow b b+ηyib

式中η(0≤η≤1)是步长,在统计学是中成为学习速率。步长越大,梯度下降的速度越快,更能接近极小点。如果步长过大,有可能导致跨过极小点,导致函数发散;如果步长过小,有可能会耗很长时间才能达到极小点。

具体算法过程如下:

输入训练集 T,学习率 η \eta η。输出 w,b 和 感知机模型 f ( x ) = s i g n ( w ⋅ x + b ) f(x)=sign(w \cdot x+b) f(x)=sign(wx+b)

(1)首先任选一个超平面,参数分别为 w 0 , b 0 w_0,b_0 w0,b0

(2)在训练集中任选一条数据 ( x i , y i ) (x_i,y_i) (xi,yi)

(3)如果 y i ( w ⋅ x i + b ) ≤ 0 y_i(w \cdot x_i+b) \leq 0 yi(wxi+b)0,则执行:

w + η y i x i → w w+ \eta y_i x_i \rightarrow w w+ηyixiw
b + η y i → b b+ \eta y_i \rightarrow b b+ηyib

(4)转至(2),直至训练集中没有误分类的点。

这种方法直观地解释就是:不断调整参数 w,b ,将超平面向当前选择的误分类点得方向移动(一个点可能会更新多次,最终使得误分类点分类正确为止),以减少误分类点,最终所有误分类点都被正确分类。

此外,感知机学习算法是可能有很多解的,为了得到唯一的超平面,就要对超平面增加约束条件,也就是 SVM 的想法。

三、实现代码

从输入参数得到训练文件和模型文件:

n = float(sys.argv[1]) trainFile = open(sys.argv[2]) modelFile= open(sys.argv[3], 'w') 

从训练文件中读取训练数据:

for line in trainFile: chunk = line.strip().split(' ') #每行的数据 lens = len(chunk) - 1 #最后一行是训练输出 tmp_all = [] tmp = [] for i in range(1, lens+1): tmp.append(int(chunk[i])) tmp_all.append(tmp) tmp_all.append(int(chunk[0])) training_set.append(tmp_all) trainFile.close() 

训练数据:

1 3 3 1 4 3 -1 1 1 

计算点到超平面的距离:

def cal(item): global w, b res = 0 for i in range(len(item[0])): res += item[0][i] * w[i] #w和xi的内积 res += b res *= item[1] return res 

判断是否是误分类点,如果是误分类点则更新参数:

for item in training_set: if cal(item) <= 0: flag = True update(item) 

使用随机梯度下降法更新参数:

def update(item): global w, b, lens, n #n就是学习速率η for i in range(lens): w[i] = w[i] + n * item[1] * item[0][i] b = b + n * item[1] 

PyTorch版感知机实现:

class Perceptron(nn.Module): def __init__(self, input_dim): super(Perceptron, self).__init__() self.fc1 = nn.Linear(input_dim, 1) def forward(self, x_in): return torch.sigmoid(self.fc1(x_in)).squeeze() perceptron = Perceptron(3) x = torch.Tensor([1,3,2]) f = perceptron.forward(x) print(f) 

输出:tensor(0.3471, grad_fn=)

四、感知机学习算法的对偶形式

感知机学习算法的对偶形式的基本思想就是将参数 w 和偏置 b用实例 x i x_i xi 和标签 y i y_i yi线性组合来表示。通过求解这个线性组合的系数来求得 w 和 b。这里还是设初值 w 0 , b 0 w_0,b_0 w0,b0 均为0。对误分类的点也还是按如下规则更新:

w + η y i x i → w w+ \eta y_i x_i \rightarrow w w+ηyixiw
b + η y i → b b+ \eta y_i \rightarrow b b+ηyib

如果对于某个误分类点 ( x i , y i ) (x_i,y_i) (xi,yi) ,我们通过上面这个规则更新了 n i n_i ni 次参数 w 和 b。那么 w 和 b 关于 ( x i , y i ) (x_i,y_i) (xi,yi) 的增量为: a i y i x i a_iy_ix_i aiyixi a i y i a_iy_i aiyi,由于每个点更新了 n i n_i ni 次,且学习率为 η \eta η,所以 a i = n i η a_i=n_i \eta ai=niη这里也就解释了下面具体算法过程中 a 每次只增加 η)。通过这个学习过程,最终 w 和 b 为:

w = ∑ i = 1 N a i y i x i w=\sum_{i=1}^{N} a_iy_ix_i w=i=1Naiyixi

b = ∑ i = 1 N a i y i b=\sum_{i=1}^{N} a_iy_i b=i=1Naiyi

由于 a i > 0 , i = 1 , 2 , . . . , N a_i > 0,i=1,2,…,N ai>0,i=1,2,...,N,所以当 η = 1 \eta=1 η=1 时, a i = n i a_i=n_i ai=ni 实际上就是第 i 个误分类点更新到正确之后所用的次数。某个误分类点更新次数越多,意味着它离超平面距离越近,也就越难分类正确。这样的点对感知机学习算法影响最大。

具体算法过程如下:

输入训练集 T,学习率 η \eta η。输出 a,b 和感知机模型 f ( x ) = s i g n ( ∑ j = 1 N a j y j x j ⋅ x + b ) f(x)=sign(\sum_{j=1}^{N} a_jy_jx_j \cdot x+b) f(x)=sign(j=1Najyjxjx+b)

(1) a ← 0 , b ← 0 a \leftarrow 0,b \leftarrow 0 a0,b0

(2) 任选误分类点 ( x i , y i ) (x_i,y_i) (xi,yi)

(3) 如果 y i ( ∑ j = 1 N a j y j x j ⋅ x + b ) ≤ 0 y_i(\sum_{j=1}^{N} a_jy_jx_j \cdot x+b) \leq 0 yi(j=1Najyjxjx+b)0,则更新:

a i ← a i + η a_i \leftarrow a_i+\eta aiai+η
b i ← b i + η y i b_i \leftarrow b_i+\eta y_i bibi+ηyi

(4)转至(2),直至训练集中没有误分类的点。

另外,可以看第三步的判断条件,说明每次都要判断实例的内积 ( x j ⋅ x i ) (x_j \cdot x_i) (xjxi),所以可以预先将训练集的实例之间的内积算出来并以矩阵形式表示,这就是所谓的 Gram 矩阵:

G = [ x i ⋅ x j ] N × N G = [x_i \cdot x_j]_{N \times N} G=[xixj]N×N


注:

[1]. 线性可分:存在超平面能够将所有的数据点完全划分到两侧。

[2]. 验证单层感知机不能表示异或逻辑

[3]. 异或运算(XOR):a⊕b = (¬a ∧ b) ∨ (a ∧¬b),如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。


参考:

[1]. 感知机(python实现)

[2]. 《统计学习方法(李航)》:感知机


THE END.

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/176516.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月26日 下午9:44
下一篇 2026年3月26日 下午9:44


相关推荐

  • STM32中的NVIC详解[通俗易懂]

    STM32中的NVIC详解[通俗易懂]转载自https://blog.csdn.net/wuyuzun/article/details/72783152NVIC的全称是Nestedvectoredinterruptcontroller,即嵌套向量中断控制器。对于M3和M4内核的MCU,每个中断的优先级都是用寄存器中的8位来设置的。8位的话就可以设置2^8=256级中断,实际中用不了这么多,所以芯片厂商…

    2022年5月8日
    255
  • 控件之combox

    控件之combox一 combox 显示 nbsp nbsp 首先 combox 有两个属性来存储数据 DisplayMembe 显示成员 ValueMember 值成员 DisplayMembe 是我们在 combox 界面上看到的 ValueMember 是隐藏的数据 一般来说我们只需要设置 DisplayMembe 属性的值即可 循环赋值 通过 combox Items Add 方法绑定数据 给 combox Da

    2026年3月19日
    2
  • CSS中关于滚动条样式设置的代码实例

    CSS中关于滚动条样式设置的代码实例因为在模拟开发冒险岛 2 游戏官网的时候 遇到一个关于滚动条样式设置的问题 如果我们不设置滚动条的样式 那么如下图所示 特别丑陋 但是在冒险岛的官网上呈现的样式却是 明显感觉到视觉上的不同 那么现在我们就来设置滚动条的样式 在所有浏览器 滚动条可定制性最强的当属 webkit 内核的浏览器了 因为源代码开放的原因 市面上基于 webkit 内核的浏览器也是很难穷举完 例如有 Goo

    2026年3月26日
    2
  • OpenSearch 简单学习

    OpenSearch 简单学习OpenSearch 简单学习项目中用到了阿里云的开放搜索 进行一下总结 OpenSearch 基于阿里巴巴自主研发的大规模分布式搜索引擎平台 该平台承载了阿里巴巴全部主要搜索业务 包括淘宝 天猫 一淘 1688 ICBU 神马搜索等业务 OpenSearch 以平台服务化的形式 将专业搜索技术简单化 低门槛化和低成本化 让搜索引擎技术不再成为客户的业务瓶颈 以低成本实现产品搜索功能并快速迭代

    2025年7月5日
    10
  • 2、工厂方法模式

    2、工厂方法模式

    2021年9月13日
    56
  • I2C之知(六)–s3c2440用I2C接口访问EEPROM

    I2C之知(六)–s3c2440用I2C接口访问EEPROM在前面阅读理解了I2C的官方协议文档后,就拿s3c2440和EEPROM来验证一下.    本来是想用s3c2440的SDA和SCL管脚复用为GPIO来模拟的,但在没有示波器的情况下搞了一周,怎么都出不来,最后还是放弃了.甚至参考了linux下i2c-algo-bit.c和i2c-gpio.c,依然没调出来.如果有示波器,可能很快就能找到原因,现在完全不知道问题出在哪里.其实想用GPI

    2022年5月31日
    34

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号