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