21 #define GRT_DLL_EXPORTS
32 this->networkTypology = networkTypology;
33 this->maxNumEpochs = maxNumEpochs;
34 this->alphaStart = alphaStart;
35 this->alphaEnd = alphaEnd;
37 classType =
"SelfOrganizingMap";
38 clustererType = classType;
39 debugLog.setProceedingText(
"[DEBUG SelfOrganizingMap]");
40 errorLog.setProceedingText(
"[ERROR SelfOrganizingMap]");
41 trainingLog.setProceedingText(
"[TRAINING SelfOrganizingMap]");
42 warningLog.setProceedingText(
"[WARNING SelfOrganizingMap]");
47 classType =
"SelfOrganizingMap";
48 clustererType = classType;
49 debugLog.setProceedingText(
"[DEBUG KMeans]");
50 errorLog.setProceedingText(
"[ERROR KMeans]");
51 trainingLog.setProceedingText(
"[TRAINING KMeans]");
52 warningLog.setProceedingText(
"[WARNING KMeans]");
56 this->networkTypology = rhs.networkTypology;
57 this->alphaStart = rhs.alphaStart;
58 this->alphaEnd = rhs.alphaEnd;
73 this->networkTypology = rhs.networkTypology;
74 this->alphaStart = rhs.alphaStart;
75 this->alphaEnd = rhs.alphaEnd;
86 if( clusterer == NULL )
return false;
92 this->networkTypology = ptr->networkTypology;
93 this->alphaStart = ptr->alphaStart;
94 this->alphaEnd = ptr->alphaEnd;
118 networkWeights.
clear();
130 numInputDimensions = N;
138 errorLog <<
"train_( MatrixFloat &data ) - Failed to resize neurons Vector, there might not be enough memory!" << std::endl;
145 neurons[j].init( N, 0.5 );
152 switch( networkTypology ){
154 networkWeights.
resize(numClusters, numClusters);
158 networkWeights[i][i] = 1;
170 if( indexA != indexB ){
175 networkWeights[indexA][indexB] = weight;
176 networkWeights[indexB][indexA] = weight;
185 for(UINT i=0; i<M; i++){
186 for(UINT j=0; j<numInputDimensions; j++){
187 data[i][j] =
scale(data[i][j],ranges[j].minValue,ranges[j].maxValue,0,1);
194 Float trainingSampleError = 0;
197 Float weightUpdate = 0;
198 Float weightUpdateSum = 0;
200 Float neuronDiff = 0;
202 bool keepTraining =
true;
209 for(UINT i=0; i<M; i++){
210 randomTrainingOrder[i] = i;
212 std::random_shuffle(randomTrainingOrder.begin(), randomTrainingOrder.end());
215 while( keepTraining ){
218 alpha =
Util::scale(iter,0,maxNumEpochs,alphaStart,alphaEnd);
222 for(UINT i=0; i<M; i++){
224 trainingSampleError = 0;
227 trainingSample = data.
getRowVector( randomTrainingOrder[i] );
234 dist = neurons[j].getSquaredWeightDistance( trainingSample );
235 if( dist < bestDist ){
248 for(UINT n=0; n<N; n++){
249 neuronDiff = trainingSample[n] - neurons[j][n];
250 weightUpdate = networkWeights[bestIndex][j] * alpha * neuronDiff;
251 neurons[j][n] += weightUpdate;
252 weightUpdateSum += neuronDiff;
255 trainingSampleError += grt_sqr( weightUpdateSum );
258 error += grt_sqrt( trainingSampleError / numClusters );
262 delta = fabs( error-lastError );
266 if( delta <= minChange ){
268 keepTraining =
false;
271 if( grt_isinf( error ) ){
272 errorLog <<
"train_(MatrixFloat &data) - Training failed! Error is NAN!" << std::endl;
276 if( ++iter >= maxNumEpochs ){
277 keepTraining =
false;
280 trainingLog <<
"Epoch: " << iter <<
" Squared Error: " << error <<
" Delta: " << delta <<
" Alpha: " << alpha << std::endl;
283 numTrainingIterationsToConverge = iter;
306 for(UINT i=0; i<numInputDimensions; i++){
307 x[i] =
scale(x[i], ranges[i].minValue, ranges[i].maxValue, 0, 1);
315 mappedData[i] = neurons[i].fire( x );
324 errorLog <<
"saveModelToFile(fstream &file) - Can't save model to file, the model has not been trained!" << std::endl;
328 file <<
"GRT_SELF_ORGANIZING_MAP_MODEL_FILE_V1.0\n";
331 errorLog <<
"saveModelToFile(fstream &file) - Failed to save cluster settings to file!" << std::endl;
335 file <<
"NetworkTypology: " << networkTypology << std::endl;
336 file <<
"AlphaStart: " << alphaStart << std::endl;
337 file <<
"AlphaEnd: " << alphaEnd << std::endl;
340 file <<
"NetworkWeights: \n";
341 for(UINT i=0; i<networkWeights.
getNumRows(); i++){
342 for(UINT j=0; j<networkWeights.
getNumCols(); j++){
343 file << networkWeights[i][j];
344 if( j<networkWeights.getNumCols()-1 ) file <<
"\t";
349 file <<
"Neurons: \n";
350 for(UINT i=0; i<neurons.
getSize(); i++){
351 if( !neurons[i].saveNeuronToFile( file ) ){
352 errorLog <<
"saveModelToFile(fstream &file) - Failed to save neuron to file!" << std::endl;
369 if( word !=
"GRT_SELF_ORGANIZING_MAP_MODEL_FILE_V1.0" ){
370 errorLog <<
"loadModelFromFile(fstream &file) - Failed to load file header!" << std::endl;
375 errorLog <<
"loadModelFromFile(fstream &file) - Failed to load cluster settings from file!" << std::endl;
380 if( word !=
"NetworkTypology:" ){
381 errorLog <<
"loadModelFromFile(fstream &file) - Failed to load NetworkTypology header!" << std::endl;
384 file >> networkTypology;
387 if( word !=
"AlphaStart:" ){
388 errorLog <<
"loadModelFromFile(fstream &file) - Failed to load AlphaStart header!" << std::endl;
394 if( word !=
"AlphaEnd:" ){
395 errorLog <<
"loadModelFromFile(fstream &file) - Failed to load alphaEnd header!" << std::endl;
403 if( word !=
"NetworkWeights:" ){
404 errorLog <<
"loadModelFromFile(fstream &file) - Failed to load NetworkWeights header!" << std::endl;
409 for(UINT i=0; i<networkWeights.
getNumRows(); i++){
410 for(UINT j=0; j<networkWeights.
getNumCols(); j++){
411 file >> networkWeights[i][j];
416 if( word !=
"Neurons:" ){
417 errorLog <<
"loadModelFromFile(fstream &file) - Failed to load Neurons header!" << std::endl;
422 for(UINT i=0; i<neurons.size(); i++){
423 if( !neurons[i].loadNeuronFromFile( file ) ){
424 errorLog <<
"loadModelFromFile(fstream &file) - Failed to save neuron to file!" << std::endl;
434 if( networkTypology == RANDOM_NETWORK )
return true;
436 warningLog <<
"validateNetworkTypology(const UINT networkTypology) - Unknown networkTypology!" << std::endl;
445 Float SelfOrganizingMap::getAlphaStart()
const{
449 Float SelfOrganizingMap::getAlphaEnd()
const{
453 VectorFloat SelfOrganizingMap::getMappedData()
const{
465 MatrixFloat SelfOrganizingMap::getNetworkWeights()
const{
466 return networkWeights;
469 bool SelfOrganizingMap::setNetworkSize(
const UINT networkSize ){
470 if( networkSize > 0 ){
475 warningLog <<
"setNetworkSize(const UINT networkSize) - The networkSize must be greater than 0!" << std::endl;
480 bool SelfOrganizingMap::setNetworkTypology(
const UINT networkTypology ){
482 this->networkTypology = networkTypology;
488 bool SelfOrganizingMap::setAlphaStart(
const Float alphaStart ){
490 if( alphaStart > 0 ){
491 this->alphaStart = alphaStart;
495 warningLog <<
"setAlphaStart(const Float alphaStart) - AlphaStart must be greater than zero!" << std::endl;
500 bool SelfOrganizingMap::setAlphaEnd(
const Float alphaEnd ){
503 this->alphaEnd = alphaEnd;
507 warningLog <<
"setAlphaEnd(const Float alphaEnd) - AlphaEnd must be greater than zero!" << std::endl;
virtual bool deepCopyFrom(const Clusterer *clusterer)
Float scale(const Float &x, const Float &minSource, const Float &maxSource, const Float &minTarget, const Float &maxTarget, const bool constrain=false)
This class implements the Self Oganizing Map clustering algorithm.
static Float scale(const Float &x, const Float &minSource, const Float &maxSource, const Float &minTarget, const Float &maxTarget, const bool constrain=false)
std::string getClustererType() const
MatrixFloat getDataAsMatrixFloat() const
virtual bool resize(const unsigned int size)
virtual bool train_(MatrixFloat &trainingData)
UINT getNetworkSize() const
bool copyBaseVariables(const Clusterer *clusterer)
bool validateNetworkTypology(const UINT networkTypology)
bool loadClustererSettingsFromFile(std::fstream &file)
virtual bool map_(VectorFloat &x)
SelfOrganizingMap(const UINT networkSize=20, const UINT networkTypology=RANDOM_NETWORK, const UINT maxNumEpochs=1000, const Float alphaStart=0.8, const Float alphaEnd=0.1)
bool saveClustererSettingsToFile(std::fstream &file) const
Vector< T > getRowVector(const unsigned int r) const
UINT numClusters
Number of clusters in the model.
unsigned int getNumRows() const
unsigned int getNumCols() const
virtual bool saveModelToFile(std::fstream &file) const
virtual bool loadModelFromFile(std::fstream &file)
Vector< MinMax > getRanges() const
Float getRandomNumberUniform(Float minRange=0.0, Float maxRange=1.0)
int getRandomNumberInt(int minRange, int maxRange)
MatrixFloat getDataAsMatrixFloat() const
virtual bool resize(const unsigned int r, const unsigned int c)
virtual ~SelfOrganizingMap()
SelfOrganizingMap & operator=(const SelfOrganizingMap &rhs)