DMP_BBO library
FunctionApproximatorRRRFF.cpp
Go to the documentation of this file.
1 
24 #include <boost/serialization/export.hpp>
25 #include <boost/archive/text_iarchive.hpp>
26 #include <boost/archive/text_oarchive.hpp>
27 #include <boost/archive/xml_iarchive.hpp>
28 #include <boost/archive/xml_oarchive.hpp>
30 
33 
38 
41 
42 #include <eigen3/Eigen/LU>
43 
44 #include <boost/math/constants/constants.hpp>
45 #include <boost/random.hpp>
46 #include <boost/random/variate_generator.hpp>
47 #include <boost/random/normal_distribution.hpp>
48 #include <boost/random/uniform_real.hpp>
49 
50 #include <iostream>
51 
52 using namespace Eigen;
53 using namespace std;
54 
55 namespace DmpBbo {
56 
57 FunctionApproximatorRRRFF::FunctionApproximatorRRRFF(const MetaParametersRRRFF *const meta_parameters, const ModelParametersRRRFF *const model_parameters)
58 :
59  FunctionApproximator(meta_parameters,model_parameters)
60 {
61 }
62 
63 FunctionApproximatorRRRFF::FunctionApproximatorRRRFF(const ModelParametersRRRFF *const model_parameters)
64 :
65  FunctionApproximator(model_parameters)
66 {
67 }
68 
69 
71  // All error checking and cloning is left to the FunctionApproximator constructor.
72  return new FunctionApproximatorRRRFF(
73  dynamic_cast<const MetaParametersRRRFF*>(getMetaParameters()),
74  dynamic_cast<const ModelParametersRRRFF*>(getModelParameters())
75  );
76 };
77 
78 
79 void FunctionApproximatorRRRFF::train(const Eigen::Ref<const Eigen::MatrixXd>& inputs, const Eigen::Ref<const Eigen::MatrixXd>& targets)
80 {
81  if (isTrained())
82  {
83  cerr << "WARNING: You may not call FunctionApproximatorRRRFF::train more than once. Doing nothing." << endl;
84  cerr << " (if you really want to retrain, call reTrain function instead)" << endl;
85  return;
86  }
87 
88  assert(inputs.rows() == targets.rows()); // Must have same number of examples
89  assert(inputs.cols()==getExpectedInputDim());
90 
91  const MetaParametersRRRFF* meta_parameters_RRRFF =
92  static_cast<const MetaParametersRRRFF*>(getMetaParameters());
93 
94  int nb_cos = meta_parameters_RRRFF->number_of_basis_functions_;
95 
96  // Init random generator.
97  boost::mt19937 rng(getpid() + time(0));
98 
99  // Draw periodes
100  boost::normal_distribution<> twoGamma(0, sqrt(2 * meta_parameters_RRRFF->gamma_));
101  boost::variate_generator<boost::mt19937&, boost::normal_distribution<> > genPeriods(rng, twoGamma);
102  MatrixXd cosines_periodes(nb_cos, inputs.cols());
103  for (int r = 0; r < nb_cos; r++)
104  for (int c = 0; c < inputs.cols(); c++)
105  cosines_periodes(r, c) = genPeriods();
106 
107  // Draw phase
108  boost::uniform_real<> twoPi(0, 2 * boost::math::constants::pi<double>());
109  boost::variate_generator<boost::mt19937&, boost::uniform_real<> > genPhases(rng, twoPi);
110  VectorXd cosines_phase(nb_cos);
111  for (int r = 0; r < nb_cos; r++)
112  cosines_phase(r) = genPhases();
113 
114  MatrixXd proj_inputs;
115  BasisFunction::Cosine::activations(cosines_periodes,cosines_phase,inputs,proj_inputs);
116 
117  // Compute linear model analatically with least squares
118  double regularization = meta_parameters_RRRFF->regularization_;
119  bool use_offset = false;
120  VectorXd linear_model = leastSquares(proj_inputs,targets,use_offset,regularization);
121 
122  setModelParameters(new ModelParametersRRRFF(linear_model, cosines_periodes, cosines_phase));
123 }
124 
125 void FunctionApproximatorRRRFF::predict(const Eigen::Ref<const Eigen::MatrixXd>& inputs, Eigen::MatrixXd& outputs)
126 {
127  if (!isTrained())
128  {
129  cerr << "WARNING: You may not call FunctionApproximatorRRRFF::predict if you have not trained yet. Doing nothing." << endl;
130  return;
131  }
132 
133  const ModelParametersRRRFF* model = static_cast<const ModelParametersRRRFF*>(getModelParameters());
134 
135  MatrixXd proj_inputs;
136  model->cosineActivations(inputs,proj_inputs);
137 
138  outputs = proj_inputs * model->weights_;
139 }
140 
141 bool FunctionApproximatorRRRFF::saveGridData(const VectorXd& min, const VectorXd& max, const VectorXi& n_samples_per_dim, string save_directory, bool overwrite) const
142 {
143  if (save_directory.empty())
144  return true;
145 
146  MatrixXd inputs_grid;
147  FunctionApproximator::generateInputsGrid(min, max, n_samples_per_dim, inputs_grid);
148 
149  const ModelParametersRRRFF* model_parameters_RRRFF = static_cast<const ModelParametersRRRFF*>(getModelParameters());
150 
151  MatrixXd activations_grid;
152  model_parameters_RRRFF->cosineActivations(inputs_grid, activations_grid);
153 
154  saveMatrix(save_directory,"n_samples_per_dim.txt",n_samples_per_dim,overwrite);
155  saveMatrix(save_directory,"inputs_grid.txt",inputs_grid,overwrite);
156  saveMatrix(save_directory,"activations_grid.txt",activations_grid,overwrite);
157 
158  // Weight the basis function activations
159  VectorXd weights = model_parameters_RRRFF->weights();
160  for (int b=0; b<activations_grid.cols(); b++)
161  activations_grid.col(b).array() *= weights(b);
162  saveMatrix(save_directory,"activations_weighted_grid.txt",activations_grid,overwrite);
163 
164  // Sum over weighed basis functions
165  MatrixXd predictions_grid = activations_grid.rowwise().sum();
166  saveMatrix(save_directory,"predictions_grid.txt",predictions_grid,overwrite);
167 
168  return true;
169 
170 }
171 
172 template<class Archive>
173 void FunctionApproximatorRRRFF::serialize(Archive & ar, const unsigned int version)
174 {
175  // serialize base class information
176  ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(FunctionApproximator);
177 }
178 
179 }
Meta-parameters for the RRRFF function approximator.
MetaParametersRRRFF class header file.
Header file for input/output of Eigen matrices to ASCII files.
BOOST_CLASS_EXPORT_IMPLEMENT(DmpBbo::FunctionApproximatorRRRFF)
For boost::serialization.
Header file for various least squares functions.
const Eigen::VectorXd & weights(void) const
Return the weights of the basis functions.
virtual FunctionApproximator * clone(void) const
Return a pointer to a deep copy of the FunctionApproximator object.
static void generateInputsGrid(const Eigen::VectorXd &min, const Eigen::VectorXd &max, const Eigen::VectorXi &n_samples_per_dim, Eigen::MatrixXd &inputs_grid)
Generate a input samples that lie on a grid (much like Matlab&#39;s meshgrid) For instance, if min = [2 6], and max = [3 8], and n_samples_per_dim = [3 5] then this function first makes linearly spaces samples along each dimension, e.g.
void predict(const Eigen::Ref< const Eigen::MatrixXd > &inputs, Eigen::MatrixXd &outputs)
Query the function approximator to make a prediction.
bool saveMatrix(std::string filename, Eigen::Matrix< Scalar, RowsAtCompileTime, ColsAtCompileTime > matrix, bool overwrite=false)
Save an Eigen matrix to an ASCII file.
bool isTrained(void) const
Determine whether the function approximator has already been trained with data or not...
void train(const Eigen::Ref< const Eigen::MatrixXd > &inputs, const Eigen::Ref< const Eigen::MatrixXd > &targets)
Train the function approximator with corresponding input and target examples.
BasisFunction header file.
Base class for all function approximators.
RRRFF (Ridge Regression with Random Fourier Features) function approximatorhttps://www.ncbi.nlm.nih.gov/pmc/articles/PMC3935121/.
ModelParametersRRRFF class header file.
Model parameters for the RRRFF function approximator.
const MetaParameters * getMetaParameters(void) const
Accessor for FunctionApproximator::meta_parameters_.
const ModelParameters * getModelParameters(void) const
Accessor for FunctionApproximator::model_parameters_.
void setModelParameters(ModelParameters *model_parameters)
Accessor for FunctionApproximator::model_parameters_.
int getExpectedInputDim(void) const
The expected dimensionality of the input data.
bool saveGridData(const Eigen::VectorXd &min, const Eigen::VectorXd &max, const Eigen::VectorXi &n_samples_per_dim, std::string directory, bool overwrite=false) const
Generate a grid of inputs, and output the response of the basis functions and line segments for these...
void cosineActivations(const Eigen::Ref< const Eigen::MatrixXd > &inputs, Eigen::MatrixXd &cosine_activations) const
Get the values of the cosine basis functions for given inputs.
Header file for serialization of Eigen matrices.
FunctionApproximatorRRRFF class header file.
Eigen::MatrixXd leastSquares(const Eigen::Ref< const Eigen::MatrixXd > &inputs, const Eigen::Ref< const Eigen::MatrixXd > &targets, bool use_offset, double regularization)
(Regularized) least squares with bias