VC++ 6.0读取mat文件,并构建神经网络

本实验在vc++6.0中进行,使用c++语言实现对mat文件的读取,并送入神经网络进行训练

如果是VS中的可参考这个博主的https://blog.csdn.net/left_la/article/details/8206645

想在VC中调用matlab函数库,首先开始配置:

1、添加路径:

在project-settings-c/ C++ -category:-preprocessor-Additional include directories:栏目中添加:(根据自己Matlab的路径写)

C:\Program Files\MATLAB\R2016a\extern\include

C:\Program Files\MATLAB\R2016a\extern\lib

在project-settings-c/ C++ -category:-preprocessor-preprocessor definitions: 栏目中添加:
MS VC ,MSWIND

在project-settings-Link-Category-Input-Ignore libraries:栏目中添加:ms VC rt.lib

在Additional library path中加入C:\Program Files\MATLAB\R2016a\extern\lib

project options加入libmat.lib libmx.lib libmex.lib libeng.lib      这四个

然后就可以开始运行了~

但是我重启计算机之后需要重新配置,不知道为什么

代码是实现2分类的,可改成多分类。记得当时没改好,着急交就二分类了~

其中的mat文件有上传到资源里,可读取自己的mat文件

我的两类训练集和测试集全部在一个mat文件里

完整代码

#include<mat.h>
#include "matrix.h"
#include<iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#include<ctime>
using namespace std;
 
//输入一对数(x,y),输出为xxxx(x=0或1)
//判断(x,y)在第几象限,若在第一象限,则输出1000,以此类推;
//样本为随机的1000对(x,y)
//对指定输入对求其所在象限;
 
const int inputnode=59;//输入层神经元个数
const int hidenode=10;//隐含层神经元个数
const int outputnode=1;//输出层神经元个数
const int sample_train_num=140;//训练样本个数  
const int sample_test_num=40;//测试样本个数  
double **sample_train;
double **sample_test;
//const int test_num=450;
 
double w_ih[inputnode][hidenode];//输入层隐含层间权值矩阵
double w_ho[hidenode];//隐含层输出层间权值矩阵
 
double sita_h[hidenode];//隐含层间阈值
double sita_o;//输出层间阈值
 
//double sample[sample_num][inputnode];
double sample_train_label[sample_train_num];
double sample_test_label[sample_test_num];
 
double error[sample_train_num];
double totalerror=0;
 
double x[sample_train_num][inputnode];//网络输入
double a[sample_train_num][hidenode];//隐层的输出
double *y=new double[140];//[sample_train_num];//网络输出
double d[sample_train_num];//样本参考输出
double *outerrors=new double[5000];

 
double delta_ih[sample_train_num][hidenode];//输入到隐层的权值修正
double delta_ho[sample_train_num];//隐层到输出的权值修正
 
const int epochs=1000000;//迭代次数
const double goal=0.01;//误差目标精度
const double lr=0.1;//学习速率

int count=0;
/*void readmat()
{
	
	MATFile *pmatFile = NULL;    
	mxArray *pMxArray = NULL;    
    // 读取.mat文件(例:mat文件名为"initUrban.mat",其中包含"initA")    
    double *initA;    
    pmatFile = matOpen("Ucmd.mat","r");    
    pMxArray = matGetVariable(pmatFile, "initA");    
    initA = (double*) mxGetData(pMxArray);    
    M = mxGetM(pMxArray);    
    N = mxGetN(pMxArray);    
    Matrix<double> A(M,N);    
    for (int i=0; i<M; i++)    
        for (int j=0; j<N; j++)    
            A[i][j] = initA[M*j+i];    

    matClose(pmatFile);    
    mxFree(initA);    
}
void initmat()
{
    // 生成.mat文件    
    double *outA = new double[5000];    
        for (int i=0; i<5000; i++)    
          //  for (int j=0; j<N; j++)    
			outA[i] = A[i];    
    pmatFile = matOpen("A.mat","w");    
    mxSetData(pMxArray, outA);    
    matPutVariable(pmatFile, "A", pMxArray);    
    matClose(pmatFile);    
}*/
int* sample_fun()
{	

	MATFile *pmat;//指向mat文件的指针
    const char **dir;//元素名列表
    const char *file;//要打开的mat文件名
    int         ndir;//mat文件中的元素(矩阵、元胞)个数
    mxArray *cell1;//指向要读取的元胞数据的指针
   // mxArray *mat1;//指向元胞中某个元素的指针
    double *a;//指向元胞中某个元素第一个数据的指针
    int cellM,cellN,M,N;
    //int count;
    int i,j;
	//double **b;
	int *size;
	size=(int *)malloc(2* sizeof(int));

    file="ULBPNormalDatabase2.mat";  //要打开的mat文件名
    pmat = matOpen(file, "r");//打开文件,返回指向文件指针
    if (pmat == NULL)
    {
        printf("打开mat文件失败!");
    }
    //读取mat文件中的矩阵列表(返回mat中包含的元素的名字)
    dir = (const char **)matGetDir(pmat, &ndir);
    if (dir == NULL)
    {
        printf("读取mat文件失败!");
    }   

    //输出cellMat.mat中的元素数量
    printf("%s文件中一共有%d个元素\n",file,ndir);

    //从打开的mat文件中(pamt)读取名字为dir[0]的元胞
    //(返回指向该矩阵的指针,注意:MATLAB中的矩阵是按列优先存储到)
    cell1 = matGetVariable(pmat,dir[0]);//指向名字为dir[0]的元胞
	cout<<dir[0]<<endl;
    cellM = (int)mxGetM(cell1);//获取元胞的行数
	size[0] = cellM;
    cellN = (int)mxGetN(cell1);//获取元胞的列数
	size[1] = cellN;
	cout<<"M="<<cellM<<endl<<"N="<<cellN <<endl;
    //按列优先依次读取元胞中的数据
    //mat1 = mxGetCell(cell1,count);//按列优先,指向元胞中的第count+1个元素
	cout<<1<<endl;
    a = (double*)mxGetData(cell1);//指向mat1中的第一个数据
    M = (int)mxGetM(cell1);//获取mat1的行数
    N = (int)mxGetN(cell1);//获取mat1的列数
	size[0] = M;
	size[1] = N;
	printf("the size:%d,%d",size[0],size[1]);
	/*for(i=0;i<M;i++)
    {
        for (j=0;j<N;j++)
		{
           printf("%-5.4f ",a[j*M+i]);
		  // b[i][j]=a[j*M+i];
		   //printf("%-5.4f ",b[i][j]);
		  
		} printf("结束此时i=%d,j=%d\n",i,j);
        
    }*/

	sample_train=(double **)malloc((M-40)* sizeof(double*));
	sample_test=(double **)malloc(40* sizeof(double*));
	for(i=0;i<M-40;i++)
	{
		sample_train[i]=(double *)malloc(N*sizeof(double));
	}
	for(i=0;i<40;i++)
	{
		sample_test[i]=(double *)malloc(N*sizeof(double));
	}
    for(i=0;i<M;i++)
    {
        for (j=0;j<N;j++)
		{
           //printf("%-5.4f ",a[j*M+i]);
			if(i>=70&&i<90)
				sample_test[i-70][j]=a[j*M+i];
			else if(i>=160&&i<180)
				sample_test[i-140][j]=a[j*M+i];
			else if(i>=90&&i<160)
				sample_train[i-20][j]=a[j*M+i];
			else
				sample_train[i][j]=a[j*M+i];
		   //printf("%-5.4f ",samplefeature[i][j]);		  
		} printf("结束此时i=%d,j=%d\n",i,j);
    }
 
	//free(a);
	printf("维数为:(%d,%d)\n",M,N);
    matClose(pmat);//关闭文件
	return size; 
}
void init()
{
    //生成样本
    int i,j;
    //srand((unsigned)time(NULL));
    for(i=0;i<sample_train_num;i++)
    {   
        //sample[i][0]=(double)(rand()%20000-10000)/10000;
        //sample[i][1]=(double)(rand()%20000-10000)/10000;
        if(i<70)
        {
            sample_train_label[i]=0;
            //sample_train_label[i][1]=0;
            //sample_label[i][2]=0;
            //sample_label[i][3]=0;
        }
        else
        {
            sample_train_label[i]=1;
            //sample_train_label[i][1]=1;
            //sample_label[i][2]=0;
            //sample_label[i][3]=0;
        }
		printf("第%d训练样本标签的值%f%f\n",i,sample_train_label[i]);
	}
	/*for(i=0;i<sample_test_num;i++)
    {   
        //sample[i][0]=(double)(rand()%20000-10000)/10000;
        //sample[i][1]=(double)(rand()%20000-10000)/10000;
        if(i<20)
        {
            sample_test_label[i][0]=1;
            sample_test_label[i][1]=0;
        }
     
        else
        {
            sample_test_label[i][0]=0;
            sample_test_label[i][1]=1;
        }
		printf("第%d测试样本标签的值%f%f\n",i,sample_test_label[i][0],sample_test_label[i][1]);
	}*/
        /*if(sample[i][0]>0&&sample[i][1]<0)
        {
            sample_label[i][0]=0;
            sample_label[i][1]=0;
            sample_label[i][2]=0;
            sample_label[i][3]=1;
        }*/
    //初始化权值矩阵
    for(i=0;i<inputnode;i++)
    {
        for(j=0;j<hidenode;j++)
        {
            w_ih[i][j]=(double)(rand()%20000-10000)/10000;
        }
    }
    for(i=0;i<hidenode;i++)
    {
        w_ho[i]=(double)(rand()%20000-10000)/10000;
    }
    //初始化阈值
    for(i=0;i<hidenode;i++)
    {
        sita_h[i]=(double)(rand()%1000)/1000;
    }
    
    sita_o=(double)(rand()%1000)/1000;
    
    //初始化误差
    for(i=0;i<sample_train_num;i++)
    {
        error[i]=0;
    }
    //初始化权值调整系数
    for(i=0;i<sample_train_num;i++)
    {
        for(j=0;j<hidenode;j++)
        {
            delta_ih[i][j]=0;
        }
    }
    for(i=0;i<sample_train_num;i++)
    {
        
         delta_ho[i]=0;
        
    }
}
 
