?? som.class.cpp
字號:
#include <vector>
#include <iostream>
#include <math.h>
#include <stdlib.h>
#include "som.class.const.cpp"
#include "Unit1.h"
using namespace std;
// -----------------------------------------------------------------------
class som_Node
{
private:
//
public:
vector <double> l_weights;
som_Node(int,int,int);
float distance (const vector <double> &);
void update(const vector <double> &, const double, const double);
double color;
int X;
int Y;
};
som_Node::som_Node(int numWeights,int n_col,int n_row)
{
for (int i = 0; i < numWeights; ++i)
l_weights.push_back(RandFloat());
X = n_col;
Y = n_row;
}
float som_Node::distance(const vector <double> &Input)
{
double dist = 0;
for (unsigned int i = 0; i < l_weights.size(); ++i)
{
dist += (Input[i] - l_weights[i]) * (Input[i] - l_weights[i]);
}
return dist;
}
void som_Node::update(const vector <double> &Input, const double LearningRate, const double Influence)
{
for (unsigned int i = 0; i < l_weights.size(); ++i)
{
l_weights[i] += LearningRate * Influence * (Input[i] - l_weights[i]);
}
}
// ------------------------------------------------------------
class SOM
{
public:
SOM(int,int,int,int);
int Epoch(vector <vector <double> > );
som_Node* SOM::FindWinner(const vector <double> &);
int complete();
double getErrorValue(int,int);
som_Node **Latice;
int s_cols;
int s_rows;
int Iteration;
private:
int doneTraining;
int maxIter;
int numIterations;
double Radius;
double timeConst;
double mapRadius;
double influence;
double learningRate;
som_Node *winner;
};
SOM::SOM(int rows, int cols,int inputs,int maxI)
{
Latice = (som_Node **)calloc(rows,sizeof(som_Node *));
for (int row = 0; row < rows; row++)
{
Latice[row] = (som_Node *)calloc(cols,sizeof(som_Node));
for (int col = 0; col < cols; col++)
{
Latice[row][col] = som_Node(
inputs,
row,
col
);
}
}
doneTraining = FALSE;
maxIter = maxI;
learningRate = constStartLearningRate;
numIterations = constNumIterations;
Iteration = 0;
mapRadius = max(cols, rows)/2;
timeConst = (double) maxI/log(mapRadius);
s_cols = cols;
s_rows = rows;
}
int SOM::Epoch(vector <vector<double> > Input)
{
if (doneTraining) return 1;
if (maxIter--)
{
int selectPattern = RandInt(0, Input.size()-1);
winner = FindWinner(Input[selectPattern]);
Radius = mapRadius * exp(-(double)Iteration/timeConst);
for (int j = 0; j < s_rows; j++)
for (int i = 0; i < s_cols; i++)
{
double dist = (winner->X - Latice[j][i].X)*(winner->X - Latice[j][i].X) +
(winner->Y - Latice[j][i].Y)*(winner->Y - Latice[j][i].Y);
if (dist < Radius*Radius)
{
influence = exp(-(dist) / (2*Radius*Radius));
Latice[j][i].update(Input[selectPattern],learningRate,influence);
}
}
Iteration++;
learningRate = constStartLearningRate * exp(-(double)Iteration/numIterations);
}
else
{
doneTraining = 1;
}
return 1;
}
double SOM::getErrorValue(int y,int x)
{
double max = 0;
for (int j = -1; j <= 1; j++)
for (int i = -1; i <=1; i++)
{
if ( (x+i>=0) && (y+j >= 0) && (x + i < s_cols) && (y+j < s_cols) )
{
if ( (abs(Latice[y][x].X - Latice[y+j][x+i].X) <= 1) &&
(abs(Latice[y][x].Y - Latice[y+j][x+i].Y) <= 1) )
{
if (Latice[y][x].distance(Latice[y+j][x+i].l_weights) > max)
max = Latice[y][x].distance(Latice[y+j][x+i].l_weights);
}
}
}
return max;
}
som_Node* SOM::FindWinner(const vector <double> &pattern)
{
som_Node *temp_Winner;
double min = 9999999;
double dist = 0;
for (int j = 0; j < s_rows; j++)
for (int i = 0; i < s_cols; i++)
{
dist = Latice[j][i].distance(pattern);
if (dist < min)
{
min = dist;
temp_Winner = &Latice[j][i];
}
}
return temp_Winner;
}
int SOM::complete()
{
return doneTraining;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -