GestureRecognitionToolkit  Version: 0.1.0
The Gesture Recognition Toolkit (GRT) is a cross-platform, open-source, c++ machine learning library for real-time gesture recognition.
BernoulliRBM.cpp
1 
2 #include "BernoulliRBM.h"
3 
4 GRT_BEGIN_NAMESPACE
5 
6 BernoulliRBM::BernoulliRBM(const UINT numHiddenUnits,const UINT maxNumEpochs,const Float learningRate,const Float learningRateUpdate,const Float momentum,const bool useScaling,const bool randomiseTrainingOrder){
7 
8  this->numHiddenUnits = numHiddenUnits;
9  this->maxNumEpochs = maxNumEpochs;
10  this->learningRate = learningRate;
11  this->learningRateUpdate = learningRateUpdate;
12  this->momentum = momentum;
13  this->useScaling = useScaling;
14  this->randomiseTrainingOrder = randomiseTrainingOrder;
15  randomizeWeightsForTraining = true;
16  batchSize = 100;
17  batchStepSize = 1;
18  minNumEpochs = 1;
19  minChange = 1.0e-5;
20 
21  classType = "BernoulliRBM";
22  debugLog.setProceedingText("[DEBUG BernoulliRBM]");
23  errorLog.setProceedingText("[ERROR BernoulliRBM]");
24  trainingLog.setProceedingText("[TRAINING BernoulliRBM]");
25  warningLog.setProceedingText("[WARNING BernoulliRBM]");
26 }
27 
28 BernoulliRBM::~BernoulliRBM(){
29 
30 }
31 
33 
34  if( !predict_(inputData,outputData) ){
35  return false;
36  }
37 
38  return true;
39 }
40 
41 bool BernoulliRBM::predict_(VectorFloat &inputData,VectorFloat &outputData){
42 
43  if( !trained ){
44  errorLog << "predict_(VectorFloat &inputData,VectorFloat &outputData) - Failed to run prediction - the model has not been trained." << std::endl;
45  return false;
46  }
47 
48  if( inputData.size() != numVisibleUnits ){
49  errorLog << "predict_(VectorFloat &inputData,VectorFloat &outputData) - Failed to run prediction - the input data size (" << inputData.size() << ")";
50  errorLog << " does not match the number of visible units (" << numVisibleUnits << "). " << std::endl;
51  return false;
52  }
53 
54  if( outputData.size() != numHiddenUnits ){
55  outputData.resize( numHiddenUnits );
56  }
57 
58  //Scale the data if needed
59  if( useScaling ){
60  for(UINT i=0; i<numVisibleUnits; i++){
61  inputData[i] = grt_scale(inputData[i],ranges[i].minValue,ranges[i].maxValue,0.0,1.0);
62  }
63  }
64 
65  //Propagate the data up through the RBM
66  Float x = 0.0;
67  for(UINT i=0; i<numHiddenUnits; i++){
68  for(UINT j=0; j<numVisibleUnits; j++) {
69  x += weightsMatrix[i][j] * inputData[j];
70  }
71  outputData[i] = grt_sigmoid( x + hiddenLayerBias[i] );
72  }
73 
74  return true;
75 }
76 
77 bool BernoulliRBM::predict_(const MatrixFloat &inputData,MatrixFloat &outputData,const UINT rowIndex){
78 
79  if( !trained ){
80  errorLog << "predict_(const MatrixFloat &inputData,MatrixFloat &outputData,const UINT rowIndex) - Failed to run prediction - the model has not been trained." << std::endl;
81  return false;
82  }
83 
84  if( inputData.getNumCols() != numVisibleUnits ){
85  errorLog << "predict_(const MatrixFloat &inputData,MatrixFloat &outputData,const UINT rowIndex) -";
86  errorLog << " Failed to run prediction - the number of columns in the input matrix (" << inputData.getNumCols() << ")";
87  errorLog << " does not match the number of visible units (" << numVisibleUnits << ")." << std::endl;
88  return false;
89  }
90 
91  if( outputData.getNumCols() != numHiddenUnits ){
92  errorLog << "predict_(const MatrixFloat &inputData,MatrixFloat &outputData,const UINT rowIndex) -";
93  errorLog << " Failed to run prediction - the number of columns in the output matrix (" << outputData.getNumCols() << ")";
94  errorLog << " does not match the number of hidden units (" << numHiddenUnits << ")." << std::endl;
95  return false;
96  }
97 
98  //Propagate the data up through the RBM
99  Float x = 0.0;
100  for(UINT j=0; j<numHiddenUnits; j++){
101  x = 0;
102  for(UINT i=0; i<numVisibleUnits; i++) {
103  x += weightsMatrix[j][i] * inputData[rowIndex][i];
104  }
105  outputData[rowIndex][j] = grt_sigmoid( x + hiddenLayerBias[j] ); //This gives P( h_j = 1 | input )
106  }
107 
108  return true;
109 }
110 
112 
113  const UINT numTrainingSamples = data.getNumRows();
114  numInputDimensions = data.getNumCols();
115  numOutputDimensions = numHiddenUnits;
116  numVisibleUnits = numInputDimensions;
117 
118  trainingLog << "NumInputDimensions: " << numInputDimensions << std::endl;
119  trainingLog << "NumOutputDimensions: " << numOutputDimensions << std::endl;
120 
121  if( randomizeWeightsForTraining ){
122 
123  //Init the weights matrix
124  weightsMatrix.resize(numHiddenUnits, numVisibleUnits);
125 
126  Float a = 1.0 / numVisibleUnits;
127  for(UINT i=0; i<numHiddenUnits; i++) {
128  for(UINT j=0; j<numVisibleUnits; j++) {
129  weightsMatrix[i][j] = rand.getRandomNumberUniform(-a, a);
130  }
131  }
132 
133  //Init the bias units
134  visibleLayerBias.resize( numVisibleUnits );
135  hiddenLayerBias.resize( numHiddenUnits );
136  std::fill(visibleLayerBias.begin(),visibleLayerBias.end(),0);
137  std::fill(hiddenLayerBias.begin(),hiddenLayerBias.end(),0);
138 
139  }else{
140  if( weightsMatrix.getNumRows() != numHiddenUnits ){
141  errorLog << "train_(MatrixFloat &data) - Weights matrix row size does not match the number of hidden units!" << std::endl;
142  return false;
143  }
144  if( weightsMatrix.getNumCols() != numVisibleUnits ){
145  errorLog << "train_(MatrixFloat &data) - Weights matrix row size does not match the number of visible units!" << std::endl;
146  return false;
147  }
148  if( visibleLayerBias.size() != numVisibleUnits ){
149  errorLog << "train_(MatrixFloat &data) - Visible layer bias size does not match the number of visible units!" << std::endl;
150  return false;
151  }
152  if( hiddenLayerBias.size() != numHiddenUnits ){
153  errorLog << "train_(MatrixFloat &data) - Hidden layer bias size does not match the number of hidden units!" << std::endl;
154  return false;
155  }
156  }
157 
158  //Flag the model has been trained encase the user wants to save the model during a training iteration using an observer
159  trained = true;
160 
161  //Make sure the data is scaled between [0 1]
162  ranges = data.getRanges();
163  if( useScaling ){
164  for(UINT i=0; i<numTrainingSamples; i++){
165  for(UINT j=0; j<numInputDimensions; j++){
166  data[i][j] = grt_scale(data[i][j], ranges[j].minValue, ranges[j].maxValue, 0.0, 1.0);
167  }
168  }
169  }
170 
171 
172  const UINT numBatches = static_cast<UINT>( ceil( Float(numTrainingSamples)/batchSize ) );
173 
174  //Setup the batch indexs
175  Vector< BatchIndexs > batchIndexs( numBatches );
176  UINT startIndex = 0;
177  for(UINT i=0; i<numBatches; i++){
178  batchIndexs[i].startIndex = startIndex;
179  batchIndexs[i].endIndex = startIndex + batchSize;
180 
181  //Make sure the last batch end index is not larger than the number of training examples
182  if( batchIndexs[i].endIndex >= numTrainingSamples ){
183  batchIndexs[i].endIndex = numTrainingSamples;
184  }
185 
186  //Get the batch size
187  batchIndexs[i].batchSize = batchIndexs[i].endIndex - batchIndexs[i].startIndex;
188 
189  //Set the start index for the next batch
190  startIndex = batchIndexs[i].endIndex;
191  }
192 
193  Timer timer;
194  UINT i,j,n,epoch,noChangeCounter = 0;
195  Float startTime = 0;
196  Float alpha = learningRate;
197  Float error = 0;
198  Float err = 0;
199  Float delta = 0;
200  Float lastError = 0;
201  Vector< UINT > indexList(numTrainingSamples);
202  TrainingResult trainingResult;
203  MatrixFloat wT( numVisibleUnits, numHiddenUnits ); //Stores a transposed copy of the weights vector
204  MatrixFloat vW( numHiddenUnits, numVisibleUnits ); //Stores the weight velocity updates
205  MatrixFloat tmpW( numHiddenUnits, numVisibleUnits ); //Stores the weight values that will be used to update the main weights matrix at each batch update
206  MatrixFloat v1( batchSize, numVisibleUnits ); //Stores the real batch data during a batch update
207  MatrixFloat v2( batchSize, numVisibleUnits ); //Stores the sampled batch data during a batch update
208  MatrixFloat h1( batchSize, numHiddenUnits ); //Stores the hidden states given v1 and the current weightsMatrix
209  MatrixFloat h2( batchSize, numHiddenUnits ); //Stores the sampled hidden states given v2 and the current weightsMatrix
210  MatrixFloat c1( numHiddenUnits, numVisibleUnits ); //Stores h1' * v1
211  MatrixFloat c2( numHiddenUnits, numVisibleUnits ); //Stores h2' * v2
212  MatrixFloat vDiff( batchSize, numVisibleUnits ); //Stores the difference between v1-v2
213  MatrixFloat hDiff( batchSize, numVisibleUnits ); //Stores the difference between h1-h2
214  MatrixFloat cDiff( numHiddenUnits, numVisibleUnits ); //Stores the difference between c1-c2
215  VectorFloat vDiffSum( numVisibleUnits ); //Stores the column sum of vDiff
216  VectorFloat hDiffSum( numHiddenUnits ); //Stores the column sum of hDiff
217  VectorFloat visibleLayerBiasVelocity( numVisibleUnits ); //Stores the velocity update of the visibleLayerBias
218  VectorFloat hiddenLayerBiasVelocity( numHiddenUnits ); //Stores the velocity update of the hiddenLayerBias
219 
220  //Set all the velocity weights to zero
221  vW.setAllValues( 0 );
222  std::fill(visibleLayerBiasVelocity.begin(),visibleLayerBiasVelocity.end(),0);
223  std::fill(hiddenLayerBiasVelocity.begin(),hiddenLayerBiasVelocity.end(),0);
224 
225  //Randomize the order that the training samples will be used in
226  for(UINT i=0; i<numTrainingSamples; i++) indexList[i] = i;
227  if( randomiseTrainingOrder ){
228  std::random_shuffle(indexList.begin(), indexList.end());
229  }
230 
231  //Start the main training loop
232  timer.start();
233  for(epoch=0; epoch<maxNumEpochs; epoch++) {
234  startTime = timer.getMilliSeconds();
235  error = 0;
236 
237  //Randomize the batch order
238  std::random_shuffle(batchIndexs.begin(),batchIndexs.end());
239 
240  //Run each of the batch updates
241  for(UINT k=0; k<numBatches; k+=batchStepSize){
242 
243  //Resize the data matrices, the matrices will only be resized if the rows cols are different
244  v1.resize( batchIndexs[k].batchSize, numVisibleUnits );
245  h1.resize( batchIndexs[k].batchSize, numHiddenUnits );
246  v2.resize( batchIndexs[k].batchSize, numVisibleUnits );
247  h2.resize( batchIndexs[k].batchSize, numHiddenUnits );
248 
249  //Setup the data pointers, using data pointers saves a few ms on large matrix updates
250  Float **w_p = weightsMatrix.getDataPointer();
251  Float **wT_p = wT.getDataPointer();
252  Float **vW_p = vW.getDataPointer();
253  Float **data_p = data.getDataPointer();
254  Float **v1_p = v1.getDataPointer();
255  Float **v2_p = v2.getDataPointer();
256  Float **h1_p = h1.getDataPointer();
257  Float **h2_p = h2.getDataPointer();
258  Float *vlb_p = &visibleLayerBias[0];
259  Float *hlb_p = &hiddenLayerBias[0];
260 
261  //Get the batch data
262  UINT index = 0;
263  for(i=batchIndexs[k].startIndex; i<batchIndexs[k].endIndex; i++){
264  for(j=0; j<numVisibleUnits; j++){
265  v1_p[index][j] = data_p[ indexList[i] ][j];
266  }
267  index++;
268  }
269 
270  //Copy a transposed version of the weights matrix, this is used to compute h1 and h2
271  for(i=0; i<numHiddenUnits; i++)
272  for(j=0; j<numVisibleUnits; j++)
273  wT_p[j][i] = w_p[i][j];
274 
275  //Compute h1
276  h1.multiple(v1, wT);
277  for(n=0; n<batchIndexs[k].batchSize; n++){
278  for(i=0; i<numHiddenUnits; i++){
279  h1_p[n][i] = sigmoidRandom( h1_p[n][i] + hlb_p[i] );
280  }
281  }
282 
283  //Compute v2
284  v2.multiple(h1, weightsMatrix);
285  for(n=0; n<batchIndexs[k].batchSize; n++){
286  for(i=0; i<numVisibleUnits; i++){
287  v2_p[n][i] = sigmoidRandom( v2_p[n][i] + vlb_p[i] );
288  }
289  }
290 
291  //Compute h2
292  h2.multiple(v2,wT);
293  for(n=0; n<batchIndexs[k].batchSize; n++){
294  for(i=0; i<numHiddenUnits; i++){
295  h2_p[n][i] = grt_sigmoid( h2_p[n][i] + hlb_p[i] );
296  }
297  }
298 
299  //Compute c1, c2 and the difference between v1-v2
300  c1.multiple(h1,v1,true);
301  c2.multiple(h2,v2,true);
302  vDiff.subtract(v1, v2);
303 
304  //Compute the sum of vdiff
305  for(j=0; j<numVisibleUnits; j++){
306  vDiffSum[j] = 0;
307  for(i=0; i<batchIndexs[k].batchSize; i++){
308  vDiffSum[j] += vDiff[i][j];
309  }
310  }
311 
312  //Compute the difference between h1 and h2
313  hDiff.subtract(h1, h2);
314  for(j=0; j<numHiddenUnits; j++){
315  hDiffSum[j] = 0;
316  for(i=0; i<batchIndexs[k].batchSize; i++){
317  hDiffSum[j] += hDiff[i][j];
318  }
319  }
320 
321  //Compute the difference between c1 and c2
322  cDiff.subtract(c1,c2);
323 
324  //Update the weight velocities
325  for(i=0; i<numHiddenUnits; i++){
326  for(j=0; j<numVisibleUnits; j++){
327  vW_p[i][j] = ((momentum * vW_p[i][j]) + (alpha * cDiff[i][j])) / batchIndexs[k].batchSize;
328  }
329  }
330  for(i=0; i<numVisibleUnits; i++){
331  visibleLayerBiasVelocity[i] = ((momentum * visibleLayerBiasVelocity[i]) + (alpha * vDiffSum[i])) / batchIndexs[k].batchSize;
332  }
333  for(i=0; i<numHiddenUnits; i++){
334  hiddenLayerBiasVelocity[i] = ((momentum * hiddenLayerBiasVelocity[i]) + (alpha * hDiffSum[i])) / batchIndexs[k].batchSize;
335  }
336 
337  //Update the weights
338  weightsMatrix.add( vW );
339 
340  //Update the bias for the visible layer
341  for(i=0; i<numVisibleUnits; i++){
342  visibleLayerBias[i] += visibleLayerBiasVelocity[i];
343  }
344 
345  //Update the bias for the visible layer
346  for(i=0; i<numHiddenUnits; i++){
347  hiddenLayerBias[i] += hiddenLayerBiasVelocity[i];
348  }
349 
350  //Compute the reconstruction error
351  err = 0;
352  for(i=0; i<batchIndexs[k].batchSize; i++){
353  for(j=0; j<numVisibleUnits; j++){
354  err += SQR( v1[i][j] - v2[i][j] );
355  }
356  }
357 
358  error += err / batchIndexs[k].batchSize;
359  }
360  error /= numBatches;
361  delta = lastError - error;
362  lastError = error;
363 
364  trainingLog << "Epoch: " << epoch+1 << "/" << maxNumEpochs;
365  trainingLog << " Epoch time: " << (timer.getMilliSeconds()-startTime)/1000.0 << " seconds";
366  trainingLog << " Learning rate: " << alpha;
367  trainingLog << " Momentum: " << momentum;
368  trainingLog << " Average reconstruction error: " << error;
369  trainingLog << " Delta: " << delta << std::endl;
370 
371  //Update the learning rate
372  alpha *= learningRateUpdate;
373 
374  trainingResult.setClassificationResult(epoch, error, this);
375  trainingResults.push_back(trainingResult);
376  trainingResultsObserverManager.notifyObservers( trainingResult );
377 
378  //Check for convergance
379  if( fabs(delta) < minChange ){
380  if( ++noChangeCounter >= minNumEpochs ){
381  trainingLog << "Stopping training. MinChange limit reached!" << std::endl;
382  break;
383  }
384  }else noChangeCounter = 0;
385 
386  }
387  trainingLog << "Training complete after " << epoch << " epochs. Total training time: " << timer.getMilliSeconds()/1000.0 << " seconds" << std::endl;
388 
389  trained = true;
390 
391  return true;
392 }
393 
395 
396  //Reset the base class
397  MLBase::reset();
398 
399  return true;
400 }
401 
403 
404  //Clear the base class
405  MLBase::clear();
406 
407  weightsMatrix.clear();
408  weightsMatrix.clear();
409  visibleLayerBias.clear();
410  hiddenLayerBias.clear();
411  ph_mean.clear();
412  ph_sample.clear();
413  nv_means.clear();
414  nv_samples.clear();
415  nh_means.clear();
416  nh_samples.clear();
417  outputData.clear();
418  ranges.clear();
419 
420  randomizeWeightsForTraining = true;
421 
422  return true;
423 }
424 
425 bool BernoulliRBM::saveModelToFile( std::fstream &file ) const{
426 
427  if(!file.is_open())
428  {
429  errorLog <<"saveModelToFile(fstream &file) - The file is not open!" << std::endl;
430  return false;
431  }
432 
433  //Write the header info
434  file<<"GRT_BERNOULLI_RBM_MODEL_FILE_V1.1\n";
435 
436  if( !saveBaseSettingsToFile( file ) ){
437  errorLog <<"saveModelToFile(fstream &file) - Failed to save base settings to file!" << std::endl;
438  return false;
439  }
440 
441  file << "NumVisibleUnits: " << numVisibleUnits << std::endl;
442  file << "NumHiddenUnits: " << numHiddenUnits << std::endl;
443  file << "BatchSize: " << batchSize << std::endl;
444  file << "BatchStepSize: " << batchStepSize << std::endl;
445  file << "LearningRate: " << learningRate << std::endl;
446  file << "LearningRateUpdate: " << learningRateUpdate << std::endl;
447  file << "Momentum: " << momentum << std::endl;
448  file << "RandomizeWeightsForTraining: " << randomizeWeightsForTraining << std::endl;
449 
450  file << "Ranges: \n";
451  for(UINT n=0; n<ranges.size(); n++){
452  file << ranges[n].minValue << "\t" << ranges[n].maxValue << std::endl;
453  }
454 
455  //If the model has been trained then write the model
456  if( trained ){
457  file << "WeightsMatrix: " << std::endl;
458  for(UINT i=0; i<weightsMatrix.getNumRows(); i++){
459  for(UINT j=0; j<weightsMatrix.getNumCols(); j++){
460  file << weightsMatrix[i][j];
461  if( j < weightsMatrix.getNumCols()-1 ) file << " ";
462  }
463  file << std::endl;
464  }
465 
466  file << "VisibleLayerBias: ";
467  for(unsigned int i=0; i<visibleLayerBias.size(); i++){
468  file << visibleLayerBias[i];
469  if( i < visibleLayerBias.size()-1 ) file << " ";
470  }
471  file << std::endl;
472 
473  file << "HiddenLayerBias: ";
474  for(unsigned int i=0; i<hiddenLayerBias.size(); i++){
475  file << hiddenLayerBias[i];
476  if( i < hiddenLayerBias.size()-1 ) file << " ";
477  }
478  file << std::endl;
479  }
480 
481  return true;
482 }
483 
484 bool BernoulliRBM::loadModelFromFile( std::fstream &file ){
485 
486  if(!file.is_open())
487  {
488  errorLog <<"loadModelFromFile(fstream &file) - The file is not open!" << std::endl;
489  return false;
490  }
491 
492  std::string word;
493 
494  //Read the header info
495  file >> word;
496 
497  if( word == "GRT_BERNOULLI_RBM_MODEL_FILE_V1.0" ){
498  return loadLegacyModelFromFile( file );
499  }
500 
501  if( word != "GRT_BERNOULLI_RBM_MODEL_FILE_V1.1" ){
502  errorLog <<"loadModelFromFile(fstream &file) - Failed to read file header!" << std::endl;
503  return false;
504  }
505 
506  if( !loadBaseSettingsFromFile( file ) ){
507  errorLog <<"loadModelFromFile(fstream &file) - Failed to load base settings to file!" << std::endl;
508  return false;
509  }
510 
511  //Read the number of visible units
512  file >> word;
513  if( word != "NumVisibleUnits:" ){
514  errorLog <<"loadModelFromFile(fstream &file) - Failed to read NumVisibleUnits header!" << std::endl;
515  return false;
516  }
517  file >> numVisibleUnits;
518 
519  //Read the number of hidden units
520  file >> word;
521  if( word != "NumHiddenUnits:" ){
522  errorLog <<"loadModelFromFile(fstream &file) - Failed to read NumHiddenUnits header!" << std::endl;
523  return false;
524  }
525  file >> numHiddenUnits;
526 
527  //Read the batch size
528  file >> word;
529  if( word != "BatchSize:" ){
530  errorLog <<"loadModelFromFile(fstream &file) - Failed to read BatchSize header!" << std::endl;
531  return false;
532  }
533  file >> batchSize;
534 
535  //Read the batch step size
536  file >> word;
537  if( word != "BatchStepSize:" ){
538  errorLog <<"loadModelFromFile(fstream &file) - Failed to read BatchStepSize header!" << std::endl;
539  return false;
540  }
541  file >> batchStepSize;
542 
543  //Read the learning rate
544  file >> word;
545  if( word != "LearningRate:" ){
546  errorLog <<"loadModelFromFile(fstream &file) - Failed to read LearningRate header!" << std::endl;
547  return false;
548  }
549  file >> learningRate;
550 
551  //Read the learning rate update
552  file >> word;
553  if( word != "LearningRateUpdate:" ){
554  errorLog <<"loadModelFromFile(fstream &file) - Failed to read LearningRateUpdate header!" << std::endl;
555  return false;
556  }
557  file >> learningRateUpdate;
558 
559  //Read the momentum
560  file >> word;
561  if( word != "Momentum:" ){
562  errorLog <<"loadModelFromFile(fstream &file) - Failed to read Momentum header!" << std::endl;
563  return false;
564  }
565  file >> momentum;
566 
567  //Read the randomizeWeightsForTraining
568  file >> word;
569  if( word != "RandomizeWeightsForTraining:" ){
570  errorLog <<"loadModelFromFile(fstream &file) - Failed to read RandomizeWeightsForTraining header!" << std::endl;
571  return false;
572  }
573  file >> randomizeWeightsForTraining;
574 
575  //Read the ranges
576  file >> word;
577  if( word != "Ranges:" ){
578  errorLog <<"loadModelFromFile(fstream &file) - Failed to read Ranges header!" << std::endl;
579  return false;
580  }
581  ranges.resize(numInputDimensions);
582  for(UINT n=0; n<ranges.size(); n++){
583  file >> ranges[n].minValue;
584  file >> ranges[n].maxValue;
585  }
586 
587  //If the model has been trained then load the model
588  if( trained ){
589 
590  //Load the weights matrix
591  file >> word;
592  if( word != "WeightsMatrix:" ){
593  errorLog <<"loadModelFromFile(fstream &file) - Failed to read WeightsMatrix header!" << std::endl;
594  return false;
595  }
596  weightsMatrix.resize(numHiddenUnits, numVisibleUnits);
597 
598  for(UINT i=0; i<weightsMatrix.getNumRows(); i++){
599  for(UINT j=0; j<weightsMatrix.getNumCols(); j++){
600  file >> weightsMatrix[i][j];
601  }
602  }
603 
604  //Load the VisibleLayerBias
605  file >> word;
606  if( word != "VisibleLayerBias:" ){
607  errorLog <<"loadModelFromFile(fstream &file) - Failed to read VisibleLayerBias header!" << std::endl;
608  return false;
609  }
610  visibleLayerBias.resize(numVisibleUnits);
611 
612  for(unsigned int i=0; i<visibleLayerBias.size(); i++){
613  file >> visibleLayerBias[i];
614  }
615 
616  //Load the HiddenLayerBias
617  file >> word;
618  if( word != "HiddenLayerBias:" ){
619  errorLog <<"loadModelFromFile(fstream &file) - Failed to read HiddenLayerBias header!" << std::endl;
620  return false;
621  }
622  hiddenLayerBias.resize(numHiddenUnits);
623 
624  for(unsigned int i=0; i<hiddenLayerBias.size(); i++){
625  file >> hiddenLayerBias[i];
626  }
627  }
628 
629  return true;
630 }
631 
632 bool BernoulliRBM::print() const{
633 
634  if( !trained ){
635  return false;
636  }
637 
638  std::cout << "WeightsMatrix: \n";
639  for(UINT i=0; i<numVisibleUnits; i++) {
640  for(UINT j=0; j<numHiddenUnits; j++) {
641  std::cout << weightsMatrix[j][i] << "\t";
642  }
643  std::cout << std::endl;
644  }
645  std::cout << std::endl;
646 
647  std::cout << "visible layer bias: ";
648  for(UINT j=0; j<numVisibleUnits; j++) {
649  std::cout << visibleLayerBias[j] << "\t";
650  }
651  std::cout << std::endl;
652 
653  std::cout << "hidden layer bias: ";
654  for(UINT j=0; j<numHiddenUnits; j++) {
655  std::cout << hiddenLayerBias[j] << "\t";
656  }
657  std::cout << std::endl;
658 
659  return true;
660 }
661 
662 bool BernoulliRBM::getRandomizeWeightsForTraining() const{
663  return randomizeWeightsForTraining;
664 }
665 
666 UINT BernoulliRBM::getNumVisibleUnits() const{
667  return numVisibleUnits;
668 }
669 
670 UINT BernoulliRBM::getNumHiddenUnits() const{
671  return numHiddenUnits;
672 }
673 
674 const MatrixFloat& BernoulliRBM::getWeights() const{
675  return weightsMatrix;
676 }
677 
678 VectorFloat BernoulliRBM::getOutputData()const{
679  return outputData;
680 }
681 
682 bool BernoulliRBM::setNumHiddenUnits(const UINT numHiddenUnits){
683  this->numHiddenUnits = numHiddenUnits;
684  clear();
685  return true;
686 }
687 
688 bool BernoulliRBM::setMomentum(const Float momentum){
689  this->momentum = momentum;
690  return true;
691 }
692 
693 bool BernoulliRBM::setLearningRateUpdate(const Float learningRateUpdate){
694  this->learningRateUpdate = learningRateUpdate;
695  return true;
696 }
697 
698 bool BernoulliRBM::setRandomizeWeightsForTraining(const bool randomizeWeightsForTraining){
699  this->randomizeWeightsForTraining = randomizeWeightsForTraining;
700  return true;
701 }
702 
703 bool BernoulliRBM::setBatchSize(const UINT batchSize){
704  this->batchSize = batchSize;
705  return true;
706 }
707 
708 bool BernoulliRBM::setBatchStepSize(const UINT batchStepSize){
709  this->batchStepSize = batchStepSize;
710  return true;
711 }
712 
713 bool BernoulliRBM::loadLegacyModelFromFile( std::fstream &file ){
714 
715  std::string word;
716  UINT numGibbsSteps = 0;
717 
718  if( !loadBaseSettingsFromFile( file ) ){
719  errorLog <<"loadModelFromFile(fstream &file) - Failed to load base settings to file!" << std::endl;
720  return false;
721  }
722 
723  //Read the number of visible units
724  file >> word;
725  if( word != "NumVisibleUnits:" ){
726  errorLog <<"loadModelFromFile(fstream &file) - Failed to read NumVisibleUnits header!" << std::endl;
727  return false;
728  }
729  file >> numVisibleUnits;
730 
731  //Read the number of hidden units
732  file >> word;
733  if( word != "NumHiddenUnits:" ){
734  errorLog <<"loadModelFromFile(fstream &file) - Failed to read NumHiddenUnits header!" << std::endl;
735  return false;
736  }
737  file >> numHiddenUnits;
738 
739  //Read the number of training epochs
740  file >> word;
741  if( word != "NumTrainingEpochs:" ){
742  errorLog <<"loadModelFromFile(fstream &file) - Failed to read NumTrainingEpochs header!" << std::endl;
743  return false;
744  }
745  file >> maxNumEpochs;
746 
747  //Read the number of gibbs steps
748  file >> word;
749  if( word != "NumGibbsSteps:" ){
750  errorLog <<"loadModelFromFile(fstream &file) - Failed to read NumGibbsSteps header!" << std::endl;
751  return false;
752  }
753  file >> numGibbsSteps;
754 
755  //Read the learning rate
756  file >> word;
757  if( word != "LearningRate:" ){
758  errorLog <<"loadModelFromFile(fstream &file) - Failed to read LearningRate header!" << std::endl;
759  return false;
760  }
761  file >> learningRate;
762 
763  //Read the learning rate update
764  file >> word;
765  if( word != "LearningRateUpdate:" ){
766  errorLog <<"loadModelFromFile(fstream &file) - Failed to read LearningRateUpdate header!" << std::endl;
767  return false;
768  }
769  file >> learningRateUpdate;
770 
771  //Read the momentum
772  file >> word;
773  if( word != "Momentum:" ){
774  errorLog <<"loadModelFromFile(fstream &file) - Failed to read Momentum header!" << std::endl;
775  return false;
776  }
777  file >> momentum;
778 
779  //Read the randomizeWeightsForTraining
780  file >> word;
781  if( word != "RandomizeWeightsForTraining:" ){
782  errorLog <<"loadModelFromFile(fstream &file) - Failed to read RandomizeWeightsForTraining header!" << std::endl;
783  return false;
784  }
785  file >> randomizeWeightsForTraining;
786 
787  //Read the ranges
788  file >> word;
789  if( word != "Ranges:" ){
790  errorLog <<"loadModelFromFile(fstream &file) - Failed to read Ranges header!" << std::endl;
791  return false;
792  }
793  ranges.resize(numInputDimensions);
794  for(UINT n=0; n<ranges.size(); n++){
795  file >> ranges[n].minValue;
796  file >> ranges[n].maxValue;
797  }
798 
799  //If the model has been trained then load the model
800  if( trained ){
801 
802  //Load the weights matrix
803  file >> word;
804  if( word != "WeightsMatrix:" ){
805  errorLog <<"loadModelFromFile(fstream &file) - Failed to read WeightsMatrix header!" << std::endl;
806  return false;
807  }
808  weightsMatrix.resize(numHiddenUnits, numVisibleUnits);
809 
810  for(UINT i=0; i<weightsMatrix.getNumRows(); i++){
811  for(UINT j=0; j<weightsMatrix.getNumCols(); j++){
812  file >> weightsMatrix[i][j];
813  }
814  }
815 
816  //Load the VisibleLayerBias
817  file >> word;
818  if( word != "VisibleLayerBias:" ){
819  errorLog <<"loadModelFromFile(fstream &file) - Failed to read VisibleLayerBias header!" << std::endl;
820  return false;
821  }
822  visibleLayerBias.resize(numVisibleUnits);
823 
824  for(unsigned int i=0; i<visibleLayerBias.getSize(); i++){
825  file >> visibleLayerBias[i];
826  }
827 
828  //Load the HiddenLayerBias
829  file >> word;
830  if( word != "HiddenLayerBias:" ){
831  errorLog <<"loadModelFromFile(fstream &file) - Failed to read HiddenLayerBias header!" << std::endl;
832  return false;
833  }
834  hiddenLayerBias.resize(numHiddenUnits);
835 
836  for(unsigned int i=0; i<hiddenLayerBias.getSize(); i++){
837  file >> hiddenLayerBias[i];
838  }
839  }
840 
841  return true;
842 }
843 
844 GRT_END_NAMESPACE
void clear()
Definition: Matrix.h:522
bool saveBaseSettingsToFile(std::fstream &file) const
Definition: MLBase.cpp:370
Definition: Timer.h:43
virtual bool loadModelFromFile(std::fstream &file)
virtual bool reset()
Definition: MLBase.cpp:124
bool predict_(VectorFloat &inputData)
virtual bool reset()
virtual bool resize(const unsigned int size)
Definition: Vector.h:133
This class implements a Bernoulli Restricted Boltzmann machine.
virtual bool clear()
signed long getMilliSeconds()
Definition: Timer.h:117
unsigned int getSize() const
Definition: Vector.h:193
bool setAllValues(const T &value)
Definition: Matrix.h:336
bool add(const MatrixFloat &b)
bool subtract(const MatrixFloat &b)
unsigned int getNumRows() const
Definition: Matrix.h:542
bool loadLegacyModelFromFile(std::fstream &file)
unsigned int getNumCols() const
Definition: Matrix.h:549
bool loadBaseSettingsFromFile(std::fstream &file)
Definition: MLBase.cpp:393
bool start()
Definition: Timer.h:64
T ** getDataPointer() const
Definition: Matrix.h:571
virtual bool print() const
virtual bool clear()
Definition: MLBase.cpp:126
Vector< MinMax > getRanges() const
Float getRandomNumberUniform(Float minRange=0.0, Float maxRange=1.0)
Definition: Random.h:198
virtual bool saveModelToFile(std::fstream &file) const
virtual bool train_(MatrixFloat &data)
virtual bool resize(const unsigned int r, const unsigned int c)
Definition: Matrix.h:232
Definition: Vector.h:41
MatrixFloat multiple(const Float value) const