|
@@ -5,12 +5,17 @@
|
|
|
* @date 29-10-2007 (dd-mm-yyyy)
|
|
|
*/
|
|
|
|
|
|
+#ifdef NICE_USELIB_OPENMP
|
|
|
+#include <omp.h>
|
|
|
+#endif
|
|
|
+
|
|
|
+
|
|
|
+#include <set>
|
|
|
#include <iostream>
|
|
|
|
|
|
#include "vislearning/math/cluster/KMeans.h"
|
|
|
#include "vislearning/math/distances/genericDistance.h"
|
|
|
|
|
|
-#include <set>
|
|
|
|
|
|
using namespace OBJREC;
|
|
|
|
|
@@ -20,8 +25,8 @@ using namespace NICE;
|
|
|
|
|
|
#undef DEBUG_KMEANS
|
|
|
|
|
|
-KMeans::KMeans(const int & _noClasses, const std::string & _distanceType) :
|
|
|
- noClasses(_noClasses), distanceType(_distanceType)
|
|
|
+KMeans::KMeans(const int & _noClusters, const std::string & _distanceType) :
|
|
|
+ noClusters(_noClusters), distanceType(_distanceType)
|
|
|
{
|
|
|
//srand(time(NULL));
|
|
|
this->distancefunction = GenericDistanceSelection::selectDistance(distanceType);
|
|
@@ -35,7 +40,9 @@ KMeans::KMeans( const NICE::Config *conf, const std::string & _section)
|
|
|
this->d_minDelta = conf->gD( _section, "minDelta", 1e-5 );
|
|
|
this->i_maxIterations = conf->gI( _section, "maxIterations", 200);
|
|
|
|
|
|
- this->noClasses = conf->gI( _section, "noClasses", 20);
|
|
|
+ this->noClusters = conf->gI( _section, "noClusters", 20);
|
|
|
+ std::cerr << "KMeans::KMeans -- noClusters: " << this->noClusters << std::endl;
|
|
|
+
|
|
|
}
|
|
|
|
|
|
KMeans::~KMeans()
|
|
@@ -66,8 +73,8 @@ int KMeans::compute_prototypes(const VVector & features, VVector & prototypes,
|
|
|
std::vector<double> & weights, const std::vector<int> & assignment)
|
|
|
{
|
|
|
int j = 0;
|
|
|
- // fprintf (stderr, "KMeans::compute_prototypes: init noClasses=%d\n", noClasses);
|
|
|
- for (int k = 0; k < this->noClasses; k++)
|
|
|
+ // fprintf (stderr, "KMeans::compute_prototypes: init noClusters=%d\n", noClusters);
|
|
|
+ for (int k = 0; k < this->noClusters; k++)
|
|
|
{
|
|
|
prototypes[k].set(0);
|
|
|
weights[k] = 0;
|
|
@@ -100,7 +107,8 @@ int KMeans::compute_prototypes(const VVector & features, VVector & prototypes,
|
|
|
}
|
|
|
|
|
|
// fprintf (stderr, "KMeans::compute_prototypes: scaling\n");
|
|
|
- for (int k = 0; k < this->noClasses; k++)
|
|
|
+ #pragma omp parallel for
|
|
|
+ for (int k = 0; k < this->noClusters; k++)
|
|
|
{
|
|
|
|
|
|
NICE::Vector & p = prototypes[k];
|
|
@@ -109,19 +117,21 @@ int KMeans::compute_prototypes(const VVector & features, VVector & prototypes,
|
|
|
std::cerr << "prototype for this class before scaling : " << p << std::endl;
|
|
|
#endif
|
|
|
|
|
|
- if (weights[k] <= 0)
|
|
|
+// if (weights[k] <= 0)
|
|
|
+// {
|
|
|
+// return -1;
|
|
|
+// }
|
|
|
+ if (weights[k] > 0)
|
|
|
{
|
|
|
- return -1;
|
|
|
- }
|
|
|
+ p *= (1.0 / weights[k]);
|
|
|
|
|
|
- p *= (1.0 / weights[k]);
|
|
|
+ weights[k] = weights[k] / features.size();
|
|
|
|
|
|
- weights[k] = weights[k] / features.size();
|
|
|
-
|
|
|
- #ifdef DEBUG_KMEANS
|
|
|
- std::cerr << "prototype for this class after scaling with " << weights[k]
|
|
|
- << " : " << p << std::endl;
|
|
|
- #endif
|
|
|
+ #ifdef DEBUG_KMEANS
|
|
|
+ std::cerr << "prototype for this class after scaling with " << weights[k]
|
|
|
+ << " : " << p << std::endl;
|
|
|
+ #endif
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
@@ -147,11 +157,16 @@ double KMeans::compute_delta(const NICE::VVector & oldprototypes,
|
|
|
double KMeans::compute_assignments(const NICE::VVector & features,
|
|
|
const NICE::VVector & prototypes, std::vector<int> & assignment)
|
|
|
{
|
|
|
- int index = 0;
|
|
|
- for (VVector::const_iterator i = features.begin(); i != features.end(); i++, index++)
|
|
|
+// int index = 0;
|
|
|
+// for (VVector::const_iterator i = features.begin(); i != features.end(); i++, index++)
|
|
|
+
|
|
|
+ uint noFeatures ( features.size() );
|
|
|
+ #pragma omp parallel for
|
|
|
+ for (int index = 0; index < noFeatures; index++)
|
|
|
{
|
|
|
|
|
|
- const NICE::Vector & x = *i;
|
|
|
+// const NICE::Vector & x = *i;
|
|
|
+ const NICE::Vector & x = features[index];
|
|
|
double mindist = std::numeric_limits<double>::max();
|
|
|
int minclass = 0;
|
|
|
|
|
@@ -194,7 +209,7 @@ double KMeans::compute_assignments(const NICE::VVector & features,
|
|
|
double KMeans::compute_weights(const NICE::VVector & features,
|
|
|
std::vector<double> & weights, std::vector<int> & assignment)
|
|
|
{
|
|
|
- for (int k = 0; k < this->noClasses; k++)
|
|
|
+ for (int k = 0; k < this->noClusters; k++)
|
|
|
weights[k] = 0;
|
|
|
|
|
|
int j = 0;
|
|
@@ -205,7 +220,8 @@ double KMeans::compute_weights(const NICE::VVector & features,
|
|
|
weights[k]++;
|
|
|
}
|
|
|
|
|
|
- for (int k = 0; k < this->noClasses; k++)
|
|
|
+ #pragma omp parallel for
|
|
|
+ for (int k = 0; k < this->noClusters; k++)
|
|
|
weights[k] = weights[k] / features.size();
|
|
|
|
|
|
return 0.0;
|
|
@@ -219,12 +235,12 @@ void KMeans::cluster(const NICE::VVector & features, NICE::VVector & prototypes,
|
|
|
prototypes.clear();
|
|
|
weights.clear();
|
|
|
assignment.clear();
|
|
|
- weights.resize(noClasses, 0);
|
|
|
+ weights.resize(noClusters, 0);
|
|
|
assignment.resize(features.size(), 0);
|
|
|
|
|
|
int dimension;
|
|
|
|
|
|
- if ((int) features.size() >= this->noClasses)
|
|
|
+ if ((int) features.size() >= this->noClusters)
|
|
|
dimension = features[0].size();
|
|
|
else
|
|
|
{
|
|
@@ -233,7 +249,7 @@ void KMeans::cluster(const NICE::VVector & features, NICE::VVector & prototypes,
|
|
|
exit(-1);
|
|
|
}
|
|
|
|
|
|
- for (int k = 0; k < this->noClasses; k++)
|
|
|
+ for (int k = 0; k < this->noClusters; k++)
|
|
|
{
|
|
|
prototypes.push_back(Vector(dimension));
|
|
|
prototypes[k].set(0);
|