C++实现基于离散Hopfield神经网络噪声数字的识别

49 篇文章 1 订阅
19 篇文章 2 订阅

鸣谢!男朋友帮我整理的数据!真爱!!!

智能计算第三次作业

1、            题目:

基于离散Hopfield神经网络噪声数字的识别

2、            实现步骤

算法部分:

①初始化:

给定P个待存的向量u[p][N],N=120.开关函数采用sigmoid  函数

W[N][N]={0};θ=0.1.验证得θ=0时也能得到结果。

②外积法设计离散型Hopfield神经网络的圈系数矩阵W

③对样本加入噪声,25%的概率;

④ 设定迭代次数50,采用并行的工作方式,进行迭代。

画图部分:

采用opencv2进行画图,-1画点,1画实矩形 。

3、核心代码及说明:

    ///画图,采用opencv进行画图

    stringstream ss;   

    string str;  

    for(int k=0;k<P;k++)

    {

        str="u";

        ss.clear();   

        ss<<str;   

        ss<<k;   

        ss<<".jpg";   

        ss>>str;   

        Mat img(120,100,CV_8UC3,Scalar(130,240,205));//3通道图像

        for(int i=0;i<120;i++)

        {

            if(u[k][i]==-1) //画点

                circle(img,Point(5+10*(i%10),5+10*(i/10)),1,Scalar(220,0,150),1,8,0);

            if(u[k][i]==1) //画实矩形

                rectangle(img,Point(10*(i%10)+2,10*(i/10)+2),Point(8+10*(i%10),8+10*(i/10)),Scalar(220,0,150),-1,8,0);

        }

        namedWindow(str,0);

        imshow(str,img ); //显示图像

        imwrite(str,img); //保存图像

}

/外积法设计离散型Hopfield神经网络的圈系数矩阵W

for(int k=0;k<7;k++)

        {

            for(int i=0;i<N;i++)

                for(int j=0;j<N;j++)

                    W[i][j]=W[i][j]+u[k][i]*u[k][j];   

        }

        for(int i=0;i<N;i++)

        {

            for(int j=0;j<N;j++)

            {

                if(i!=j)

                    W[i][j]=W[i][j]/N

                else

                    W[i][j]=0;

            }

     }

/加入噪音

    srand ( unsigned ( time (NULL) ) );

    for(int i=0;i<P;i++)

    {

        for(int j=0;j<N;j++)

        {

            int R=(rand()%4);

            if(R==0)

                u[i][j]=-u[i][j];

        }

}

//进行迭代,采用并行的工作方式

int T=0;

while(T<50)

{

    T++;

    for(int k=0;k<7;k++)

    {

        for(int i=0;i<N;i++)

        {

            double v=0;

            for(int j=0;j<N;j++)

            {

                v=v+W[i][j]*u[k][j];

            }

            v=v-0.1; /θ=0.1

            if(v>0)

                u[k][i]=1;

            else

            {

                if(v==0)

                    u[k][i]=u[k][i];

                 else

                    u[k][i]=-1;

            }

        }

    }

}

3、            运行结果

由于选取随机污染,污染不同结果不同:

初始图像

              结果1:

  污染后图像uiT0

 

一次迭代后uiT1:

二次迭代后:uiT2

三次迭代后:uiT3

之后不再发生变化。

结果2:

污染后:

一次迭代uiT1

二次迭代uiT2

三次迭代uiT3

之后不再发生变化。

4、            总结

通过C++编程实现基于离散Hopfield神经网络噪声数字的识别,我对其的原理理解更深刻了,只有通过一次次修改代码和查阅资料才知道自己对算法的些地方存在错误的认识,再不断改进自己的算法。

今天又发现一个错误,求W矩阵的时候应该除以N,我却打成了%N。已经改过来了。作业还是晚点交好吧。奇怪的是那样结果也能出来。。。这算不算是一种新算法呢?真是醉了。

。cpp文件

#include<iostream>
#include"math.h"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <time.h>

