GestureRecognitionToolkit  Version: 0.2.5
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 //Define the string that will be used to identify the object
27 std::string RBMQuantizer::id = "RBMQuantizer";
28 std::string RBMQuantizer::getId() { return RBMQuantizer::id; }
29 
30 //Register your module with the FeatureExtraction base class
32 
34 {
35  this->numClusters = numClusters;
36 }
37 
39 {
40  //Invoke the equals operator to copy the data from the rhs instance to this instance
41  *this = rhs;
42 }
43 
45 }
46 
48  if(this!=&rhs){
49  this->numClusters = rhs.numClusters;
50  this->rbm = rhs.rbm;
51  this->quantizationDistances = rhs.quantizationDistances;
52 
53  //Copy the base variables
55  }
56  return *this;
57 }
58 
59 bool RBMQuantizer::deepCopyFrom(const FeatureExtraction *featureExtraction){
60 
61  if( featureExtraction == NULL ) return false;
62 
63  if( this->getId() == featureExtraction->getId() ){
64 
65  //invoke the equals operator
66  *this = *dynamic_cast<const RBMQuantizer*>(featureExtraction);
67 
68  return true;
69  }
70 
71  errorLog << "deepCopyFrom(FeatureExtraction *featureExtraction) - FeatureExtraction Types Do Not Match!" << std::endl;
72 
73  return false;
74 }
75 
76 bool RBMQuantizer::computeFeatures(const VectorFloat &inputVector){
77 
78  //Run the quantize algorithm
79  quantize( inputVector );
80 
81  return true;
82 }
83 
85 
86  //Reset the base class
88 
89  if( trained ){
90  rbm.reset();
91  std::fill(quantizationDistances.begin(),quantizationDistances.end(),0);
92  }
93 
94  return true;
95 }
96 
98 
99  //Clear the base class
101 
102  rbm.clear();
103  quantizationDistances.clear();
104 
105  return true;
106 }
107 
108 bool RBMQuantizer::save( std::fstream &file ) const{
109 
110  if( !file.is_open() ){
111  errorLog << "save(fstream &file) - The file is not open!" << std::endl;
112  return false;
113  }
114 
115  //Write the header
116  file << "RBM_QUANTIZER_FILE_V1.0" << std::endl;
117 
118  //Save the base feature extraction settings to the file
120  errorLog << "saveFeatureExtractionSettingsToFile(fstream &file) - Failed to save base feature extraction settings to file!" << std::endl;
121  return false;
122  }
123 
124  file << "QuantizerTrained: " << trained << std::endl;
125  file << "NumClusters: " << numClusters << std::endl;
126 
127  if( trained ){
128  if( !rbm.save( file ) ){
129  errorLog << "save(fstream &file) - Failed to save RBM settings to file!" << std::endl;
130  return false;
131  }
132  }
133 
134  return true;
135 }
136 
137 bool RBMQuantizer::load( std::fstream &file ){
138 
139  //Clear any previous model
140  clear();
141 
142  if( !file.is_open() ){
143  errorLog << "load(fstream &file) - The file is not open!" << std::endl;
144  return false;
145  }
146 
147  std::string word;
148 
149  //First, you should read and validate the header
150  file >> word;
151  if( word != "RBM_QUANTIZER_FILE_V1.0" ){
152  errorLog << "load(fstream &file) - Invalid file format!" << std::endl;
153  return false;
154  }
155 
156  //Second, you should load the base feature extraction settings to the file
158  errorLog << "loadFeatureExtractionSettingsFromFile(fstream &file) - Failed to load base feature extraction settings from file!" << std::endl;
159  return false;
160  }
161 
162  file >> word;
163  if( word != "QuantizerTrained:" ){
164  errorLog << "load(fstream &file) - Failed to load QuantizerTrained!" << std::endl;
165  return false;
166  }
167  file >> trained;
168 
169  file >> word;
170  if( word != "NumClusters:" ){
171  errorLog << "load(fstream &file) - Failed to load NumClusters!" << std::endl;
172  return false;
173  }
174  file >> numClusters;
175 
176  if( trained ){
177  if( !rbm.load( file ) ){
178  errorLog << "load(fstream &file) - Failed to load SelfOrganizingMap settings from file!" << std::endl;
179  return false;
180  }
181  initialized = true;
182  featureDataReady = false;
183  quantizationDistances.resize(numClusters,0);
184  }
185 
186  return true;
187 }
188 
190  MatrixFloat data = trainingData.getDataAsMatrixFloat();
191  return train_( data );
192 }
193 
195  MatrixFloat data = trainingData.getDataAsMatrixFloat();
196  return train_( data );
197 }
198 
200  MatrixFloat data = trainingData.getDataAsMatrixFloat();
201  return train_( data );
202 }
203 
205  MatrixFloat data = trainingData.getDataAsMatrixFloat();
206  return train_( data );
207 }
208 
209 bool RBMQuantizer::train_(MatrixFloat &trainingData){
210 
211  //Clear any previous model
212  clear();
213 
214  if( trainingData.getNumRows() == 0 ){
215  errorLog << "train_(MatrixFloat &trainingData) - Failed to train quantizer, the training data is empty!" << std::endl;
216  return false;
217  }
218 
219  //Train the RBM model
220  rbm.setNumHiddenUnits( numClusters );
221  rbm.setLearningRate( learningRate );
222  rbm.setMinNumEpochs( minNumEpochs );
223  rbm.setMaxNumEpochs( maxNumEpochs );
224  rbm.setMinChange( minChange );
225 
226  if( !rbm.train_( trainingData ) ){
227  errorLog << "train_(MatrixFloat &trainingData) - Failed to train quantizer!" << std::endl;
228  return false;
229  }
230 
231  //Flag that the feature vector is now initalized
232  initialized = true;
233  trained = true;
234  numInputDimensions = trainingData.getNumCols();
235  numOutputDimensions = 1; //This is always 1 for the quantizer
236  featureVector.resize(numOutputDimensions,0);
237  quantizationDistances.resize(numClusters,0);
238 
239  return true;
240 }
241 
242 UINT RBMQuantizer::quantize(const Float inputValue){
243  return quantize( VectorFloat(1,inputValue) );
244 }
245 
246 UINT RBMQuantizer::quantize(const VectorFloat &inputVector){
247 
248  if( !trained ){
249  errorLog << "quantize(const VectorFloat &inputVector) - The quantizer model has not been trained!" << std::endl;
250  return 0;
251  }
252 
253  if( inputVector.getSize() != numInputDimensions ){
254  errorLog << "quantize(const VectorFloat &inputVector) - The size of the inputVector (" << inputVector.getSize() << ") does not match that of the filter (" << numInputDimensions << ")!" << std::endl;
255  return 0;
256  }
257 
258  if( !rbm.predict( inputVector ) ){
259  errorLog << "quantize(const VectorFloat &inputVector) - Failed to quantize input!" << std::endl;
260  return 0;
261  }
262 
263  quantizationDistances = rbm.getOutputData();
264 
265  //Search for the neuron with the maximum output
266  UINT quantizedValue = 0;
267  Float maxValue = 0;
268  for(UINT k=0; k<numClusters; k++){
269  if( quantizationDistances[k] > maxValue ){
270  maxValue = quantizationDistances[k];
271  quantizedValue = k;
272  }
273  }
274 
275  featureVector[0] = quantizedValue;
276  featureDataReady = true;
277 
278  return quantizedValue;
279 }
280 
282  return trained;
283 }
284 
286  return numClusters;
287 }
288 
290  return (trained ? static_cast<UINT>(featureVector[0]) : 0);
291 }
292 
294  return quantizationDistances;
295 }
296 
298  return rbm;
299 }
300 
301 bool RBMQuantizer::setNumClusters(const UINT numClusters){
302  clear();
303  this->numClusters = numClusters;
304  return true;
305 }
306 
307 GRT_END_NAMESPACE
bool setLearningRate(const Float learningRate)
Definition: MLBase.cpp:353
std::string getId() const
Definition: GRTBase.cpp:85
static std::string getId()
virtual bool predict(VectorFloat inputVector)
Definition: MLBase.cpp:135
virtual bool save(std::fstream &file) const
virtual bool deepCopyFrom(const FeatureExtraction *featureExtraction)
UINT getNumClusters() const
virtual bool reset()
Definition: MLBase.cpp:147
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:201
bool setNumClusters(const UINT numClusters)
virtual bool save(std::fstream &file) const
bool setMinChange(const Float minChange)
Definition: MLBase.cpp:344
virtual bool reset()
virtual bool computeFeatures(const VectorFloat &inputVector)
virtual bool train_(ClassificationData &trainingData)
unsigned int getNumRows() const
Definition: Matrix.h:574
MatrixFloat getDataAsMatrixFloat() const
unsigned int getNumCols() const
Definition: Matrix.h:581
The SOMQuantizer module quantizes the N-dimensional input vector to a 1-dimensional discrete value...
bool setMinNumEpochs(const UINT minNumEpochs)
Definition: MLBase.cpp:329
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 bool clear() override
virtual ~RBMQuantizer()
bool setMaxNumEpochs(const UINT maxNumEpochs)
Definition: MLBase.cpp:320
RBMQuantizer(const UINT numClusters=10)