当前位置: 代码迷 >> 综合 >> 感知器学习算法
  详细解决方案

感知器学习算法

热度:45   发布时间:2024-01-22 02:31:28.0

自己写的一个离散单输出感知器的训练算法的实现程序,本来想用MATLAB写,因为它对矩阵的操作比起C语言来说要简单得多,但是我想这也是一个简单的程序,矩阵操作在这里面也起不了多大的做用,再说MATLAB的程序设计语法我也不是很清楚,所以就直接用C语言了.

#include<stdio.h>
int ji(int x[10],int w[10],int k)
{
    int i,net=0;
 for(i=0;i<k;i++)
        net=net+x[i]*w[i];
 return net;
}
int F(int net)
{
 if (net>12)
  return 1;
 else
  return 0;
}
void jia(int x[],int w[],int k)
{
 int i=0;
 for (i=0;i<k;i++)
 w[i]=w[i]+x[i];
}
void main()
{
 int x[10]={1,0,1,0,1,1,1,0,1,0};
 int w[10]={0,0,0,0,0,0,0,0,0,0};
 int o;
 o=F(ji(x,w,10));
 while (o!=1)
 {
  printf("%d/n",o);
  jia(x,w,10);
  o=F(ji(x,w,10));
 }
 printf("%d/n",o);
} 

上面的程序是可以运行通过的,并且可以得到我所要的结果,但是我还有一些东西不清楚.

书上对该算法的描述是

1  初始化权向量 W;

2  重复下列过程,直到训练完成;

    2.1  对样本集中的每一个样本(X,Y),重复如下过程:

           2.1.1 输入X;

           2.1.2 计算O=F(XW);

           2.1.3 如果输出不正确,则

                     当O=0时,取 W=W+X;

                     当O=1时,取 W=W-X

  上述算法中,当O=0时,按W+X修改权向量 W.这是因为,理想输出本来应该是1,但现在却是0,所以,相应的权应该增加,而且是增加对该样本的实际输出真正有贡献的权.当O=1时,恰好相反.

  这我就有点看不懂了,这里使用的是阀值函数作为激活函数,该网络就是一个二值网络.O的取值也就0或者1两个数,但是依据算法描述中,确把两种情况都定义成了异常情况,那它的正确输出应该是怎么样的呢?

  我在程序里就把算法当中的所有一句给去掉了.也不知道这样做对不对.

  突然发现我做错了,因为对大部分的网络模型来说(也有例外情况),W的各个元素不能用相同的数据进行初始化,因为这样会使网络失去学习能力,一般地,使用一系列小伪随机数对W进行初始化.怎么产生一个0-1随机序列呢?这对我来说可是个问题.

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
int ji(int x[10],int w[10],int k)
{
    int i,net=0;
 for(i=0;i<k;i++)
        net=net+x[i]*w[i];
 return net;
}
int F(int net)
{
 if (net>12)
  return 1;
 else
  return 0;
}
void jia(int x[],int w[],int k)
{
 int i=0;
 for (i=0;i<k;i++)
 w[i]=w[i]+x[i];
}
int suiji()
{
 float i,j;  
 float s;
 i=(float)RAND_MAX;
 j=(float)rand(); 
 s=j/i;
 if(s>0.5)
  return 1;
 else
  return 0;
 
}
void init(int w[],int k)
{
 int i;
 srand((int)time(0));
 for(i=0;i<k;i++)
 {
  w[i]=suiji();
 }
 for(i=0;i<k;i++)
  printf("%d ",w[i]);
  printf("/n");
}
void main()
{
 int x[10]={1,0,1,0,1,1,1,0,1,0};
 int w[10];
 int o;
 init(w,10);
 o=F(ji(x,w,10));
 while (o!=1)
 {
  printf("%d/n",o);
  jia(x,w,10);
  o=F(ji(x,w,10));
 }
 printf("%d/n",o);
}

修改了以后的程序,里面加入了一个init()函数,目的就是使w随机产生,生成的序列是二进制随机序列.如何生成二进制随机序列这个问题上学期曾经有人问过我.我当时的回答是不知道,现在看来这个问题也挺简单,并不是那么复杂.

最后的结果当然也是符合我原先设想的.但是现在那个算法的问题我仍然没有理解得那么清楚.实在有点奇怪.

其实最后要用到的网络的建立,用MATLAB里面自带的一些现成的命令就可以了.自己现在编程的话就是为了能够比较清楚的理解算法的原理.

下一步应该看什么呢?继续努力,直到理解BP模型里面的所有算法.这也是导师给我的任务.是我现阶段的阶段性任务.

好好努力,会有收获的!

  相关解决方案