GestureRecognitionToolkit  Version: 0.2.0
The Gesture Recognition Toolkit (GRT) is a cross-platform, open-source, c++ machine learning library for real-time gesture recognition.
RBMQuantizer.cpp
1 /*
2  GRT MIT License
3  Copyright (c) <2012> <Nicholas Gillian, Media Lab, MIT>
4 
5  Permission is hereby granted, free of charge, to any person obtaining a copy of this software
6  and associated documentation files (the "Software"), to deal in the Software without restriction,
7  including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
9  subject to the following conditions:
10 
11  The above copyright notice and this permission notice shall be included in all copies or substantial
12  portions of the Software.
13 
14  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
15  LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
17  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
18  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19  */
20 
21 #define GRT_DLL_EXPORTS
22 #include "RBMQuantizer.h"
23 
24 GRT_BEGIN_NAMESPACE
25 
26 //Register your module with the FeatureExtraction base class
27 RegisterFeatureExtractionModule< RBMQuantizer > RBMQuantizer::registerModule("RBMQuantizer");
28 
29 RBMQuantizer::RBMQuantizer(const UINT numClusters){
30 
31  this->numClusters = numClusters;
32  classType = "RBMQuantizer";
33  featureExtractionType = classType;
34  debugLog.setProceedingText("[DEBUG RBMQuantizer]");
35  errorLog.setProceedingText("[ERROR RBMQuantizer]");
36  warningLog.setProceedingText("[WARNING RBMQuantizer]");
37 }
38 
40 
41  classType = "RBMQuantizer";
42  featureExtractionType = classType;
43  debugLog.setProceedingText("[DEBUG RBMQuantizer]");
44  errorLog.setProceedingText("[ERROR RBMQuantizer]");
45  warningLog.setProceedingText("[WARNING RBMQuantizer]");
46 
47  //Invoke the equals operator to copy the data from the rhs instance to this instance
48  *this = rhs;
49 }
50 
52 }
53 
55  if(this!=&rhs){
56  this->numClusters = rhs.numClusters;
57  this->rbm = rhs.rbm;
58  this->quantizationDistances = rhs.quantizationDistances;
59 
60  //Copy the base variables
62  }
63  return *this;
64 }
65 
66 bool RBMQuantizer::deepCopyFrom(const FeatureExtraction *featureExtraction){
67 
68  if( featureExtraction == NULL ) return false;
69 
70  if( this->getFeatureExtractionType() == featureExtraction->getFeatureExtractionType() ){
71 
72  //invoke the equals operator
73  *this = *(RBMQuantizer*)featureExtraction;
74 
75  return true;
76  }
77 
78  errorLog << "clone(FeatureExtraction *featureExtraction) - FeatureExtraction Types Do Not Match!" << std::endl;
79 
80  return false;
81 }
82 
83 bool RBMQuantizer::computeFeatures(const VectorFloat &inputVector){
84 
85  //Run the quantize algorithm
86  quantize( inputVector );
87 
88  return true;
89 }
90 
92 
93  //Reset the base class
95 
96  if( trained ){
97  rbm.reset();
98  std::fill(quantizationDistances.begin(),quantizationDistances.end(),0);
99  }
100 
101  return true;
102 }
103 
105 
106  //Clear the base class
108 
109  rbm.clear();
110  quantizationDistances.clear();
111 
112  return true;
113 }
114 
115 bool RBMQuantizer::save( std::fstream &file ) const{
116 
117  if( !file.is_open() ){
118  errorLog << "save(fstream &file) - The file is not open!" << std::endl;
119  return false;
120  }
121 
122  //Write the header
123  file << "RBM_QUANTIZER_FILE_V1.0" << std::endl;
124 
125  //Save the base feature extraction settings to the file
127  errorLog << "saveFeatureExtractionSettingsToFile(fstream &file) - Failed to save base feature extraction settings to file!" << std::endl;
128  return false;
129  }
130 
131  file << "QuantizerTrained: " << trained << std::endl;
132  file << "NumClusters: " << numClusters << std::endl;
133 
134  if( trained ){
135  if( !rbm.save( file ) ){
136  errorLog << "save(fstream &file) - Failed to save RBM settings to file!" << std::endl;
137  return false;
138  }
139  }
140 
141  return true;
142 }
143 
144 bool RBMQuantizer::load( std::fstream &file ){
145 
146  //Clear any previous model
147  clear();
148 
149  if( !file.is_open() ){
150  errorLog << "load(fstream &file) - The file is not open!" << std::endl;
151  return false;
152  }
153 
154  std::string word;
155 
156  //First, you should read and validate the header
157  file >> word;
158  if( word != "RBM_QUANTIZER_FILE_V1.0" ){
159  errorLog << "load(fstream &file) - Invalid file format!" << std::endl;
160  return false;
161  }
162 
163  //Second, you should load the base feature extraction settings to the file
165  errorLog << "loadFeatureExtractionSettingsFromFile(fstream &file) - Failed to load base feature extraction settings from file!" << std::endl;
166  return false;
167  }
168 
169  file >> word;
170  if( word != "QuantizerTrained:" ){
171  errorLog << "load(fstream &file) - Failed to load QuantizerTrained!" << std::endl;
172  return false;
173  }
174  file >> trained;
175 
176  file >> word;
177  if( word != "NumClusters:" ){
178  errorLog << "load(fstream &file) - Failed to load NumClusters!" << std::endl;
179  return false;
180  }
181  file >> numClusters;
182 
183  if( trained ){
184  if( !rbm.load( file ) ){
185  errorLog << "load(fstream &file) - Failed to load SelfOrganizingMap settings from file!" << std::endl;
186  return false;
187  }
188  initialized = true;
189  featureDataReady = false;
190  quantizationDistances.resize(numClusters,0);
191  }
192 
193  return true;
194 }
195 
197  MatrixFloat data = trainingData.getDataAsMatrixFloat();
198  return train_( data );
199 }
200 
202  MatrixFloat data = trainingData.getDataAsMatrixFloat();
203  return train_( data );
204 }
205 
207  MatrixFloat data = trainingData.getDataAsMatrixFloat();
208  return train_( data );
209 }
210 
212  MatrixFloat data = trainingData.getDataAsMatrixFloat();
213  return train_( data );
214 }
215 
216 bool RBMQuantizer::train_(MatrixFloat &trainingData){
217 
218  //Clear any previous model
219  clear();
220 
221  if( trainingData.getNumRows() == 0 ){
222  errorLog << "train_(MatrixFloat &trainingData) - Failed to train quantizer, the training data is empty!" << std::endl;
223  return false;
224  }
225 
226  //Train the RBM model
227  rbm.setNumHiddenUnits( numClusters );
228  rbm.setLearningRate( learningRate );
229  rbm.setMinNumEpochs( minNumEpochs );
230  rbm.setMaxNumEpochs( maxNumEpochs );
231  rbm.setMinChange( minChange );
232 
233  if( !rbm.train_( trainingData ) ){
234  errorLog << "train_(MatrixFloat &trainingData) - Failed to train quantizer!" << std::endl;
235  return false;
236  }
237 
238  //Flag that the feature vector is now initalized
239  initialized = true;
240  trained = true;
241  numInputDimensions = trainingData.getNumCols();
242  numOutputDimensions = 1; //This is always 1 for the quantizer
243  featureVector.resize(numOutputDimensions,0);
244  quantizationDistances.resize(numClusters,0);
245 
246  return true;
247 }
248 
249 UINT RBMQuantizer::quantize(const Float inputValue){
250  return quantize( VectorFloat(1,inputValue) );
251 }
252 
253 UINT RBMQuantizer::quantize(const VectorFloat &inputVector){
254 
255  if( !trained ){
256  errorLog << "quantize(const VectorFloat &inputVector) - The quantizer model has not been trained!" << std::endl;
257  return 0;
258  }
259 
260  if( inputVector.getSize() != numInputDimensions ){
261  errorLog << "quantize(const VectorFloat &inputVector) - The size of the inputVector (" << inputVector.getSize() << ") does not match that of the filter (" << numInputDimensions << ")!" << std::endl;
262  return 0;
263  }
264 
265  if( !rbm.predict( inputVector ) ){
266  errorLog << "quantize(const VectorFloat &inputVector) - Failed to quantize input!" << std::endl;
267  return 0;
268  }
269 
270  quantizationDistances = rbm.getOutputData();
271 
272  //Search for the neuron with the maximum output
273  UINT quantizedValue = 0;
274  Float maxValue = 0;
275  for(UINT k=0; k<numClusters; k++){
276  if( quantizationDistances[k] > maxValue ){
277  maxValue = quantizationDistances[k];
278  quantizedValue = k;
279  }
280  }
281 
282  featureVector[0] = quantizedValue;
283  featureDataReady = true;
284 
285  return quantizedValue;
286 }
287 
289  return trained;
290 }
291 
293  return numClusters;
294 }
295 
297  return (trained ? static_cast<UINT>(featureVector[0]) : 0);
298 }
299 
301  return quantizationDistances;
302 }
303 
305  return rbm;
306 }
307 
308 bool RBMQuantizer::setNumClusters(const UINT numClusters){
309  clear();
310  this->numClusters = numClusters;
311  return true;
312 }
313 
314 GRT_END_NAMESPACE
315 
bool setLearningRate(const Float learningRate)
Definition: MLBase.cpp:296
virtual bool predict(VectorFloat inputVector)
Definition: MLBase.cpp:113
virtual bool save(std::fstream &file) const
virtual bool deepCopyFrom(const FeatureExtraction *featureExtraction)
UINT getNumClusters() const
bool saveFeatureExtractionSettingsToFile(std::fstream &file) const
virtual bool clear()
MatrixFloat getDataAsMatrixFloat() const
virtual bool reset()
virtual bool resize(const unsigned int size)
Definition: Vector.h:133
UINT quantize(const Float inputValue)
RBMQuantizer & operator=(const RBMQuantizer &rhs)
BernoulliRBM getBernoulliRBM() const
virtual bool clear()
virtual bool load(std::fstream &file)
VectorFloat getQuantizationDistances() const
UINT getSize() const
Definition: Vector.h:191
bool setNumClusters(const UINT numClusters)
virtual bool save(std::fstream &file) const
bool setMinChange(const Float minChange)
Definition: MLBase.cpp:287
virtual bool reset()
std::string getFeatureExtractionType() const
virtual bool reset()
virtual bool computeFeatures(const VectorFloat &inputVector)
virtual bool train_(ClassificationData &trainingData)
unsigned int getNumRows() const
Definition: Matrix.h:542
MatrixFloat getDataAsMatrixFloat() const
unsigned int getNumCols() const
Definition: Matrix.h:549
The SOMQuantizer module quantizes the N-dimensional input vector to a 1-dimensional discrete value...
bool setMinNumEpochs(const UINT minNumEpochs)
Definition: MLBase.cpp:282
UINT getQuantizedValue() const
bool loadFeatureExtractionSettingsFromFile(std::fstream &file)
virtual bool load(std::fstream &file)
MatrixFloat getDataAsMatrixFloat() const
virtual bool train_(MatrixFloat &data)
bool getQuantizerTrained() const
bool copyBaseVariables(const FeatureExtraction *featureExtractionModule)
virtual ~RBMQuantizer()
bool setMaxNumEpochs(const UINT maxNumEpochs)
Definition: MLBase.cpp:273
RBMQuantizer(const UINT numClusters=10)