void train()
{
    cout<<"BP网络开始训练:"<<endl;
    int i,j,k;
	int m=0,n=0;
    for(int loop=0;loop<epochs;loop++)
    {
        totalerror=0;
        int count=0;
        for(i=0;i<sample_train_num;i++)
        {
            //读入样本
			for(m=0;m<inputnode;m++)
			{
				x[count][m]=sample_train[count][m];
			}
            d[count]=sample_train_label[count];
            //d[count][1]=sample_train_label[count][1];
            /*d[count][2]=sample_label[count][2];
            d[count][3]=sample_label[count][3];*/
            //计算隐含层输出
            double net_h[hidenode];
            for(j=0;j<hidenode;j++)
            {
				net_h[j]=0;
				for(m=0;m<inputnode;m++)
				{
					//net_h[j]=w_ih[0][j]*x[count][0]+w_ih[1][j]*x[count][1]-sita_h[j];
					net_h[j]+=w_ih[m][j]*x[count][m];
					
				}
				net_h[j]-=sita_h[j];
				a[count][j]=1/(1+exp(-net_h[j]));
            }
            //计算输出层输出
            double net_o;
            
            net_o=0;
            for(j=0;j<hidenode;j++)
            {
                 net_o+=w_ho[j]*a[count][j];
            }
            net_o-=sita_o;
            y[count]=1/(1+exp(-net_o));
            
            //计算样本误差
            
            error[count]+=(d[count]-y[count])*(d[count]-y[count]);
            
            error[count]/=2;
            //计算隐含层输出层间权值调整系数
           
            delta_ho[count]=(d[count]-y[count])*y[count]*(1-y[count]);
            
            //计算输入层到隐含层的权值调整系数
            for(j=0;j<hidenode;j++)
            {               
                delta_ih[count][j]+=delta_ho[count]*w_ho[j]*a[count][j]*(1-a[count][j]);
            }
            totalerror+=error[count];
            count++;
        }
		outerrors[loop]=totalerror; 
        cout<<"第"<<loop+1<<"次迭代,"<<"totalerror为:"<<totalerror<<endl;
		
        //调整w_ih
        double temp=0.0;
        for(i=0;i<inputnode;i++)
        {
            for(j=0;j<hidenode;j++)
            {
                temp=0;
                for(k=0;k<sample_train_num;k++)
                {
                    temp+=delta_ih[k][j]*x[k][i];
                }
                w_ih[i][j]+=lr*temp;
            }
        }
        //调整sita_h
        for(j=0;j<hidenode;j++)
        {
            temp=0;
            for(k=0;k<sample_train_num;k++)
            {
                temp-=delta_ih[k][j];
            }
            sita_h[j]+=0.005*temp;
        }
        //调整w_ho
        for(i=0;i<hidenode;i++)
        {
           
           temp = 0;
           for (k=0;k<sample_train_num;k++)
           {
               temp+=delta_ho[k]*a[k][i];
           }
           w_ho[i]+=lr*temp;
        }
        //调整sita_o

        temp=0;
        for(j=0;j<sample_train_num;j++)
        {
            temp-=delta_ho[j];
        }
        sita_o+=0.005*temp;
        if(totalerror<goal) break;
    }
}
 
