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

📄 somdoc.cpp

📁 神经网络中的无监督学习中的SOM学习算法
💻 CPP
字号:
// SOMDoc.cpp : implementation of the CSOMDoc class
//

#include "stdafx.h"
#include "SOM.h"
#include <math.h>
#include "SOMDoc.h"
#include "RandMaker.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CSOMDoc

IMPLEMENT_DYNCREATE(CSOMDoc, CDocument)

BEGIN_MESSAGE_MAP(CSOMDoc, CDocument)
	//{{AFX_MSG_MAP(CSOMDoc)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSOMDoc construction/destruction

CSOMDoc::CSOMDoc()
{
	// TODO: add one-time construction code here
}

CSOMDoc::~CSOMDoc()
{

}

BOOL CSOMDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	// TODO: add reinitialization code here
	// (SDI documents will reuse this document)

	return TRUE;
}



/////////////////////////////////////////////////////////////////////////////
// CSOMDoc serialization

void CSOMDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: add storing code here
	}
	else
	{
		// TODO: add loading code here
	}
}

/////////////////////////////////////////////////////////////////////////////
// CSOMDoc diagnostics

#ifdef _DEBUG
void CSOMDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CSOMDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CSOMDoc commands

void CSOMDoc::ClearPatterns()
{
    m_vecPatterns.clear();
}

void CSOMDoc::ResetWeights(int lines, int column)
{
    m_nLine = lines;
    m_nColumn = column;

    m_vecWeights.clear();
    m_vecWeights.resize(lines * column);
    RandMaker::RandInit();
    for (int i = 0; i < lines * column; i++)
    {
        m_vecWeights[i].x = RandMaker::AverageRand(-0.5, 0.5);
        m_vecWeights[i].y = RandMaker::AverageRand(-0.5, 0.5);
    }
}
void CSOMDoc::AddNormalPatterns(int nNum, double miu, double sigma, double min, double max)
{
    RandMaker::RandInit();
    int size = m_vecPatterns.size();
    m_vecPatterns.resize(size + nNum);
    for (int i = size; i < size + nNum; i++)
    {
        m_vecPatterns[i].x = RandMaker::NormalRand(min, max, miu, sigma);
        m_vecPatterns[i].y = RandMaker::NormalRand(min, max, miu, sigma);
    }
}

void CSOMDoc::AddAveragePatterns(int nNum, double min, double max)
{
    RandMaker::RandInit();
    int size = m_vecPatterns.size();
    m_vecPatterns.resize(size + nNum);
    for (int i = size; i < size + nNum; i++)
    {
        CPointf pf;
        pf.x = RandMaker::AverageRand(min, max);
        pf.y = RandMaker::AverageRand(min, max);
        
        m_vecPatterns[i] = pf;
    }
}

/**************************************************** 
  return false if no large changes occur in weights or something goes wrong,
  otherwise return true
/*****************************************************/
bool CSOMDoc::Train(int nPatternIndex, int step)
{
    double SIGMA_0 = (m_nColumn + m_nLine) / 4;
    double TAU_1 = m_vecPatterns.size() / log(SIGMA_0);
    double ETA_0 = 0.1;
    double TAU_2 = m_vecPatterns.size();

    if (nPatternIndex >= m_vecPatterns.size() || step < 0 || m_nColumn == 0)
        return false;

    double dmin = 1000000.0;
    int nWinnerIndex;
    int i;

    /* get the winner */
    for (i = 0; i < m_vecWeights.size(); i++)
    {
        double tmp = (m_vecPatterns[nPatternIndex].x - m_vecWeights[i].x) 
                   * (m_vecPatterns[nPatternIndex].x - m_vecWeights[i].x)
                   + (m_vecPatterns[nPatternIndex].y - m_vecWeights[i].y)
                   * (m_vecPatterns[nPatternIndex].y - m_vecWeights[i].y);

        if (dmin > tmp)
        {
            dmin = tmp;
            nWinnerIndex = i;
        }
    }

    /* adjust the weights */
    double sigma_n = SIGMA_0 * exp(-step / TAU_1);
    double eta_n = ETA_0 * exp(-step / TAU_2);

    double maxChange = 0.0;
    for (i = 0; i < m_vecWeights.size(); i++)
    {
        double line = (nWinnerIndex - i)  / m_nColumn;
        double column = nWinnerIndex % m_nColumn - i % m_nColumn;
        double d = line * line + column * column;
        double h = exp(-d / (2 * sigma_n * sigma_n));

        /* compute the change occuring in weights */
        column = eta_n * h * (m_vecPatterns[nPatternIndex].x - m_vecWeights[i].x);
        line = eta_n * h * (m_vecPatterns[nPatternIndex].y - m_vecWeights[i].y);
        d = line * line + column * column;

        m_vecWeights[i].x += column;
        m_vecWeights[i].y += line;

        if (maxChange < d)
        {
            maxChange  = d;
        }
    }

    if (maxChange < 0.00001)
        return false;

    return true;
}

CPointf& CSOMDoc::GetWeight(int line, int column)
{
    return m_vecWeights[line * m_nColumn + column]; 
}

⌨️ 快捷键说明

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