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