⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ukohonennet.cpp

📁 Kohonen神经网络的类代码
💻 CPP
字号:
//---------------------------------------------------------------------------

#include "stdafx.h"
#pragma hdrstop

#include "UKohonenNet.h"

#include "GEO_RasterData.h"

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>

//---------------------------------------------------------------------------
//随机选取J,当J大于N时,返回N;
unsigned int Random(int N) 
{
  unsigned int j;
  srand( (unsigned)time( NULL ) );
  j= (N*rand())/RAND_MAX;
  if ((int)j >= N) j=N;
  return j;
}


//---------------------------------------------------------------------------
// 构造函数
// 功能描述:
//
// 初始参数:numPatterns 原始模式数
//           sizeVector  每个模式的向量维数。
//           **data      原始模式
//           Shuffle     各个模式的数目混乱下标。
//---------------------------------------------------------------------------
TKNPattern::TKNPattern(CRasterData *pData)
{
	NumPatterns = pData->GetHeight();
	SizeVector = pData->GetWidth();
	m_pRaster = pData;
	Shuffle = new int[NumPatterns];
	for (int i=0; i<NumPatterns; i++)  Shuffle[i] = i;
}
//---------------------------------------------------------------------------
//功能描述:
//参数说明:
//---------------------------------------------------------------------------
TKNPattern::~TKNPattern(){
  delete[] Shuffle;
}
//---------------------------------------------------------------------------
//功能描述:
//         向量归一化。
//参数说明:
//         maxValue:归一化后的最大值
//----------------------------------------------------------------------------
int __fastcall TKNPattern::Norm(int maxValue)
{
  int i,q;
  double *mmin = new double[SizeVector];
  double *mmax = new double[SizeVector];
  for (q=0; q<SizeVector; q++)
  {
    mmin[q] = 10;
    mmax[q] = 0;
    for (i=0; i<NumPatterns; i++)
	{
		double temp=m_pRaster->GetDoublePixel(q,i);
		if(temp < mmin[q])
			mmin[q] = temp;
		if (temp > mmax[q])  
		  mmax[q] = temp;
    }
    for (i=0; i<NumPatterns; i++)
      m_pRaster->SetPixel(q,i,(float)(maxValue*(m_pRaster->GetDoublePixel(q,i)-mmin[q])/(mmax[q]-mmin[q])- maxValue/2.0));
  }
  
  delete[] mmin;
  delete[] mmax;
  return 0;
}
//---------------------------------------------------------------------------
// 功能说明:
//         从文件获得模式;
// 参数说明:
//         fname:存放模式的文件名;
//----------------------------------------------------------------------------
/*int TKNPattern::GetPatterns(char *fname) {
  FILE *fp;
  int i,j;
  double x;
  fp=fopen(fname,"r");
  if (fp==NULL) return 0;  // Test for failure.
  fscanf(fp,"%d",&NumPatterns);
  fscanf(fp,"%d",&SizeVector);

  Shuffle = new int[NumPatterns];
  P = new double*[NumPatterns];
  for (i=0; i<NumPatterns; i++){
    Shuffle[i] = i;
    P[i] = new double[SizeVector];
  }
  for (i=0; i<NumPatterns; i++) {         // For each vector
    for (j=0; j<SizeVector; j++) {       // create a pattern
      fscanf(fp,"%lf",&x);              // consisting of all elements
      P[i][j]=x;
    } //* endfor
  } //* endfor
  fclose(fp);
  return 1;
}*/
//-------------------------------------------------------------------------
//功能说明:
//         获得随机模式;
//参数说明:
//         n1:模式个数;
//         n2:每个模式的向量个数;
//---------------------------------------------------------------------------
int TKNPattern::GetRandPats(int n1,int n2) {
   int i,j;
   double x;
NumPatterns=n1;
SizeVector=n2;
for (i=0; i<NumPatterns; i++) {         // For each vector
   for (j=0; j<SizeVector; j++) {       // create a pattern
      x=(double)rand()/RAND_MAX;        // consisting of random elements
      //P[i][j]=x;                        // between 0 and 1
	  m_pRaster->SetPixel(j,i,(float)x);
      } /* endfor */
   } /* endfor */
return 1;
}
//---------------------------------------------------------------------------
//功能说明:
//        重新排列Shuffle;
//参数说明:
//        N:为Shuffle向量长度;
//---------------------------------------------------------------------------
void TKNPattern::ReShuffle(int N) {
int i,a1,a2,tmp;
for (i=0; i<N ;i++) {
   a1=Random(NumPatterns);
   a2=Random(NumPatterns);
   tmp=Shuffle[a1];
   Shuffle[a1]=Shuffle[a2];
   Shuffle[a2]=tmp;
   }
}
//----------------------------------------------------------------------------
//功能说明:
//        查询当前模式值
//参数说明:
//        pat:当前查询模式个数;
//         j: 当前查询模式向量维数;
//----------------------------------------------------------------------------
double TKNPattern::Query(int pat,int j) 
{
	//return P[pat][j];
	return m_pRaster->GetDoublePixel(j,pat);
}
//----------------------------------------------------------------------------
//功能说明:
//        查询混乱后模式值
//参数说明;
//        pat:模式个数;
//        j:  当前查询模式向量维数。
double TKNPattern::QueryR(int pat,int j) 
{
	//return P[Shuffle[pat]][j];
	return m_pRaster->GetDoublePixel(j,pat);
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//功能说明:
//        构造函数;
//参数说明:
//
//----------------------------------------------------------------------------
KNET::KNET(){
StochFlg=0;
}
//----------------------------------------------------------------------------
//功能说明:
//       析构函数;
//参数说明:
//
//-----------------------------------------------------------------------------
KNET::~KNET(){
  delete[] Label;
}
//-----------------------------------------------------------------------------
//功能说明:
//       设置模式;
//参数说明:
//       p:输入模式。
//-----------------------------------------------------------------------------
void KNET::SetPattern(TKNPattern *p) {
  m_pPattern=p;
  YinSize=p->SizeVector;
  Label = new unsigned char[p->NumPatterns];
}

//-----------------------------------------------------------------------------
//功能说明:
//        设置参数;权值参数初始化。
//参数说明:
//        X:输出层接点个数,即分类个数;
//        LR:learn rate;
//-----------------------------------------------------------------------------
void KNET::SetParms(int X, double LR){
  int i,k;
  YoutSize=X;
  eta=LR;
  delta_eta=0.005;
for (i=0; i<YoutSize; i++) {
   for (k=0; k<YinSize; k++) {
      W[k][i]= (double)rand()/(10.0 * (double)RAND_MAX);
      } /* endfor */
   } /* endfor */
}
//-------------------------------------------------------------------------------
//功能说明:
//        装载输入层;两种方式,一种是随机,一种非随机;
//参数说明:
//       P:模式节点下标;
//       StochFlg:当前节点的随机标识;
//--------------------------------------------------------------------------------
int KNET::LoadInLayer(int P){
  int i;
for (i=0; i<YinSize; i++){
   if (StochFlg){
      Yin[i]=m_pPattern->QueryR(P,i);
      }
    else {
      Yin[i]=m_pPattern->Query(P,i);
      }
   }
return 1;
}
//--------------------------------------------------------------------------
//功能说明:
//        自适应调节学习因子;
//参数说明:
//        fid:存放学习因子的文件;
//---------------------------------------------------------------------------
void KNET::AdaptParms(FILE *fid){
  eta=eta-delta_eta;
  if (eta<ETAMIN)
    eta=ETAMIN;
  #ifndef DEBUG
  fprintf(fid,"  New eta=%f\n",eta);
  #endif
}
//----------------------------------------------------------------------
//功能说明:
//        打印权值矩阵;
//参数说明:
//        fid:存放权值的文件名;
//-----------------------------------------------------------------------
void  KNET::PrintWeights(FILE *fid) {
   int i,k;
for (i=0; i<YoutSize; i++) {
      for (k=0; k<YinSize; k++) {
         fprintf(fid,"W[%d][%d]=%f  ",k,i,W[k][i]);
         } /* endfor */
      fprintf(fid,"\n");
   } /* endfor */
}
//--------------------------------------------------------------------------------
//功能说明:
//        训练网络权值,epoch为迭代次数,当竞争胜利,权值增加。
//参数说明:   
//-------------------------------------------------------------------------------
void KNET::RunTrn(){
  int i,np;
  int Winner;
  epoch=0;
  np=m_pPattern->NumPatterns;
  FILE *fid=NULL;
  #ifndef DEBUG
  if ((fid = fopen(".//FractalDimension.out","w")) == NULL)
    return;
  #endif
  while (epoch<=MAXEPOCHS){
    for (i=0; i<np; i++){
      LoadInLayer(i);
      Winner=FindWinner();
      Train(Winner);
    }
    #ifndef DEBUG
    if(50*(epoch/50)==epoch) {
      fprintf(fid,"Epoch=%d\n",epoch);
      PrintWeights(fid);
    }
    #endif
    epoch++;
    if (StochFlg)
      m_pPattern->ReShuffle(np);
    AdaptParms(fid);
  }
  #ifndef DEBUG
  fclose(fid);
  #endif
}

//------------------------------------------------------------------------------
//功能说明:
//        训练权值,胜利者权值变化。
//参数说明:
//        Winner:对应类别数,说明此向量属于Winner定义域中的哪个。
//-------------------------------------------------------------------------------
void KNET::Train(int Winner){
  int k;
for (k=0; k<YinSize; k++){
   W[k][Winner]=W[k][Winner]+eta*(Yin[k]-W[k][Winner]);
   } /*endfor*/
}


//------------------------------------------------------------------------
//功能说明:
//        找出胜利者,衡量标准是权值与输入向量的距离。
//-------------------------------------------------------------------------
int  KNET::FindWinner(){
  int i;
  double d,best;
  int Winner;
best=1.0e99;
Winner=-1;
for (i=0; i<YoutSize; i++){
  d=EucNorm(i);
  if (d<best) {
     best=d;
     Winner=i;
     } // endif
  } // endfor
return Winner;
}
//----------------------------------------------------------------------------
//距离函数
//----------------------------------------------------------------------------
double KNET::EucNorm(int x){   // Calc Euclidean norm of vector dif
int i;
double dist;
dist=0;
for (i=0; i< YinSize;i++){
   dist += (W[i][x]-Yin[i]) * (W[i][x]-Yin[i]);
   } /* endfor */
dist=sqrt(dist);
return dist;
}
//------------------------------------------------------------------
//功能说明:
//        完成聚类
//------------------------------------------------------------------
void KNET::Run()
{
  for (int i=0; i<m_pPattern->NumPatterns; i++){
    LoadInLayer(i);
    Label[i] = FindWinner();
  }
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -