Rossenblat感知器可以被视为一种取定函数对应法则为某个限幅器的MCF神经元。若取硬限幅器阶跃函数step( )为对应法则,则Rossenblat感知器可表示为:
下面这段简易的c代码利用Rossenblat感知器实现了逻辑与运算,可以直接在Visual Studio上编译运行:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
/* define Step Function */
float step(float x)
{
float res;
if(x>=0) res=1;
else res=0;
return res;
}
int main(void)
{
float x1a,x2a,x1b,x2b,x1c,x2c,x1d,x2d;
float Yda,Ydb,Ydc,Ydd;
float Ya,Yb,Yc,Yd;
float w1,w2;
float a=0.01; /*初始化学习速率*/
float ea,eb,ec,ed; /*误差Yd-Y*/
float x,y,res;
int i=0,resR;
float s=0.4; /*初始化阈值θ*/
/*逻辑或运算的真值表*/
x1a=0;x2a=0;Yda=0;
x1b=0;x2b=1;Ydb=1;
x1c=1;x2c=0;Ydc=1;
x1d=1;x2d=1;Ydd=1;
w1=0.1;w2=0.1; /*初始化权重*/
Ya = 2; Yb = 2; Yc = 2; Yd = 2; /*初始化神经元输出(仅为进入下面的循环)*/
/*Training*/
while(Yda!=Ya || Ydb!=Yb || Ydc!=Yc || Ydd!=Yd)
{
i=i+1;
printf("iterations:%d\n",i);
/* a training*/
Ya=step(x1a*w1+x2a*w2-s);
ea=Yda-Ya;
if(ea!=0)
{
w1=w1+a*x1a*ea;
w2=w2+a*x2a*ea;
}
printf("weight1:w1=%f,w2=%f;ea=%f\n",w1,w2,ea);
/* b training*/
Yb=step(x1b*w1+x2b*w2-s);
eb=Ydb-Yb;
if(eb!=0)
{
w1=w1+a*x1b*eb;
w2=w2+a*x2b*eb;
}
printf("weight2:w1=%f,w2=%f;eb=%f\n",w1,w2,eb);
/* c training*/
Yc=step(x1c*w1+x2c*w2-s);
ec=Ydc-Yc;
if(ec!=0)
{
w1=w1+a*x1c*ec;
w2=w2+a*x2c*ec;
}
printf("weight3:w1=%f,w2=%f;ec=%f\n",w1,w2,ec);
/* d training*/
Yd=step(x1d*w1+x2d*w2-s);
ed=Ydd-Yd;
if(ed!=0)
{
w1=w1+a*x1d*ed;
w2=w2+a*x2d*ed;
}
printf("weight4:w1=%f,w2=%f;ed=%f\n",w1,w2,ed);
printf("finished\n");
}
/*Test*/
printf("training result:w1=%f,w2=%f\n",w1,w2);
printf("Input:");
scanf("%f %f", &x,&y);
res=step(x*w1+y*w2-s);
resR=res;
printf("%d\n", resR);
system("pause");
return 0;
}
激活函数使用了阶跃函数step( )。
注意其中w1,w2,s,a初始化时都是可调的,但理论上这会影响训练的迭代次数。
该程序除定义阶跃函数step( )外可分为两部分,前半部分为训练,后半部分为测试。由于训练所需的数据已经写好,并通过while循环实现迭代,所以程序运行后神经元即可训练完毕。此后会出现Input,在其后输入测试值(0或1),就可以输出其对应的逻辑值。
单个Rossenblat感知器可以处理线性分割区域,所以但凡两组结果可以被划分到两个不同的决策区域里,都能用感知器实现。事实上,改变真值表,不但可以实现逻辑与运算,也可以实现逻辑非与运算,但这时候需要对阶跃函数和delta规则作相应的调整。其原因在于:神经元线性分割了一个二维平面,当不改变阶跃函数时,上方的决策区域取值为1,下方取值为0,为使之进行非与运算,需要将取值调换;同时,必须将delta规则中的加号变为减号,使之能使Yd与Y的差值不断缩小。
测试效果如下图所示(部分):
iterations后面为迭代次数。注意后面的ea、eb、ec、ed都是按照上一组w1和w2计算的,每行e左侧的权重都是本轮修正后的权重。当x1和x2四种情况误差均为0时训练结束,w1和w2分别收敛到0.41(两个权重未必收敛于同一值,这会受到权重初始值的影响)。Input后输入0 1,执行逻辑或运算,输出正确结果1。