31 this->networkTypology = networkTypology;
32 this->maxNumEpochs = maxNumEpochs;
33 this->alphaStart = alphaStart;
34 this->alphaEnd = alphaEnd;
36 classType =
"SelfOrganizingMap";
37 clustererType = classType;
38 debugLog.setProceedingText(
"[DEBUG SelfOrganizingMap]");
39 errorLog.setProceedingText(
"[ERROR SelfOrganizingMap]");
40 trainingLog.setProceedingText(
"[TRAINING SelfOrganizingMap]");
41 warningLog.setProceedingText(
"[WARNING SelfOrganizingMap]");
46 classType =
"SelfOrganizingMap";
47 clustererType = classType;
48 debugLog.setProceedingText(
"[DEBUG KMeans]");
49 errorLog.setProceedingText(
"[ERROR KMeans]");
50 trainingLog.setProceedingText(
"[TRAINING KMeans]");
51 warningLog.setProceedingText(
"[WARNING KMeans]");
55 this->networkTypology = rhs.networkTypology;
56 this->alphaStart = rhs.alphaStart;
57 this->alphaEnd = rhs.alphaEnd;
72 this->networkTypology = rhs.networkTypology;
73 this->alphaStart = rhs.alphaStart;
74 this->alphaEnd = rhs.alphaEnd;
85 if( clusterer == NULL )
return false;
91 this->networkTypology = ptr->networkTypology;
92 this->alphaStart = ptr->alphaStart;
93 this->alphaEnd = ptr->alphaEnd;
117 networkWeights.
clear();
129 numInputDimensions = N;
137 errorLog <<
"train_( MatrixFloat &data ) - Failed to resize neurons Vector, there might not be enough memory!" << std::endl;
144 neurons[j].init( N, 0.5 );
151 switch( networkTypology ){
153 networkWeights.
resize(numClusters, numClusters);
157 networkWeights[i][i] = 1;
169 if( indexA != indexB ){
174 networkWeights[indexA][indexB] = weight;
175 networkWeights[indexB][indexA] = weight;
184 for(UINT i=0; i<M; i++){
185 for(UINT j=0; j<numInputDimensions; j++){
186 data[i][j] =
scale(data[i][j],ranges[j].minValue,ranges[j].maxValue,0,1);
193 Float trainingSampleError = 0;
196 Float weightUpdate = 0;
197 Float weightUpdateSum = 0;
199 Float neuronDiff = 0;
201 bool keepTraining =
true;
208 for(UINT i=0; i<M; i++){
209 randomTrainingOrder[i] = i;
211 std::random_shuffle(randomTrainingOrder.begin(), randomTrainingOrder.end());
214 while( keepTraining ){
217 alpha =
Util::scale(iter,0,maxNumEpochs,alphaStart,alphaEnd);
221 for(UINT i=0; i<M; i++){
223 trainingSampleError = 0;
226 trainingSample = data.
getRowVector( randomTrainingOrder[i] );
233 dist = neurons[j].getSquaredWeightDistance( trainingSample );
234 if( dist < bestDist ){
247 for(UINT n=0; n<N; n++){
248 neuronDiff = trainingSample[n] - neurons[j][n];
249 weightUpdate = networkWeights[bestIndex][j] * alpha * neuronDiff;
250 neurons[j][n] += weightUpdate;
251 weightUpdateSum += neuronDiff;
254 trainingSampleError += grt_sqr( weightUpdateSum );
257 error += grt_sqrt( trainingSampleError / numClusters );
261 delta = fabs( error-lastError );
265 if( delta <= minChange ){
267 keepTraining =
false;
270 if( grt_isinf( error ) ){
271 errorLog <<
"train_(MatrixFloat &data) - Training failed! Error is NAN!" << std::endl;
275 if( ++iter >= maxNumEpochs ){
276 keepTraining =
false;
279 trainingLog <<
"Epoch: " << iter <<
" Squared Error: " << error <<
" Delta: " << delta <<
" Alpha: " << alpha << std::endl;
282 numTrainingIterationsToConverge = iter;
305 for(UINT i=0; i<numInputDimensions; i++){
306 x[i] =
scale(x[i], ranges[i].minValue, ranges[i].maxValue, 0, 1);
314 mappedData[i] = neurons[i].fire( x );
323 errorLog <<
"saveModelToFile(fstream &file) - Can't save model to file, the model has not been trained!" << std::endl;
327 file <<
"GRT_SELF_ORGANIZING_MAP_MODEL_FILE_V1.0\n";
330 errorLog <<
"saveModelToFile(fstream &file) - Failed to save cluster settings to file!" << std::endl;
334 file <<
"NetworkTypology: " << networkTypology << std::endl;
335 file <<
"AlphaStart: " << alphaStart << std::endl;
336 file <<
"AlphaEnd: " << alphaEnd << std::endl;
339 file <<
"NetworkWeights: \n";
340 for(UINT i=0; i<networkWeights.
getNumRows(); i++){
341 for(UINT j=0; j<networkWeights.
getNumCols(); j++){
342 file << networkWeights[i][j];
343 if( j<networkWeights.getNumCols()-1 ) file <<
"\t";
348 file <<
"Neurons: \n";
349 for(UINT i=0; i<neurons.
getSize(); i++){
350 if( !neurons[i].saveNeuronToFile( file ) ){
351 errorLog <<
"saveModelToFile(fstream &file) - Failed to save neuron to file!" << std::endl;
368 if( word !=
"GRT_SELF_ORGANIZING_MAP_MODEL_FILE_V1.0" ){
369 errorLog <<
"loadModelFromFile(fstream &file) - Failed to load file header!" << std::endl;
374 errorLog <<
"loadModelFromFile(fstream &file) - Failed to load cluster settings from file!" << std::endl;
379 if( word !=
"NetworkTypology:" ){
380 errorLog <<
"loadModelFromFile(fstream &file) - Failed to load NetworkTypology header!" << std::endl;
383 file >> networkTypology;
386 if( word !=
"AlphaStart:" ){
387 errorLog <<
"loadModelFromFile(fstream &file) - Failed to load AlphaStart header!" << std::endl;
393 if( word !=
"AlphaEnd:" ){
394 errorLog <<
"loadModelFromFile(fstream &file) - Failed to load alphaEnd header!" << std::endl;
402 if( word !=
"NetworkWeights:" ){
403 errorLog <<
"loadModelFromFile(fstream &file) - Failed to load NetworkWeights header!" << std::endl;
408 for(UINT i=0; i<networkWeights.
getNumRows(); i++){
409 for(UINT j=0; j<networkWeights.
getNumCols(); j++){
410 file >> networkWeights[i][j];
415 if( word !=
"Neurons:" ){
416 errorLog <<
"loadModelFromFile(fstream &file) - Failed to load Neurons header!" << std::endl;
421 for(UINT i=0; i<neurons.size(); i++){
422 if( !neurons[i].loadNeuronFromFile( file ) ){
423 errorLog <<
"loadModelFromFile(fstream &file) - Failed to save neuron to file!" << std::endl;
433 if( networkTypology == RANDOM_NETWORK )
return true;
435 warningLog <<
"validateNetworkTypology(const UINT networkTypology) - Unknown networkTypology!" << std::endl;
444 Float SelfOrganizingMap::getAlphaStart()
const{
448 Float SelfOrganizingMap::getAlphaEnd()
const{
452 VectorFloat SelfOrganizingMap::getMappedData()
const{
464 MatrixFloat SelfOrganizingMap::getNetworkWeights()
const{
465 return networkWeights;
468 bool SelfOrganizingMap::setNetworkSize(
const UINT networkSize ){
469 if( networkSize > 0 ){
474 warningLog <<
"setNetworkSize(const UINT networkSize) - The networkSize must be greater than 0!" << std::endl;
479 bool SelfOrganizingMap::setNetworkTypology(
const UINT networkTypology ){
481 this->networkTypology = networkTypology;
487 bool SelfOrganizingMap::setAlphaStart(
const Float alphaStart ){
489 if( alphaStart > 0 ){
490 this->alphaStart = alphaStart;
494 warningLog <<
"setAlphaStart(const Float alphaStart) - AlphaStart must be greater than zero!" << std::endl;
499 bool SelfOrganizingMap::setAlphaEnd(
const Float alphaEnd ){
502 this->alphaEnd = alphaEnd;
506 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)
unsigned int getSize() const
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)