一、单层感知器(MCP人工神经元模型)

news2024/11/25 23:00:31

目录

前言

由来

介绍

算法原理 

假设前提

一、前向传递过程(算法训练好后的使用过程)

补充:sign函数

二、训练方法(求解权重w、偏转量b)

写出损失函数

误分点选取

损失函数求导 

梯度下降自确定w、b

算法实现

总结


前言

在我的第一篇《深度学习的发展历史(深度学习入门、学习指导)-CSDN博客》中,介绍了深度学习模型发展的一个全进程。在这一个深度学习历史上最早出现的就是MCP人工神经元模型,这个模型有一个相当有名的算法——感知器(也称为单层感知机

本篇文章,我们就来讲一讲这个神经网路\深度学习邻域的老祖宗模型

由来

我们大脑做出每一个决定,都可以看作是接受一定输入然后在确认自身状态后,返回这个输入的输出值。举个例子:

一、

输入值:同学叫我去打篮球

输出值:拒绝同学

二、

输入值:同学叫我去打羽毛球

输出值:同意同学

这里可以看到不同的输入值,我们的输出值不一样。这就说明不同的输出值它对输出值的影响是不同的,所以对每一个输入值需要有一个权重。如何判断同意还是拒绝呢,因为输入数放到函数中输出的肯定是一个连续的值而拒绝和同意只有两个值,所以这里就需要用到激活函数(只有输出两次达到一定值后才会激活,输出1)

介绍

单层感知机是机器学习中最基础的方法之一,其本质和逻辑回归有一定的相似,两者都是接受输入,然后会根据输入返回一个输出(两者的区别在于损失函数激活函数选择不同)。单层感知机选用sign函数作为激活函数,选用误分类点到超平面距离的总和作为损失函数。

单层感知机只能用来解决二分类问题,对于较为复杂的分类问题无法解决。并且只能处理二分类中的线性可分问题(例如异或问题无法解决)

算法原理 

对于一个机器学习算法,我们去研究其原理时主要从两个角度:一、前向传递过程(算法训练好后的使用过程) 二、训练过程(算法的训练过程)。对于单层感知机,我们也从这两个角度来看这个算法。

假设前提

假设有n条记录,每记录p个指标,每记录有一个输出类别,这个输出类别分为A类和B类

一、前向传递过程(算法训练好后的使用过程)

假如已经得到训练好的单层感知机模型如下:

s=w_0x_0+w_1x_1+w_3x_3+\cdots+w_px_p+b = \mathbf{w}^T\mathbf{x}+b

其中权重\mathbf{w}=[w_0,w_1,\cdots,w_p]^T,以及偏转量b经过训练过程已经是已知的。

此时得到一组数据\mathbf{x}=[x_0,x_1,\cdots,x_p]^T,那么代入感知机模型可以得到结果为:

Output=sign(s)

由于sign函数能够将连续的结果s转变为1/-1,所以最终结果Output只有1(代表A),-1(代表B)两种情况。Output的值就是这一组数据得到的结果。

补充:sign函数

sign函数是tanh函数的极限特例

sign(x)或者Sign(x)叫做符号函数,在数学和计算机运算中,其功能是取某个数的符号(正或负):
当x>0,sign(x)=1;
当x=0,sign(x)=0;
当x<0, sign(x)=-1

二、训练方法(求解权重w、偏转量b)

写出损失函数

一般神经网络的训练方法都是相同的,就是构造损失函数,然后对损失函数进行求导,算出损失函数极小值点下对应的权重w以及偏转量b(有时候损失函数关于w、b不是连续可导的,这种情况要另外处理)

单层感知机的损失函数就是统计所有误分类点到超平面的距离之和

超平面:一个高维函数在高维空间上的具象化体现

这个超平面能够将高维度点分为两类:一类在超平面的一侧另一类在超平面的另一侧。

举个例子(左图为二维超平面,右图为三维超平面):

        

设超平面为 wx+b=0,其中w和x的维度也就是超平面所在的维度。若n个点中有m个点为误分类点,那么损失函数可以写为:

Loss=\sum_{i=1}^{m}d_i=\sum_{i=1}^{m}\frac{\left| \mathbf{w}^T\mathbf{x}_i+b \right|}{\left| \left| \mathbf{w} \right| \right|}

求Loss的最小值需要对Loss函数对w、b分别求偏导,但是此时Loss函数中存在绝对值以及向量长度,这都导致无法直接求导

处理方式

1、考虑到向量长度是一个常量,所以对Loss取极值时w、b的取值并没有影响,可以忽略不计

2、令超平面上方的点的类别为:A(也就是1),那此时上方点的类别值Output与\mathbf{w}^T\mathbf{x}+b

符号相同。故绝对值可以用y_i(\mathbf{w}^T\mathbf{x}+b)来代替

通过上面两个处理方式最终Loss可以简化为:

Loss=\sum_{i=1}^m-y_i(\mathbf{w}^T\mathbf{x_i}+b)

误分点选取

写出损失函数后,我们不禁思考这个误分点要如何获取?显然,靠画出数据图像人为去数点是不合理的(1、wb不确定图像画不出来 2、点很多人为数点不现实)从数学的角度,Loss函数只能包含w、b两个变量,所以我们要将m转化为w、b,即找到m和wb的关系。解决这个问题,可以用计算机的思维:设计一个判断语句,若y_i\mathbf{w}^T\mathbf{x_i}+b的符号不相同,那么这个点便是误分点,便包含在\sum当中。例如图中在下方的蓝色小球,其类别为1,同时\mathbf{w}^T\mathbf{x_i}+b<0也成立,所以该点为误分点

损失函数求导 

损失函数Loss是关于w和b的函数,对其求偏导时,由于w是一个向量,Loss本身也是一个向量,所以需要用到矩阵求导的知识。这里设计的是矩阵求导中的向量关于向量求导,这里附上求导的结果公式(想要了解原理的友友们可以自己去详细看看矩阵求导的内容)(下图为生信小兔手写)

\frac{\partial A\mathbf{x}}{\partial \mathbf{x}}=A^T\\ \frac{\partial A\mathbf{x}}{\partial \mathbf{x}^T}=A

图中的w为向量需要用到矩阵求导公式,而b仅仅就是一个变量直接求导即可(图中每个地方都可以去掉一个符号,因为前文对AB对应的数做了调整) 

最终求导后的结果为:

dw=\frac{\partial Loss}{\partial \mathbf{w}}=\sum_{i=1}^m y_i\mathbf{x_i}\\ db=\frac{\partial Loss}{\partial b}=\sum_{i=1}^m-y_i

梯度下降自确定w、b

由于此时令两个求导结果的值等于0,是不存在唯一的共同解的。这个时候我们只能选择极大似然估计或者梯度下降的方式去求导离极值最近的一个值。

梯度下降

流程:

一、随机生成一个w,b(即待下降的参数)

二、求出此时随机生成的w,b关于Loss的导数

三、利用上面求得的dw、db的关系式,不停循环得到最终的dw、db值

四、令\mathbf{w}=\mathbf{w}-\frac{\partial Loss}{\partial \mathbf{w}}*\frac{alpha}{n}生成新的w(alpha为学习率,n为样本数目)

五、令b=b-\frac{\partial Loss}{\partial b}*\frac{alpha}{n}生成新的b

六、利用新的w、b生成新的分割线,参与下一轮的训练,重复三四五步骤

定义:

\frac{\partial Loss}{\partial b}\frac{\partial Loss}{\partial \mathbf{w}}称为梯度

特别点:

1、在利用梯度进行下降的时候,除n是为了对梯度归一化处理,使得梯度更加平稳,不会受样本数目的影响

2、学习率是梯度下降算法中一个重要的超参数,它控制着参数在每次更新时的步长

随机梯度下降(SGD)

定义:

SGD算法是从样本中随机抽出一组,训练后按梯度更新一次,然后再抽取一组,再更新一次。简单来说就是,将一个大数据分为多组小数据,用每一小组进行训练得到训练结果,并将结果用于下一次训练

分类:

1.SGD是最基本的随机梯度下降,它是指每次参数更新只使用一个样本,这样可能导致更新较慢;
2.Batch-SGD是批随机梯度下降,它是指每次参数更新使用所有样本,即把所有样本都代入计算一遍,然后取它们的参数更新均值,来对参数进行一次性更新,这种更新方式较为粗糙;
3.Mini-Batch-SGD是小批量随机梯度下降,它是指每次参数更新使用一小批样本

这三类得区别仅仅在于每次随机抽取得组的大小,三类的抽取都是随机的

本题选用Batch-SGD

优点:

一、小组训练便返回结果使得在数据量很大时,不必要全部训练完便可以得到一个较好得结果

二、随机抽取使得数据之间的相关性降低,让准确度更好

三、每次抽取一组数据计算出新计算的dw、db后便更新w、b,产生新的分割线。利用这个分割线再去判断误分点

四、Batch-SGD和一般的SGD的区别在于,更新权重和梯度是取每一个batch的平均值进行的。相较于SGD不用每次都更新权重和梯度效率将提升,但是每一个批次取平均值更新一次使得更新的权重和梯度较为粗糙。

Batch—SGD流程:

一、设定一个BatchLength,表示每一训练组的大小

二、利用zip函数与list函数将x、y打包成元组放在data数组中(元素为xy元组)

三、利用batches数组,将data数组切片处理(data[i:i+BatchLength]为一组)

四、在每一个batches数组元素上进行组内训练(重复上面梯度下降的过程)

算法实现

在这里以dry_bean_dataset数据集为例。为了直观体现该模型的效果,我们仅选取MajorAxisLength和MinorAxisLength两个指标,数据选取前3500组数据,此时数据集仅含有SEKER和BARBUNYA两类。

在数据较少(如几十组数据)时,可以使用所有数据进行训练;对于数据较多的情况(几千甚至几万以上),用所有数据进行训练速度会很慢,效果也很差,所以可以采用随机梯度下降法,每次从中选取部分数据进行训练。代码如下:

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
class perceptron:
    def __init__(self,x,y,alpha=0.01,circle=500,batchlength=20): #python中函数都有一个self参数,表示实例本身(这里是一个具体的向量机)
        #init中定义的self.变量就是这个类所有的属性
        self.x=x #训练样本数据中的各指标数
        self.y=y #训练样本数据中各组数据对应的类别
        self.alpha=alpha #学习率
        self.circle=circle #学习轮数
        self.n=x.shape[0] #样本的数量
        self.p=x.shape[1] #样本的指标个数
        self.w=np.random.normal(size=(self.p,1)) #利用np随机生成(normal法)向量w,其规模就是(指标个数,1)
        self.b=np.random.normal(size=1) #利用np随机生成(normal法)常量b
        self.batchlength=batchlength #每次训练样本中使用的数据个数,随机梯度下降法
    def batches(self): #batches作用就是让梯度下降分组进行,而不是
        data=list(zip(self.x,self.y)) #zip作用为压缩两个元组一一合并返回值是一个zip压缩包不能直接浏览内容,list将合并后的元组以列表形式呈现方便浏览
        np.random.shuffle(data) #将data内容打乱
        batches=[data[i:i+self.batchlength] for i in range(0,self.n,self.batchlength)]
        return batches
    def sign(self,x): #激活函数sign
        if x>0:
            return 1
        elif x<0:
            return -1
        else:
            return 0
    def train(self):
        for i in range(self.circle): #省略了(0,self.circle)
            print('the {} circle'.format(i)) #{}作用是在字符串中插入数字
            for batch in self.batches(): #每一个batch都可以认为是一组数组,数组中每个元素都是一个元组,batches()返回值是数组的数组
                dw=0
                db=0 #用来实现数学表达式中的求和的中间值
                num=1; #误分类点的个数
                for x,y in batch:
                    if y*(np.dot(self.w.T,x.T)+self.b)>=0: #同号表示不是误分点
                        continue
                    else:
                        dw += -y * x.T
                        db += -y
                        num += 1
                if num!=0:
                    self.w -= self.alpha * dw / num
                    self.b -= self.alpha * db / num
                else:
                    continue
            #每一轮对所有数据进行学习后,都画出新的分割线和分割点
            color=[]
            for c in self.y:
                if c==1:
                    color.append('green')
                else:
                    color.append('red')
            x = np.arange(180, 470, 1) #根据数据的范围确定画图中x的范围
            y = -self.w[0] * x / self.w[1] - self.b / self.w[1]  # 分割线
            plt.plot(x, y)
            plt.scatter(np.array(self.x[:, 0]), np.array(self.x[:, 1]), color=color)
            plt.xlim([180, 470])
            plt.ylim([160, 320])
            plt.pause(1)
            plt.clf()
        # x = np.arange(180, 470, 1)  # 根据数据的范围确定画图中x的范围
        # y = -self.w[0] * x / self.w[1] - self.b / self.w[1]  # 分割线
        # plt.plot(x, y)
        # plt.scatter(np.array(self.x[:, 0]), np.array(self.x[:, 1]), color=color)
        # plt.xlim([180, 470])
        # plt.ylim([160, 320])
        # plt.pause(1)
        # plt.clf()
def prediction(self,x):
        s=np.dot(self.w.T,x)+self.b
        output=self.sign(s)
        return output
if __name__=='__main__': #下面语句作为主程序单独运行时执行,作为模块导入时不执行
    df=pd.read_excel('Dry_Bean_Dataset.xlsx') #读取excel文件
    df.to_csv('Dry_Bean_Dataset.csv',index=False) #将excel文件另存为csv文件
    df=pd.DataFrame(pd.read_csv('Dry_Bean_Dataset.csv')) #将csv文件转变为dataframe对象,然后就可以用dataframe对象下的许多函数来进行数据分析处理
    x=df.loc[0:3500, 'MajorAxisLength':'MinorAxisLength'] #对列表进行切片操作,对矩阵本身的操作(筛选、删除等)用[]进行
    y=df.loc[0:3500, 'Class']
    X=np.mat(x) #将列表对象转为numpy矩阵
    Y=[]
    color=[]
    #对数据进行可视化画图
    for c in y:
        if c=='SEKER':
            Y.append(1)
        else:
            Y.append(-1)
    p = perceptron(x=X, y=Y)
    p.train()

代码中直接将数据集xlsx文件与程序放在一个文件夹内,同时有将xlsx文件转化为csv文件的操作。

关键点:

图中的超平面为\mathbf{w}^T\mathbf{x}+b=0,要将这个超平面画出来,考虑到这个超平面在本数据集中是二维的,所以画这个超平面也就是画一条直线。因为w=(wo,w1)x=(x1,x2),所以可以另其中一个x2为y,x1为x去画这个直线,因此直线的方程就是:y=-\frac{w_0x}{w_1}-\frac{b}{w_1}

因此代码中有: y = -self.w[0] * x / self.w[1] - self.b / self.w[1]  # 分割线这一句子

最终结果图为:

 我们肉眼可以看出,这个分割方式不会是最好的分割方式,这说明机器对于单层感知器来说其准确率并不是很高的

总结

单层感知机虽然整体思路非常简单,但是其确实更加复杂的神经网络学习的基础。通过单层感知机的学习我们可以学到损失函数、梯度下降、矩阵求导、数据分析处理等在所有机器学习中都可以使用的知识。同时单层感知器存在无法处理异或问题、准确度低等缺陷,但是其组合在一起变成多层感知机便可以处理这些问题。

(由于本人也是刚刚接触机器学习算法,本篇内容参考并沿用了大量其他大佬们的资料,在这里向“生信小兔”表示感谢,通过他的文章真的学了挺多)

还是想厚脸皮的求赞啦~~~人工智能领域小白

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1563442.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

救砖刷机------MTK芯片类线刷 救砖 常规线刷不开机 MTK分区表修复【二】

救砖刷机------MTK芯片类线刷 救砖 免授权的一些操作步骤与工具解析【一】 在上期的博文中解析了mtk刷机平台的一些基本选项说明和授权刷写的一些常识。这期将着重说明下mtk机型分区表损坏如何解决。 众所周知。高通分区表在高通线刷包中显而易见,在常规9008刷写中你会正常刷…

主流公链 - Fantom

Fantom&#xff1a;高性能的区块链协议 Fantom是一种开创性的区块链协议&#xff0c;旨在革新去中心化应用和数字金融领域 技术特点 共识机制 Lachesis协议&#xff1a;Fantom使用了Lachesis协议作为其共识算法。Lachesis是一种 异步拜占庭容错&#xff08;ABFT&#xff09;共…

基于springboot+vue+Mysql的火车订票管理系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

TikTok账号封号原因是什么?全面攻略

多人在使用TikTok的过程中都会遇到一些问题&#xff0c;比如为什么TikTok没有浏览量&#xff1f;事实上&#xff0c;这很可能是因为你的账号已被禁止。但为什么它会被封呢&#xff1f;你怎样才能解决它&#xff1f; 一、TikTok账号为什么被封&#xff1f; 1、什么是 TikTok 影…

掼蛋技巧秘籍

1、开始出牌不走牌一定是在理顺子。 2、起手出顺&#xff0c;后面一定还有两三把顺子。 3、上中场就出同花顺就一定还有大炸。 4、双贡顺子、对子是优势&#xff0c;绝对不能放。 5、单贡返牌&#xff0c;给对友单张小牌&#xff08;5以下&#xff09;&#xff0c;给对手大…

vue3中播放flv流视频,以及组件封装超全

实现以上功能的播放&#xff0c;只需要传入一个流的地址即可&#xff0c;当然组件也只有简单的实时播放功能 下面直接上组件 里面的flvjs通过npm i flv.js直接下载 <template><div class"player" style"position: relative;"><p style&…

站群CMS系统

站群CMS系统是一种用于批量建立和管理网站的内容管理系统&#xff0c;它能够帮助用户快速创建大量的网站&#xff0c;并实现对这些网站的集中管理。以下是三个在使用广泛的站群CMS系统&#xff0c;它们各具特色&#xff0c;可以满足不同用户的需求。 1. Z-BlogPHP Z-BlogPHP是…

云计算HCIE学员分享丨授人以鱼不如授人以渔

我还记得大一时&#xff0c;我对是否要报名云计算IE有着很多犹豫。当时&#xff0c;我对这个领域充满了好奇&#xff0c;但同时也担心自己是否有能力应对这样的挑战。正是在这个时候&#xff0c;我有幸认识了誉天培训机构的老师们。 我第一次接触誉天&#xff0c;就被那里的师资…

数据结构二叉树顺序存储——堆

堆 1.堆的概念2.堆的实现 &#xff08;建小堆为例&#xff09;2.1 初始化和销毁2.2 判空2.3 获得堆顶元素和堆的大小2.4 插入2.5 删除 3.堆的构建&#xff08;建小堆为例&#xff09; 1.堆的概念 将若干数据或元素按照完全二叉树的存储方式顺序存储到一个一维数组中&#xff0…

jupyter加目录contrib nbextension 使用

jupyter在工作中使用很方便&#xff0c;可是一旦单个文件的内容多了&#xff0c;即使有markdown文本提醒&#xff0c;上下翻找依旧很费精力。这时&#xff0c;有个目录就显得至关重要了。 1 安装模块 打开anaconda的PowerShell&#xff08;带有Prompt的&#xff09;&#xff0…

Springboot中的三层架构

我们在进行前后端交互的时候&#xff0c;会分为数据访问&#xff0c;业务逻辑&#xff0c;接受请求并响应数据三个操作&#xff0c;这三部分其实是可以拆分的&#xff0c;让他们解耦&#xff0c;否则代码复用性差并且不易维护&#xff0c;所以诞生了三层架构——1.Dao(数据访问…

js使用canvas实现画roi功能,并实现交集并集差集操作,附源码

效果概览 支持圆形,矩形,旋转矩形绘制,鼠标像素拾取,图片缩放,图片拖拽,像素测量,roi交集并集补集输出 TODO:实现自由路径绘制,与后台交互数据 实现原理 交集并集差集使用像素做运算,使用0代表没有像素,1代表有像素,然后再做运算 // 计算交集calculateIntersec…

Mouse on Mouse(M.O.M.™)Immunodectection Kits

在检测小鼠组织抗原的实验中&#xff0c;我们经常会遇到所找到的一抗只有小鼠来源的情况&#xff0c;也就经常会存在着多种疑虑&#xff1a;比如抗小鼠的二抗不仅识别小鼠源性的一抗&#xff0c;同时也识别小鼠组织中内源性的小鼠免疫球蛋白&#xff0c;因而背景非常高。 而实际…

2024年通信安全员ABC证证考试题库及通信安全员ABC证试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年通信安全员ABC证证考试题库及通信安全员ABC证试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#xff09;特种设备作业人员上岗证考试大…

c++的STL(6)-- map和multimap

map和multimap概述 map和multimap中存储的是使用pair对象的键值对。 map和multimap底层也是使用红黑树的数据结构进行实现的。所以&#xff0c;map和multimap内部存储的键值对也是有序的。并且内部数据也是使用链表的形式进行关联。所以其的迭代器和指针&#xff0c;也只能进行…

Gmail多账号防封攻略,看这一篇就够了

您的业务活动需要多个 Gmail 帐户吗&#xff1f;出海畅游&#xff0c;Gmail账号是少不了的工具之一&#xff0c;可以关联到Twitter、Facebook、Youtube、Chatgpt等等平台&#xff0c;可以说是海外网络的“万能锁”。但是大家都知道&#xff0c;以上这些平台注册多账号如果产生关…

初识UART串行总线,51单片机串口通信

串口基本认知 串行接口简称串口&#xff0c;也称串行通信接口或串行通讯接口&#xff08;通常指COM接口&#xff09;&#xff0c;是采用串行通信方式的扩展接口。串行接口&#xff08;Serial Interface&#xff09;是指数据一位一位地顺序传送。其特点是通信线路简单&#xff0…

素组主元素

主要元素&#xff08;主元素&#xff09;是在一整数序列&#xff08;长度是N&#xff09;中出现次数大于N/2的元素&#xff0c;因为整数序列本身长度就是N&#xff0c;那么只要该整数序列中存在主元素&#xff0c;主要元素就是唯一的 思路&#xff1a; 思路一&#xff1a;穷举…

git可视化工具

Gitkraken GitKraken 是一款专门用于管理和协作Git仓库的图形化界面工具。它拥有友好直观的界面&#xff0c;使得Git的操作变得更加简单易用&#xff0c;尤其适合那些不熟悉Git命令行的开发者。GitKraken提供了丰富的功能&#xff0c;如代码审查、分支管理、仓库克隆、提交、推…