void test(double *sample_test)
{
    int i,j;
    double net_h[hidenode];
    double net_o;
    double hide[hidenode];
    double output;
    for(j=0;j<hidenode;j++)
    {
		net_h[j]=0;
		for(i=0;i<inputnode;i++)
		{
        //net_h[j]=w_ih[0][j]*x0+w_ih[1][j]*y0-sita_h[j];
			net_h[j]+=w_ih[i][j]*sample_test[i];
			cout<<sample_test[i]<<" ";
		}
		net_h[j]-=sita_h[j];
        hide[j]=1/(1+exp(-net_h[j]));
    }
   
    net_o=0;
    for(j=0;j<hidenode;j++)
    {
        net_o+=w_ho[j]*hide[j];
    }
    net_o-=sita_o;
    output=1/(1+exp(-net_o));
   
    if(output<0.5) cout<<output<<"这个图片是台风眼"<<endl;
	else cout<<output<<"这个图片不是台风眼"<<endl;
}
 
void main()
{	
	int i,j,m;
	int *size=sample_fun();
	for(i=0;i<size[0]-40;i++)
    {
        for (j=0;j<size[1];j++)
		{
           //printf("%-5.4f ",a[j*M+i]);
		   printf("%-5.4f ",sample_train[i][j]);
		  
		} printf("结束此时i=%d,j=%d\n",i,j);
	}
	for(i=0;i<40;i++)
    {
        for (int j=0;j<size[1];j++)
		{
           //printf("%-5.4f ",a[j*M+i]);
		   printf("%-5.4f ",sample_test[i][j]);
		  
		} printf("结束此时i=%d,j=%d\n",i,j);
	}
        
	//printf("?????????????");
	//
//	printf("?????????????"); 
//printf("?????????????\n");/**/
	init();
    clock_t starttime=clock();
    train();
    clock_t endtime=clock();
    cout<<"训练时间为:"<<endtime-starttime<<"毫秒"<<endl;

/*	MATFile *pmatFile = NULL;
	mxArray *pWriteArray = NULL;
	pmatFile =matOpen("error.mat","w");
    //创建一个M*N的矩阵  
    pWriteArray = mxCreateDoubleMatrix(5000,1, mxREAL);  
    //把data的值赋给pWriteArray指针
    memcpy((void *)(mxGetPr(pWriteArray)), (void *)outerrors, sizeof(outerrors)*5000);
    //给矩阵命名为A
    matPutVariable(pmatFile, "A", pWriteArray); 
    matClose(pmatFile);  */

	MATFile *pmatFile2 = NULL;
	mxArray *pWriteArray2 = NULL;
	pmatFile2 =matOpen("outy.mat","w");
    //创建一个M*N的矩阵  
    pWriteArray2 = mxCreateDoubleMatrix(280,1, mxREAL);  
    //把data的值赋给pWriteArray指针
    memcpy((void *)(mxGetPr(pWriteArray2)), (void *)y, sizeof(y)*280);
    //给矩阵命名为A
    matPutVariable(pmatFile2, "outy", pWriteArray2); 
    matClose(pmatFile2); 


	double net_h[hidenode];
	double net_o;
	double hide[hidenode];
	double output;
	for(m=0;m<sample_test_num;m++)
    {
       /* test(sample_test[i]);*/
		//cout<<"start"<<*sample_test[i]<<" "<<endl;
		//cout<<sample_test[i][1]<<endl;
		for(j=0;j<hidenode;j++)
		{
			net_h[j]=0;
			for(i=0;i<inputnode;i++)
			{
			//net_h[j]=w_ih[0][j]*x0+w_ih[1][j]*y0-sita_h[j];
				net_h[j]+=w_ih[i][j]*sample_test[m][i];
			}
		//	cout<<"end"<<endl;
			net_h[j]-=sita_h[j];
			hide[j]=1/(1+exp(-net_h[j]));
		}
		net_o=0;
		for(j=0;j<hidenode;j++)
		{
			net_o+=w_ho[j]*hide[j];
		}
		net_o-=sita_o;
		output=1/(1+exp(-net_o));
		//if(output[0]>0.5) cout<<output[0]<<","<<output[1]<<"这个图片是台风眼"<<endl;
		//if(output[1]>0.5) cout<<output[0]<<","<<output[1]<<"这个图片不是台风眼"<<endl;
		if(output<0.5) cout<<output<<"这个图片是台风眼"<<endl;
		else cout<<output<<"这个图片不是台风眼"<<endl;
	
    }for(i=0;i<inputnode;i++)
			for(j=0;j<hidenode;j++)
				cout<<w_ih[i][j]<<" ";
		cout<<"end"<<endl;
		for(i=0;i<hidenode;i++)
			cout<<w_ho[i]<<" ";
		cout<<"end"<<endl;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章