感知机:教程,实现和可视示例(感知机定义)
ztj100 2024-11-11 15:14 13 浏览 0 评论
感知器是人工神经网络的组成部分,它是大脑中生物神经元的简化模型。感知器是最简单的神经网络,仅由一个神经元组成。感知器算法由Frank Rosenblatt于1958年发明。
以下是生物神经元的图示:
经由树突接收到神经元的大部分输入信号。其他神经元与这些树突形成约1,000至10,000个连接。来自连接的信号称为突触,通过树突传播到细胞体内。细胞体内的电位增加,一旦达到阈值,神经元就会沿着轴突发出一个尖峰,该轴突通过轴突末端连接到大约100个其他神经元。
感知器是真实神经元的简化模型,它尝试通过以下过程来模仿它:接收输入信号,将它们称为x1,x2,…,xn,计算这些输入的加权和z,然后将其传递阈值函数?并输出结果。
但将w0作为阈值和将w0作为偏置添加到和中并将阈值改为0是一样的。我们考虑一个始终设置为1的附加输入信号x0。
下面是一个感知器:
要使用向量表示法,我们可以将所有输入x0、x1、…、xn和所有权重w0、w1、…、wn放入向量x和w中,当它们的点积为正时输出1,否则输出-1。
以下是仅使用2个输入x1和x2的几何表示,以便我们可以在2维中绘制:
如上所示,具有2个输入的感知器的决策边界是一条直线。如果有3个输入,则决策边界为二维平面。一般来说,如果我们有n个输入,决策边界将是一个称为n-1维的超平面,该超平面将我们的n维特征空间分成两部分:一部分是将点分类为正的,另一部分是将点分类为负的(按照惯例,我们将认为恰好在决策边界上的点是负的)。因此,感知器是一个二元分类器,其权值是线性的。
在上面的图像中,w'表示没有偏移项w0的权重向量。w'垂直于决策边界并指向正分类点的性质。该向量决定了决策边界的斜率,而偏移项w0决定了决策边界沿w'轴的偏移。
到目前为止,我们讨论了感知器如何根据输入信号及其权值做出决策。但是,感知者实际上是如何学习的呢?如何找到合适的参数w0,w1,…,wn,以便进行良好的分类?
感知器算法是基于以下简单更新规则的迭代算法:
其中y是当前数据点x的标签(要么-1要么+1),w是权重向量。
我们的更新规则怎么说?点积x?w只是感知器基于当前权重的预测(其符号与预测标签的符号相同)。表达式y(x?w)只能小于或等于0,前提是实际标签y不同于预测标签φ(x?w)。因此,如果真标签和预测标签之间不匹配,那么我们更新权重:w=w+yx;否则,我们让它们保持原样。
那么,为什么w=w+yx更新规则有效?因为它试图在if条件下将y(x?w)的值推向0的正边,从而正确地对x进行分类。如果数据集是线性可分的,通过对每个点进行一定次数的迭代,权值最终会收敛到每个点都被正确分类的状态。让我们通过在更新后重新评估if条件来查看更新规则的效果:
也就是说,在特定数据点的权重更新之后,if条件中的表达式应该更接近于正数,从而正确分类。
伪代码中的完整感知器算法如下:
Python实现
我们现在将在python中从头开始实现感知器算法,只使用numpy作为矩阵向量操作的外部库。我们将把它作为一个类来实现,这个类的接口类似于Scikit-Learn这样的通用机器学习包中的其他分类器。我们将为此类实现3个方法:.fit()、.predict()和.score()。
.fit()方法将用于训练感知器。它期望第一个参数是2D numpy数组X。该数组的行是数据集的样本,列是特征。第二个参数y应该是1D的numpy数组,它包含X中每行数据的标签。第三个参数n_iter是我们让算法运行的迭代次数。
def fit(self, X, y, n_iter=100):
n_samples = X.shape[0]
n_features = X.shape[1]
# 偏置都加1
self.weights = np.zeros((n_features+1,))
X = np.concatenate([X, np.ones((n_samples, 1))], axis=1)
for i in range(n_iter):
for j in range(n_samples):
if y[j]*np.dot(self.weights, X[j, :]) <= 0:
self.weights += y[j]*X[j, :]
.predict()方法将用于预测新数据的标签。它首先检查weights对象属性是否存在,如果不存在,则表示感知器尚未训练,然后显示警告消息并返回。该方法需要一个与.fit()方法形状相同的参数X。然后我们在X和权重之间做一个矩阵乘法,然后把它们映射到-1或+1。我们使用np.vectorize()将此映射应用于矩阵乘法结果向量中的所有元素。
def predict(self, X):
if not hasattr(self, 'weights'):
print('The model is not trained yet!')
return
n_samples = X.shape[0]
X = np.concatenate([X, np.ones((n_samples, 1))], axis=1)
y = np.matmul(X, self.weights)
y = np.vectorize(lambda val: 1 if val > 0 else -1)(y)
return y
score()方法计算并返回预测的准确性。它期望输入矩阵X和标签向量y作为参数。
def score(self, X, y):
pred_y = self.predict(X)
return np.mean(y == pred_y)
几个例子
我现在要做的是展示几个可视化的例子,说明决策边界是如何收敛到一个解的。
为了做到这一点,我将使用ScikitLearn的datasets.make_classification()和datasets.make_circles()函数创建几个由200个样本组成的2特征分类数据集。这是用于创建下两个数据集的代码:
X, y = make_classification(
n_features=2,
n_classes=2,
n_samples=200,
n_redundant=0,
n_clusters_per_class=1
)
还有一个数据集:
X, y = make_circles(n_samples=200, noise=0.03, factor=0.7)
对于每个示例,我将把数据分成150个用于训练,50个用于测试。左边显示训练集,右边显示测试集。当决策边界收敛到一个解决方案时,决策边界将在两边显示。但是决策边界将仅根据左边的数据(训练集)进行更新。
例1 线性可分的
我要展示的第一个数据集是线性可分的。下面是完整数据集的图像:
这是一个简单的数据集,我们的感知器算法在经过训练集的两次迭代后就会收敛到一个解。因此,每个数据点的动画帧都会改变。绿点是目前在算法中测试的那个。
在该数据集上,算法对训练样本和测试样本进行了正确分类。
例2 噪声数据集
如果数据集不是线性可分的呢?如果正反两个例子像下图一样混淆在一起呢?
好吧,感知器算法将不能正确分类所有的例子,但它将试图找到一条线,最好的分开他们。在这个例子中,我们的感知器得到了88%的测试精度。下面的动画帧在每次迭代后都会通过所有训练示例进行更新。
例3 非线性数据集
下面的数据集如何呢?
它是可分离的,但显然不是线性的。所以你可能会认为一个感知器不适合这个任务。但感知器的问题是,它的决策边界是线性的,就权重而言,不一定就输入而言。我们可以扩充输入向量x,使其包含原始输入的非线性函数。例如,除了原始输入x1和x2之外,我们还可以将项x1平方、x1乘以x2和x2平方相加。
下面的 polynomial_features(X, p)(X,p)函数能够将输入矩阵X转换成一个矩阵,该矩阵包含p次多项式的所有项作为特征。它使用polynom()函数计算表示要相乘列的索引列表,以获得p阶项。
def polynom(indices_list, indices, a, b, p):
indices = [*indices]
if p == 0:
indices_list.append(indices)
return
for i in range(a, b):
indices.append(i)
polynom(indices_list, indices, i, b, p-1)
indices = indices[0:-1]
def polynomial_features(X, p):
n, d = X.shape
features = []
for i in range(1, p+1):
l = []
polynom(l, [], 0, d, i)
for indices in l:
x = np.ones((n,))
for idx in indices:
x = x * X[:, idx]
features.append(x)
return np.stack(features, axis=1)
在我们的例子中,我们将在X矩阵中添加2级项作为新特征。
X = polynomial_features(X, 2)
现在,让我们看看使用这个转换后的数据集进行训练时会发生什么:
注意,对于绘图,我们只使用原始输入来保持它的二维性。决策边界在扩展特征空间中仍然是线性的,现在是5D。但是,当我们绘制投影到原始特征空间的决策边界时,它具有非线性形状。
通过这种方法,我们的感知器算法能够在不修改算法本身的情况下正确地分类训练和测试实例。我们只改变了数据集。
通过这种特征增强方法,我们可以使用线性算法在数据中建模非常复杂的模式。
但是,这种方法不是很有效。想象一下,如果我们有1000个输入特征,并且我们想用最多10次多项式项来扩充它,会发生什么。幸运的是,这个问题可以通过使用核函数来避免。但这是另一篇文章的主题,我不想把这篇文章写得太长。
相关推荐
- Vue 技术栈(全家桶)(vue technology)
-
Vue技术栈(全家桶)尚硅谷前端研究院第1章:Vue核心Vue简介官网英文官网:https://vuejs.org/中文官网:https://cn.vuejs.org/...
- vue 基础- nextTick 的使用场景(vue的nexttick这个方法有什么用)
-
前言《vue基础》系列是再次回炉vue记的笔记,除了官网那部分知识点外,还会加入自己的一些理解。(里面会有部分和官网相同的文案,有经验的同学择感兴趣的阅读)在开发时,是不是遇到过这样的场景,响应...
- vue3 组件初始化流程(vue组件初始化顺序)
-
学习完成响应式系统后,咋们来看看vue3组件的初始化流程既然是看vue组件的初始化流程,咋们先来创建基本的代码,跑跑流程(在app.vue中写入以下内容,来跑流程)...
- vue3优雅的设置element-plus的table自动滚动到底部
-
场景我是需要在table最后添加一行数据,然后把滚动条滚动到最后。查网上的解决方案都是读取html结构,暴力的去获取,虽能解决问题,但是不喜欢这种打补丁的解决方案,我想着官方应该有相关的定义,于是就去...
- Vue3为什么推荐使用ref而不是reactive
-
为什么推荐使用ref而不是reactivereactive本身具有很大局限性导致使用过程需要额外注意,如果忽视这些问题将对开发造成不小的麻烦;ref更像是vue2时代optionapi的data的替...
- 9、echarts 在 vue 中怎么引用?(必会)
-
首先我们初始化一个vue项目,执行vueinitwebpackechart,接着我们进入初始化的项目下。安装echarts,npminstallecharts-S//或...
- 无所不能,将 Vue 渲染到嵌入式液晶屏
-
该文章转载自公众号@前端时刻,https://mp.weixin.qq.com/s/WDHW36zhfNFVFVv4jO2vrA前言...
- vue-element-admin 增删改查(五)(vue-element-admin怎么用)
-
此篇幅比较长,涉及到的小知识点也比较多,一定要耐心看完,记住学东西没有耐心可不行!!!一、添加和修改注:添加和编辑用到了同一个组件,也就是此篇文章你能学会如何封装组件及引用组件;第二能学会async和...
- 最全的 Vue 面试题+详解答案(vue面试题知识点大全)
-
前言本文整理了...
- 基于 vue3.0 桌面端朋友圈/登录验证+60s倒计时
-
今天给大家分享的是Vue3聊天实例中的朋友圈的实现及登录验证和倒计时操作。先上效果图这个是最新开发的vue3.x网页端聊天项目中的朋友圈模块。用到了ElementPlus...
- 不来看看这些 VUE 的生命周期钩子函数?| 原力计划
-
作者|huangfuyk责编|王晓曼出品|CSDN博客VUE的生命周期钩子函数:就是指在一个组件从创建到销毁的过程自动执行的函数,包含组件的变化。可以分为:创建、挂载、更新、销毁四个模块...
- Vue3.5正式上线,父传子props用法更丝滑简洁
-
前言Vue3.5在2024-09-03正式上线,目前在Vue官网显最新版本已经是Vue3.5,其中主要包含了几个小改动,我留意到日常最常用的改动就是props了,肯定是用Vue3的人必用的,所以针对性...
- Vue 3 生命周期完整指南(vue生命周期及使用)
-
Vue2和Vue3中的生命周期钩子的工作方式非常相似,我们仍然可以访问相同的钩子,也希望将它们能用于相同的场景。...
- 救命!这 10 个 Vue3 技巧藏太深了!性能翻倍 + 摸鱼神器全揭秘
-
前端打工人集合!是不是经常遇到这些崩溃瞬间:Vue3项目越写越卡,组件通信像走迷宫,复杂逻辑写得脑壳疼?别慌!作为在一线摸爬滚打多年的老前端,今天直接甩出10个超实用的Vue3实战技巧,手把...
- 怎么在 vue 中使用 form 清除校验状态?
-
在Vue中使用表单验证时,经常需要清除表单的校验状态。下面我将介绍一些方法来清除表单的校验状态。1.使用this.$refs...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- Vue 技术栈(全家桶)(vue technology)
- vue 基础- nextTick 的使用场景(vue的nexttick这个方法有什么用)
- vue3 组件初始化流程(vue组件初始化顺序)
- vue3优雅的设置element-plus的table自动滚动到底部
- Vue3为什么推荐使用ref而不是reactive
- 9、echarts 在 vue 中怎么引用?(必会)
- 无所不能,将 Vue 渲染到嵌入式液晶屏
- vue-element-admin 增删改查(五)(vue-element-admin怎么用)
- 最全的 Vue 面试题+详解答案(vue面试题知识点大全)
- 基于 vue3.0 桌面端朋友圈/登录验证+60s倒计时
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- node卸载 (33)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- exceptionininitializererror (33)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)