using namespace cv;
using namespace std;
#define P 7
#define N  120
double W[N][N]={0};
int u[P][N]={
	{
		-1,-1,-1,1,1,1,1,-1,-1,-1,
			-1,-1,-1,1,1,1,1,-1,-1,-1,
			-1,-1,-1,1,1,1,1,-1,-1,-1,
			-1,-1,-1,1,1,1,1,-1,-1,-1,
			-1,-1,-1,1,1,1,1,-1,-1,-1,
			-1,-1,-1,1,1,1,1,-1,-1,-1,
			-1,-1,-1,1,1,1,1,-1,-1,-1,
			-1,-1,-1,1,1,1,1,-1,-1,-1,
			-1,-1,-1,1,1,1,1,-1,-1,-1,
			-1,-1,-1,1,1,1,1,-1,-1,-1,
			-1,-1,-1,1,1,1,1,-1,-1,-1,
			-1,-1,-1,1,1,1,1,-1,-1,-1
	},{
		1,1,1,1,1,1,1,1,-1,-1,
			1,1,1,1,1,1,1,1,-1,-1,
			-1,-1,-1,-1,-1,-1,1,1,-1,-1,
			-1,-1,-1,-1,-1,-1,1,1,-1,-1,
			-1,-1,-1,-1,-1,-1,1,1,-1,-1,
			1,1,1,1,1,1,1,1,-1,-1,
			1,1,1,1,1,1,1,1,-1,-1,
			1,1,-1,-1,-1,-1,-1,-1,-1,-1,
			1,1,-1,-1,-1,-1,-1,-1,-1,-1,
			1,1,-1,-1,-1,-1,-1,-1,-1,-1,
			1,1,1,1,1,1,1,1,-1,-1,
			1,1,1,1,1,1,1,1,-1,-1
	},{
		-1,-1,1,1,1,1,1,1,-1,-1,
			-1,-1,1,1,1,1,1,1,1,-1,
			-1,-1,-1,-1,-1,-1,-1,1,1,-1,
			-1,-1,-1,-1,-1,-1,-1,1,1,-1,
			-1,-1,-1,-1,-1,-1,-1,1,1,-1,
			-1,-1,-1,-1,1,1,1,1,-1,-1,
			-1,-1,-1,-1,1,1,1,1,-1,-1,
			-1,-1,-1,-1,-1,-1,-1,1,1,-1,
			-1,-1,-1,-1,-1,-1,-1,1,1,-1,
			-1,-1,-1,-1,-1,-1,-1,1,1,-1,
			-1,-1,1,1,1,1,1,1,1,-1,
			-1,-1,1,1,1,1,1,1,-1,-1
		},{
			-1,1,1,-1,-1,-1,-1,1,1,-1,
				-1,1,1,-1,-1,-1,-1,1,1,-1,
				-1,1,1,-1,-1,-1,-1,1,1,-1,
				-1,1,1,-1,-1,-1,-1,1,1,-1,
				-1,1,1,-1,-1,-1,-1,1,1,-1,
				-1,1,1,1,1,1,1,1,1,-1,
				-1,1,1,1,1,1,1,1,1,-1,
				-1,-1,-1,-1,-1,-1,-1,1,1,-1,
				-1,-1,-1,-1,-1,-1,-1,1,1,-1,
				-1,-1,-1,-1,-1,-1,-1,1,1,-1,
				-1,-1,-1,-1,-1,-1,-1,1,1,-1,
				-1,-1,-1,-1,-1,-1,-1,1,1,-1
		},{
			1,1,1,1,1,1,-1,-1,-1,-1,
				1,1,1,1,1,1,-1,-1,-1,-1,
				1,1,1,-1,-1,-1,-1,-1,-1,-1,
				1,1,1,-1,-1,-1,-1,-1,-1,-1,
				1,1,1,-1,-1,-1,-1,-1,-1,-1,
				1,1,1,1,1,1,-1,-1,-1,-1,
				1,1,1,1,1,1,-1,-1,-1,-1,
				1,1,-1,-1,1,1,-1,-1,-1,-1,
				1,1,-1,-1,1,1,-1,-1,-1,-1,
				1,1,-1,-1,1,1,-1,-1,-1,-1,
				1,1,1,1,1,1,-1,-1,-1,-1,
				1,1,1,1,1,1,-1,-1,-1,-1
		},{
			1,1,1,1,1,-1,-1,-1,-1,-1,
				1,1,1,1,1,-1,-1,-1,-1,-1,
				1,1,1,1,1,-1,-1,-1,-1,-1,
				1,1,1,1,1,-1,-1,-1,-1,-1,
				1,1,1,1,1,-1,-1,-1,-1,-1,
				1,1,1,1,1,-1,-1,-1,-1,-1,
				-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
				-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
				-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
				-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
				-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
				-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
			},{
				-1,-1,-1,-1,1,1,1,1,1,1,
					-1,-1,-1,-1,1,1,1,1,1,1,
					-1,-1,-1,-1,1,1,-1,-1,1,1,
					-1,-1,-1,-1,1,1,-1,-1,1,1,
					-1,-1,-1,-1,1,1,-1,-1,1,1,
					-1,-1,-1,-1,1,1,1,1,1,1,
					-1,-1,-1,-1,1,1,1,1,1,1,
					-1,-1,-1,-1,-1,-1,-1,-1,1,1,
					-1,-1,-1,-1,-1,-1,-1,-1,1,1,
					-1,-1,-1,-1,-1,-1,-1,-1,1,1,
					-1,-1,-1,-1,1,1,1,1,1,1,
					-1,-1,-1,-1,1,1,1,1,1,1}
};

