感知器c语言

  **感知器原理 代码实现**

前言

随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍机器学习中神经网络的感知器原理。

一、感知器是什么?

感知器是人工神经网络中的一种典型结构, 它的主要的特点是结构简单,对所能解决的问题 存在着收敛算法,并能从数学上严格证明,从而对神经网络研究起了重要的推动作用。
感知器在20世纪五、六十年代由科学家 Frank Rosenblatt 发明,一个感知器接受几个输入,并产生一个输出。虽然感知器算法性能不如支持向量机,现在很少使用,但感知器算法在机器学习这一领域发展过程中有着重要的历史意义,体现在它首先提出了一套机器学习的框架。

二、原理

一个感知器由以下几部分组成:
1、输入权值 一个感知器可以接收多个输入 (x1,x2,…,xn∣xi∈R),每个输入上有一个权值wi∈R,此外还有一个偏置项b,即w0。
2、激活函数 感知器的激活函数可以有很多选择
3、输出 感知器的输出由下面这个公式来计算 y=f(w∙x+b)公式
感知器本身是一个线性分类器,它通过求考虑了权重的各输入之和与阖值的大小关系,对事物进行分类。 所以任何线性分类或线性回归问题都可以用感知器来解决。然而,感知器却不能实现异或运算.
权重项和偏置项的值要用到感知器训练算法:将权重项和偏置项初始化为0,然后,利用感知器规则迭代的修改wi和b,直到训练完成。事实上,可以把b看作是值永远为1的输入所对应的权重w0。t是训练样本的实际值,一般称之为label。而y是感知器的输出值,它是根据公式计算得出。delta是一个称为学习速率的常数,其作用是控制每一步调整权的幅度。
每次从训练数据中取出一个样本的输入向量x,使用感知器计算其输出y,再根据上面的规则来调整权重。每处理一个样本就调整一次权重。经过多轮迭代后(即全部的训练数据被反复处理多轮),就可以训练出感知器的权重,使之实现目标函数。
在这里插入图片描述
一般感知器的输出 y = WX+b,以2维数据为例,W ={w1, w2},X={x1, x2},y=w1x1+w2x2+b。
从形式上令w0=b,则输出可变更为,y=WX;W={w0, w1, w2}, X = {1, x1, x2},依然有y=w1x1+w2x2+b。
硬限幅器
∑wixi>0时,值为1
otherwise, 值为-1
其功能类似于符号函数sign()

调整权重公式
当神经网络的计算输出y跟目标输出d(desired)一致时,不修改W;当计算输出y跟目标输出d不一致时,修改W。修改策略为:

W(n+1)=W(n)+delta*d(n)*X(n)
delta是学习速率,d(n)是训练样本的实际输出值

三.实训例题

使用C语言实现感知器算法。
将trainData、testData两个文件读入内存,作为训练和测试数据训练模型(即权重weight),并计算分类正确率。
数据集说明:每条数据包含6维,在数据文件中为1~6列,第7列为类别标志,用1、-1区分。共计303条样本,随机分配后得到trainData和testData两文件,分别为183和120行,用于建模和测试。

分析:
当所指定的初始权重W不同时,最终解有可能不同。
当所指定的系数delta不同时,最终解有可能不同。
delta的含义为:学习率参数。当delta大时,迭代过程不稳定;当delta小时,收敛速度慢。
当原问题线性不可分时,可通过在程序中设置最大迭代轮数强行退出循环,求得近似解。

#include<bits/stdc++.h>
using namespace std;
#define nTrain 183//训练样本
#define nInput 6 //六维数据
#define delta 0.25 //学习速率
#define nTest  120//测试样本
#define maxItre 1000//自由设置迭代轮数
typedef struct slp
{
 double input[7];
 int n;//数据集中最后一项类别标志
} slp_testData;

double com_output(double *input,double *weight)
{
 double sum=0.0;
 for(int i=0;i <nInput+1;i++)
 {
 sum= sum + (input[i] * weight[i]);
 }
 return sum;
}

int classOutPerceptron(double output)
{
if (output >0) return 1 ;
else  return -1;
}

int main(void)
{
    int i,j,k,tempResu;
    int flag[183]={0};
    freopen("E://脑与认知实验一/trainData.txt","r",stdin);//读取txt文本
    slp_testData trainData[nTrain];
    slp_testData testData[nTest];
    
    for(int i=0;i<nTrain;i++){
	trainData[i].input[0]=1;
    }//可以看作1与w0的乘积即为wx+b的b
    
    for(int i=0;i<nTrain;i++)
	fscanf(stdin,"%lf%lf%lf%lf%lf%lf%d", &trainData[i].input[1],&trainData[i].input[2],&trainData[i].input[3],&trainData[i].input[4],&trainData[i].input[5],&trainData[i].input[6],&trainData[i].n);
    
    for(int i=0;i<nTest;i++){
	testData[i].input[0]=1;
    }
    freopen("E://脑与认知实验一/testData.txt","r",stdin);
    for(int i=0;i<nTest;i++)
	fscanf(stdin,"%lf%lf%lf%lf%lf%lf%d", &testData[i].input[1],&testData[i].input[2],&testData[i].input[3],&testData[i].input[4],&testData[i].input[5],&testData[i].input[6],&testData[i].n);
    
	double weights[7]={0,0,0,0,0,0,0};//初始化权重
for(k=0;k<maxItre;k++)//循环迭代,反复学习,提高正确率
{
    int sum=0;
    for(i=0;i<nTrain;i++)
   {
    tempResu=classOutPerceptron(com_output(trainData[i].input,weights));
       if(tempResu==trainData[i].n)//如果结果和训练结果相等,则无需更新权值
       {
       flag[i]=1;
       sum+=flag[i];
       continue;
       }
       else
       {
   	    for(j=0;j<=nInput;j++)
             weights[j]=weights[j]+delta*trainData[i].n*trainData[i].input[j];
       }
   }
   if(sum==nTrain)break;//如果和训练数据完全符合,则退出迭代
}
  for(i=0; i<nInput+1; i++)
  printf("weight[%d]..%lf\n",i,weights[i]);//打印最终的权值
  
  int err=0;
  double rate=0.0;
	for(i=0;i<nTest;i++)
	{
		printf("test[%d] .. %d\n",i,classOutPerceptron(com_output(testData[i].input,weights)));
		if(classOutPerceptron(com_output(testData[i].input,weights))!=testData[i].n)
		{
			err++;//统计测试数据中与样本数据不符合的个数,求出正确率
		}
	}
	rate=(nTest-err)*1.0/nTest;
	printf("testData正确率:%lf",rate);
	return 0;
}

运行结果

运行结果:
weight[0]…107.500000
weight[1]…45.870543
weight[2]…35.343005
weight[3]…-18.575370
weight[4]…154.390230
weight[5]…97.587725
weight[6]…-65.747931
test[0] … 1 test[1] … 1 test[2] … 1 test[3] … 1 test[4] … 1 test[5] … 1
test[6] … 1 test[7] … 1 test[8] … 1 test[9] … 1 test[10] … 1 test[11] … 1
test[12] … 1 test[13] … 1 test[14] … 1 test[15] … 1
(…test数据太多这里就不全部显示)
testData正确率:0.983333

  • 9
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值