AutoEncoderTutorial.cpp
Go to the documentation of this file.
1 #include <shark/Data/Pgm.h> //for exporting the learned filters
2 #include <shark/Data/SparseData.h>//for reading in the images as sparseData/Libsvm format
3 #include <shark/Models/LinearModel.h>//single dense layer
4 #include <shark/Models/ConcatenatedModel.h>//for stacking layers
5 #include <shark/ObjectiveFunctions/ErrorFunction.h> //the error function for minibatch training
6 #include <shark/Algorithms/GradientDescent/Adam.h>// The Adam optimization algorithm
7 #include <shark/ObjectiveFunctions/Loss/SquaredLoss.h> // squared loss used for regression
8 #include <shark/ObjectiveFunctions/Regularizer.h> //L2 regulariziation
9 
10 using namespace std;
11 using namespace shark;
12 
13 int main(int argc, char **argv)
14 {
15  if(argc < 2) {
16  cerr << "usage: " << argv[0] << " path/to/mnist_subset.libsvm" << endl;
17  return 1;
18  }
19  std::size_t hidden1 = 200;
20  std::size_t hidden2 = 100;
21  std::size_t iterations = 10000;
22  double regularisation = 0.01;
23 
25  importSparseData( data, argv[1] );
26 
27  std::size_t numElems = data.numberOfElements();
28  for(std::size_t i = 0; i != numElems; ++i){
29  for(std::size_t j = 0; j != 784; ++j){
30  if(data.element(i).input(j) > 0.5){
31  data.element(i).input(j) = 1;
32  }else{
33  data.element(i).input(j) = 0;
34  }
35  }
36  }
37  std::size_t inputs = dataDimension(data.inputs());
38 
39  //We use a dense lienar model with rectifier activations
41 
42  //build encoder network
43  DenseLayer encoder1(inputs,hidden1);
44  DenseLayer encoder2(encoder1.outputShape(),hidden2);
45  auto encoder = encoder1 >> encoder2;
46 
47  //build decoder network
48  DenseLayer decoder1(encoder2.outputShape(), encoder2.inputShape());
49  DenseLayer decoder2(encoder1.outputShape(), encoder1.inputShape());
50  auto decoder = decoder1 >> decoder2;
51 
52  //Setup autoencoder model
53  auto autoencoder = encoder >> decoder;
54  //we have not implemented the derivatives of the noise model which turns the
55  //whole composite model to be not differentiable. we fix this by not optimizing the noise model
56  autoencoder.enableModelOptimization(0,false);
57  //create the objective function as a regression problem
58  LabeledData<RealVector,RealVector> trainSet(data.inputs(),data.inputs());//labels identical to inputs
60  ErrorFunction error(trainSet, &autoencoder, &loss, true);//we enable minibatch learning
61  TwoNormRegularizer regularizer(error.numberOfVariables());
62  error.setRegularizer(regularisation,&regularizer);
63  initRandomNormal(autoencoder,0.01);
64  //set up optimizer
65  Adam optimizer;
66  error.init();
67  optimizer.init(error);
68  std::cout<<"Optimizing model "<<std::endl;
69  for(std::size_t i = 0; i != iterations; ++i){
70  optimizer.step(error);
71  if(i % 100 == 0)
72  std::cout<<i<<" "<<optimizer.solution().value<<std::endl;
73  }
74  autoencoder.setParameterVector(optimizer.solution().point);
75  exportFiltersToPGMGrid("features",encoder1.matrix(),28,28);
76 }