您的位置:首页 > 其它

感知器算法及其实现

2017-04-16 20:07 232 查看


感知器算法及其实现



1.1 算法描述:

     感知器算法(Perception Approach)是通过对已知类别的训练样本集的学习,从而寻找到一个满足判别函数的权向量。对两类线性可分的模式类,具体步骤如下:

   (1)选择N个分别属于w1类和w2类的模式样本构成训练样本集,将训练样本写成增广向量形式,并对样本进行编              号和规范化处理。任取权向量初始值开始迭代。

   (2)用全部样本进行一轮迭代。每输入一个样本,计算一次判别函数的值,根据结果正误修正权向量,并将迭代                次数加1。权向量的校正分为以下两种情况进行:

          1.若判别函数的值小于等于0,说明分类器对样本的分类发生错误,需要校正权向量。

          2.若判别函数的值大于0,说明分类正确,权向量不变。

   (3)分析分类结果,只要在迭代中有样本分类发生错误,就继续进行下一轮迭代过程,直至全部样本都获得了正                确的分类结果,迭代结束。此时得到的权向量即为算法结果。 

1.2 算法实现

     算法实现效果如下图1所示。



图1 两类情况下的感知器算法的实现

1.3 代码如下:

本代码使用了OpenGL图形程序接口,需要使用glut库,具体使用方法请自行查找相关文档,此处不再介绍。

/*
感知器算法,分为两类
*/
#define N1  30
#define N2  40
#include <stdio.h>
#include <vector>
#include <time.h>
#include <GL/glut.h>

//模式结构体
struct Pattern
{
int x1,x2;//x1,x2表示特征
int c;//c代表添加的量
};
//定义w权向量
Pattern w;
//定义w1与w2数组
Pattern w1[N1],w2[N2];

void init()
{
glClearColor(1.0f,1.0f,1.0f,1.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
void display()
{
float temp1,temp2;
if(w.x2==0)
{
temp1 = (float)(-w.c)/(float)(w.x1);
glColor3f(1.0f,0.0f,0.0f);
glEnable(GL_POINT_SMOOTH);
glBegin(GL_LINES);
glVertex2f(temp1,-1);
glVertex2f(temp1,20);
glEnd();
glFlush();
}
else
{
temp1 = (float)(-w.c+2*w.x1)/(float)(w.x2);
temp2 = (float)(-w.c-20*w.x1)/(float)(w.x2);

glColor3f(1.0f,0.0f,0.0f);
glEnable(GL_POINT_SMOOTH);
glBegin(GL_LINES);
glVertex2f(-2,temp1);
glVertex2f(20,temp2);
glEnd();
glFlush();
}
glPointSize(5.0);
glBegin(GL_POINTS);
int i,j;
for(i = 0;i < N1; i++)
{
glColor3f(1.0,0.0,0.0);
glVertex2f(w1[i].x1,w1[i].x2);
}
for(j = 0;j < N2; j++)
{
glColor3f(0.0,0.0,1.0);
glVertex2f(w2[j].x1,w2[j].x2);
}
glEnd();
glFlush();
}
int main(int argc,char *argv[])
{
int i,j,count = 0;
w.x1 = 1;
w.x2 = 1;
w.c = 1;
//产生随机数的种子
printf("这是第一类中的点\n");
srand((unsigned)time(NULL));
for (i = 0; i < N1; i++)
{
w1[i].x1=rand()%10;
w1[i].x2=rand()%10;
w1[i].c=1;
//打印随机产生的点
printf("%d %d\n",w1[i].x1,w1[i].x2);
}
printf("这是第二类中的点\n");
srand((unsigned)time(NULL));
for (j = 0; j < N2; j++)
{
w2[j].x1=10+rand()%10;
w2[j].x2=10+rand()%10;
w2[j].c=1;
//打印随机产生的点
printf("%d %d\n",w2[j].x1,w2[j].x2);
}
//感知器迭代判断
while(1)
{
for (i = 0;i < N1; i++)
{

4000
if(count>=N1+N2) break;
if(((w1[i].x1*w.x1)+(w1[i].x2*w.x2)+(w1[i].c*w.c))>0)
count++;
else
{
count=0;
w.x1=w.x1+w1[i].x1;
w.x2=w.x2+w1[i].x2;
w.c=w.c+w1[i].c;
}
}
for (j = 0;j < N2; j++)
{
if(count>=N1+N2) break;
if(((w2[j].x1*w.x1)+(w2[j].x2*w.x2)+(w2[j].c*w.c))<0)
count++;
else
{
count=0;
w.x1=w.x1-w2[j].x1;
w.x2=w.x2-w2[j].x2;
w.c=w.c-w2[j].c;
}
}
if(count==N1+N2) break;
}
printf("线性分类器的权矢量的值");
printf("%2d,%2d,%2d\n",w.x1,w.x2,w.c);

glutInit(&argc,argv);//初始化glut
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);//设置显示属性为RGB颜色,单缓冲
glutInitWindowSize(300,300);//设置窗口大小
glutInitWindowPosition(200,100);//设置窗口位置
glutCreateWindow("感知器算法的设计");//生成窗口
init();
gluOrtho2D(-1,20,-1,20);
glutDisplayFunc(&display);//显示回调
glutMainLoop();
system("pause");

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息