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;
}

 

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