Hopfield神经网络+C代码

Hopfield是一个具有记忆功能的神经网络;通过网络转态的不断变化,最后转态会稳定下来,最终的状态是与待测样本向量X最接近的训练样本。所以Hopfield网络的最终输出就是待测样本向量联想结果。


Hopfield网络学习算法如下:

1. 确定权重系数,计算公式如下:


2. 对待测样本进行分类,对二值神经元,计算Hopfield网络输出:


可选用的阶跃函数为:


循环迭代步骤2,当网络神经达到稳定时结束,即神经元不再改变。


C代码如下:

测试样本如下:



对前9个样本的指标进行平均,得到3个等级评价指标:


对神经元进行编码,编码规则为:大于或等于某个等级指标时,对应的神经元状态设为1,否则为-1。

样本编码如下:

-1 -1 -1   -1 1 1   -1 -1 -1   1 1 1   -1 -1 -1   -1 -1 -1   1 1 1   -1 1 -1   1 1 1   -1 1 -1
-1 1 1  -1 1 1  -1 -1 1  1 1 1  -1 -1 -1  -1 -1 -1  1 1 1  -1 1 -1  1 1 1  -1 1 -1 
-1 -1 1   -1 1 1   -1 -1 1   1 1 1   -1 -1 -1   -1 -1 -1   1 1 1   1 1 1   -1 -1 -1   1 1 1
-1 -1 1   -1 1 1   -1 -1 1   1 1 1   1 1 1   1 -1 1   1 1 1   1 1 1   -1 1 -1   -1 1 -1
-1 -1 1   1 1 1   1 1 1   1 1 1   1 1 1   1 -1 1   1 1 1   1 1 1   1 1 1   1 1 1
1 1 1   -1 1 1   1 1 1   -1 -1 -1   -1 -1 -1   1 -1 1   1 1 1   1 1 1   1 1 1   -1 1 -1
1 1 1   1 1 1   1 1 1   1 1 1   1 1 1   1 -1 1   -1 -1 -1   1 1 -1   1 1 1   -1 1 -1
1 1 -1   -1 1 1   -1 1 1   1 1 1   1 1 1   1 1 1   1 1 1   -1 1 -1   -1 1 -1   -1 1 -1
-1 1 1   -1 1 1   1 1 1   1 1 1   1 1 1   1 -1 1   -1 -1 -1   -1 -1 -1   1 1 1   -1 1 -1
-1 -1 1   -1 1 1   1 1 1   1 1 1   -1 -1 -1   -1 -1 -1   -1 -1 -1   -1 1 -1   -1 1 -1   1 1 1


#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include "vector"
using namespace std;


#define nodeNum 10     //样本节点数
#define velumeNum 3    //样本容量
#define MAXITER 20000  //最大迭代次数


typedef vector<int> dim1vector;
typedef vector<dim1vector> dim2vector;
typedef vector<dim2vector> dim3vector;


dim3vector srcVector;   //输入样本
dim3vector Weight;   //权重矩阵
dim2vector outVector;  //输出向量


bool Dirty[nodeNum][velumeNum];  //记录修改的神经元
dim2vector Test;


void inFileInf(char *File);  //获取输入样本
void StartTrainNet();   //网络神经训练
void useNet();   //使用神经网络
int random();   //获取随机数
int updateNeuron(int m);  //更新第m个神经元
void SetAllDirty();   //初始化
bool QueryAllCean();  //检查至少每个神经元都被选中过


void main()
{
char *File = "输入样本.txt";


inFileInf(File);  //获取输入样本
StartTrainNet();   //开始训练
useNet();
}


//使用神经网络
void useNet()
{
Test = srcVector[4];
int i, j, k, m;
int Iter = 0;
int chngCount = 0;
bool flag = false;


while(!flag && Iter<MAXITER)
{
m = random();
chngCount += updateNeuron(m);  //更新神经元的总数

//记录已选的神经元
for(k=0; k<velumeNum; k++)
Dirty[m][k] = true;


//检查至少每个神经元都被选中过
if(QueryAllCean())
{
if(chngCount == 0) //网络已经稳定
{
flag = true;


for(i=0; i<nodeNum; i++)
{
for(j=0; j<velumeNum; j++)
printf("%3d", Test[i][j]>0?1:0);
printf("\n");
}
printf("迭代次数:%d\n", Iter+1);


}


else
{
SetAllDirty();
chngCount = 0;
}
}
Iter++;
}


}




//初始化Dirty
void SetAllDirty()
{
int i, j;
for(i=0; i<nodeNum; i++)
for(j=0; j<velumeNum; j++)
Dirty[i][j] = false;
}




//检查至少每个神经元都被选中过
bool QueryAllCean()
{
int i, j;
for(i=0; i<nodeNum; i++)
for(j=0; j<velumeNum; j++)
if(Dirty[i][j]==false)
return false;
return true;
}




//网络神经训练
void StartTrainNet()
{
dim1vector wTemp1(velumeNum, 0);
  dim2vector wTemp2(nodeNum, wTemp1);
  dim3vector wTemp3(nodeNum, wTemp2);


Weight = wTemp3;

int i, j , k, l;


for(i=0; i<nodeNum; i++)
for(j=0; j<nodeNum; j++)
for(l=0; l<velumeNum; l++)
for(k=0; k<srcVector.size(); k++)
Weight[i][j][l] += srcVector[k][i][l]*srcVector[k][j][l];


for(i=0; i<nodeNum; i++)
for(j=i; j<nodeNum; j++)
{
for(l=0; l<velumeNum; l++)
Weight[i][j][l] = 0;
break;
}


}




//更新第m个神经元
int updateNeuron(int m)
{
int i, k;
int sum[velumeNum] = {0};
int oldTest[velumeNum];


//保存旧的神经元
for(i=0; i<velumeNum; i++)
oldTest[i] = Test[m][i];


//计算当前Hopfield网络输出
for(k=0; k<velumeNum; k++)
for(i=0; i<nodeNum; i++)
sum[k] += Weight[m][i][k]*Test[i][k];


//更新神经元
for(k=0; k<velumeNum; k++)
{
if(sum[k]<0)
Test[m][k] = -1;
else
Test[m][k] = 1;
}


//神经元是否更新
for(k=0; k<velumeNum; k++)
if(Test[m][k] != oldTest[k])
return 1;
return 0;
}




//获取随机数
int random()
{
int x;
x = nodeNum*rand();
x = x/RAND_MAX;
return x;
}




//获取输入样本
void inFileInf(char *File)
{
int i, j;
int num;
dim1vector temp1;
dim2vector temp2;


FILE *fp = fopen(File, "r");


if(fp==NULL)
{
printf("Open file error!!\n");
exit(0);
}


i = 1;
j = 1;
while(fscanf(fp, "%d", &num)!=EOF)
{
temp1.push_back(num);
if(i%velumeNum ==0)
{
temp2.push_back(temp1);
if(j%nodeNum ==0)
{
srcVector.push_back(temp2);
temp2.clear();
}


temp1.clear();
j++;
}


i++;
}


fclose(fp);


}

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值