int main()
{
	画原图
	stringstream ss;    
	string str;   
	cout<<0.1/2;
	for(int k=0;k<P;k++)
	{
		str="u"; 
		ss.clear();    
		ss<<str;    
		ss<<k;    
		ss<<".jpg";    
		ss>>str;    

		Mat img(120,100,CV_8UC3,Scalar(130,240,205));//3通道图像
		for(int i=0;i<120;i++)

		{
			if(u[k][i]==-1)
				circle(img,Point(5+10*(i%10),5+10*(i/10)),1,Scalar(220,0,150),1,8,0);
			if(u[k][i]==1)
				rectangle(img,Point(10*(i%10)+2,10*(i/10)+2),Point(8+10*(i%10),8+10*(i/10)),Scalar(220,0,150),-1,8,0);
		}
		namedWindow(str,0);
		imshow(str,img );
		imwrite(str,img);

	}
	//waitKey();
	for(int k=0;k<7;k++)
		{
			for(int i=0;i<N;i++)
				for(int j=0;j<N;j++)
					W[i][j]=W[i][j]+u[k][i]*u[k][j];	
		}
		for(int i=0;i<N;i++)
		{
			for(int j=0;j<N;j++)
			{
				if(i!=j)
					W[i][j]=W[i][j]/N;	
				else
					W[i][j]=0;
			}
		}

	//加入噪音
	srand ( unsigned ( time (NULL) ) );
	for(int i=0;i<P;i++)
	{

		for(int j=0;j<N;j++)
		{

			int R=(rand()%4);
			if(R==0)
				u[i][j]=-u[i][j];
		}
	}
	

	//int v=0;
	int T=0;
	stringstream ss_noise;    
	string str_noise;
	
	while(T<5)
	{
		///画图
		stringstream ss_noise;    
		string str_noise;
		for(int k=0;k<P;k++)
		{
			str_noise="u";  
			ss_noise.clear();    
			ss_noise<<str_noise;    
			ss_noise<<k;  
			ss_noise<<"T"; 
			ss_noise<<T; 
			ss_noise<<".jpg";    
			ss_noise>>str_noise;    

			Mat img_noise(120,100,CV_8UC3,Scalar(130,240,205));//3通道图像
			for(int i=0;i<N;i++)

			{
				if(u[k][i]==-1)
					circle(img_noise,Point(5+10*(i%10),5+10*(i/10)),1,Scalar(220,0,150),1,8,0);
				if(u[k][i]==1)
					rectangle(img_noise,Point(10*(i%10)+2,10*(i/10)+2),Point(8+10*(i%10),8+10*(i/10)),Scalar(220,0,150),-1,8,0);
			}
			namedWindow(str_noise,0);
			imshow(str_noise,img_noise );
			imwrite(str_noise,img_noise);

		}

		T++;
		for(int k=0;k<7;k++)
		{
			
			
			for(int i=0;i<N;i++)
			{
				double v=0;
				
				for(int j=0;j<N;j++)
				{
					v=v+W[i][j]*u[k][j];
				}
				
				v=v-0.1;
				if(v>0)
					u[k][i]=1;
				else
				{
				if(v==0)
					u[k][i]=u[k][i];
				else
					u[k][i]=-1;
				}
			}
		}
	}
	waitKey();
	return 0;
}

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值