iCub-main
lmlibportable.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007-2009 Arjan Gijsberts
3  * CopyPolicy: Released under the terms of the GNU GPL v2.0.
4  *
5  * Example code how to use the learningMachine library using the portable
6  * wrapper.
7  */
8 #include <iostream>
9 #include <cmath>
10 #include <stdio.h>
15 
16 #include <yarp/sig/Vector.h>
17 #include <yarp/os/Property.h>
18 #include <yarp/math/Math.h>
19 #include <yarp/math/Rand.h>
20 #include <yarp/os/SystemClock.h>
21 
22 #define MIN(a, b) ((a < b) ? a : b)
23 
24 #define NO_TRAIN 4000
25 #define NO_TEST 8000
26 #define NOISE_MIN -0.05
27 #define NOISE_MAX 0.05
28 
29 
30 using namespace iCub::learningmachine;
31 using namespace yarp::os;
32 using namespace yarp::sig;
33 using namespace yarp::math;
34 
35 // taken from LWPR example code
36 double cross(double x1, double x2) {
37  x1 *= x1;
38  x2 *= x2;
39  double a = std::exp(-10 * x1);
40  double b = std::exp(-50 * x2);
41  double c = 1.25 * std::exp(-5 * (x1 + x2));
42  return (a > b) ? ((a > c) ? a : c) : ((b > c) ? b : c);
43 }
44 
45 double sin2d(double x1, double x2) {
46  return std::sin(x1 + x2);
47 }
48 
49 void elementProd(const Vector& v1, Vector& v2) {
50  for(size_t i = 0; i < MIN(v1.size(), v2.size()); i++) {
51  v2[i] = v1[i] * v2[i];
52  }
53 }
54 
55 Vector elementDiv(const Vector& v, double d) {
56  Vector ret(v.size());
57  for(size_t i = 0; i < v.size(); i++) {
58  ret[i] = (d == 0.) ? v[i] : v[i] / d;
59  }
60  return ret;
61 }
62 
63 
64 std::pair<Vector, Vector> createSample() {
65  std::pair<Vector, Vector> sample;
66  sample.first.resize(2);
67  sample.second.resize(2);
68  sample.first[0] = Rand::scalar(-1, +1);
69  sample.first[1] = Rand::scalar(-1, +1);
70  sample.second[0] = sin2d(sample.first[0], sample.first[1]);
71  sample.second[1] = cross(sample.first[0], sample.first[1]);
72  return sample;
73 }
74 
75 /*
76  * This example shows how LearningMachine classes can be used in a indirect
77  * manner in your code. In this context, this means that the YARP configuration
78  * mechanism is used and instances are of the abstract base type. This
79  * facilitates easy migration to other learning methods. Please see all
80  * direct/indirect/portable examples to have an idea which method suits your
81  * application best.
82  *
83  * Please keep in mind that the purpose is to demonstrate how to interface with
84  * the learningMachine library. The synthetic data used in this example is
85  * utterly useless.
86  */
87 
88 int main(int argc, char** argv) {
89  int nrf = 250;
90  Vector trainMSE(2);
91  Vector testMSE(2);
92  Vector noise_min(2);
93  Vector noise_max(2);
94  // train + test time for transformer and machine
95  double tic;
96  double trtrtime = 0.0;
97  double trtetime = 0.0;
98  double mctrtime = 0.0;
99  double mctetime = 0.0;
100 
101  if(argc > 1) sscanf(argv[1], "%d", &nrf);
102 
103  // initialize catalogue of machine factory
105  // initialize catalogue of transformers
107 
108  std::cout << "LearningMachine library example (portable)" << std::endl;
109 
110  // create Regularized Least Squares learner
111  std::string name("RLS");
112  MachinePortable mp = MachinePortable("RLS");
113  Property p;
114  p.put("dom", Value(nrf));
115  p.put("cod", Value(2));
116  p.put("lambda", Value(0.5));
117  mp.getWrapped().configure(p);
118  std::cout << "Learner:" << std::endl << mp.getWrapped().getInfo() << std::endl;
119 
120  // create Random Feature transformer
121  TransformerPortable tp = TransformerPortable("RandomFeature");
122  p.clear();
123  p.put("dom", Value(2));
124  p.put("cod", Value(nrf));
125  p.put("gamma", Value(16.0));
126  tp.getWrapped().configure(p);
127  std::cout << "Transformer:" << std::endl << tp.getWrapped().getInfo() << std::endl;
128 
129 
130  // create and feed training samples
131  noise_min = NOISE_MIN;
132  noise_max = NOISE_MAX;
133 
134 
135  trainMSE = 0.0;
136  for(int i = 0; i < NO_TRAIN; i++) {
137  // create a new training sample
138  std::pair<Vector, Vector> sample = createSample();
139 
140  // add some noise to output for training
141  Vector noisyOutput = sample.second + Rand::vector(noise_min, noise_max);
142 
143  // transform input using RF
144  tic = yarp::os::SystemClock::nowSystem();
145  Vector transInput = tp.getWrapped().transform(sample.first);
146  trtrtime += (yarp::os::SystemClock::nowSystem() - tic);
147 
148  // make prediction before feeding full sample
149  tic = yarp::os::SystemClock::nowSystem();
150  Prediction prediction = mp.getWrapped().predict(transInput);
151 
152  // train on complete sample with noisy output
153  mp.getWrapped().feedSample(transInput, noisyOutput);
154  mctrtime += (yarp::os::SystemClock::nowSystem() - tic);
155 
156  Vector diff = prediction.getPrediction() - sample.second;
157  elementProd(diff, diff);
158  trainMSE = trainMSE + diff;
159  }
160  trainMSE = elementDiv(trainMSE, NO_TRAIN);
161  std::cout << "Train MSE: " << trainMSE.toString() << std::endl;
162  std::cout << "Train Transformer Time per Sample: " << (trtrtime / NO_TRAIN) << std::endl;
163  std::cout << "Train Machine Time per Sample: " << (mctrtime / NO_TRAIN) << std::endl;
164  std::cout << "Combined Time per Sample: " << ((trtrtime + mctrtime) / NO_TRAIN) << std::endl;
165 
166  std::cout << std::endl;
167  std::cout << "Saving machine portable to file 'mp.txt'...";
168  bool ok = mp.writeToFile("mp.txt");
169  std::cout << ((ok) ? "ok!" : "failed :(") << std::endl;
170 
171  std::cout << "Saving transformer portable to file 'tp.txt'...";
172  ok = tp.writeToFile("tp.txt");
173  std::cout << ((ok) ? "ok!" : "failed :(") << std::endl;
174 
175  std::cout << "Loading machine portable from file 'mp.txt'...";
176  ok = mp.readFromFile("mp.txt");
177  std::cout << ((ok) ? "ok!" : "failed :(") << std::endl;
178 
179  std::cout << "Loading transformer portable from file 'tp.txt'...";
180  ok = tp.readFromFile("tp.txt");
181  std::cout << ((ok) ? "ok!" : "failed :(") << std::endl;
182  std::cout << std::endl;
183 
184  // predict test samples
185  testMSE = 0.;
186  for(int i = 0; i < NO_TEST; i++) {
187  // create a new testing sample
188  std::pair<Vector, Vector> sample = createSample();
189 
190  // transform input using RF
191  tic = yarp::os::SystemClock::nowSystem();
192  Vector transInput = tp.getWrapped().transform(sample.first);
193  trtetime += (yarp::os::SystemClock::nowSystem() - tic);
194 
195  // make prediction
196  tic = yarp::os::SystemClock::nowSystem();
197  Prediction prediction = mp.getWrapped().predict(transInput);
198  mctetime += (yarp::os::SystemClock::nowSystem() - tic);
199  Vector diff = prediction.getPrediction() - sample.second;
200  elementProd(diff, diff);
201  //std::cout << "Sample: " << sample.input <<
202  testMSE = testMSE + diff;
203  }
204  testMSE = elementDiv(testMSE, NO_TEST);
205  std::cout << "Test MSE: " << testMSE.toString() << std::endl;
206  std::cout << "Test Transformer Time per Sample: " << (trtetime / NO_TEST) << std::endl;
207  std::cout << "Test Machine Time per Sample: " << (mctetime / NO_TEST) << std::endl;
208  std::cout << "Combined Time per Sample: " << ((trtetime + mctetime) / NO_TEST) << std::endl;
209 
210  return 0;
211 }
212 
213 
virtual bool configure(yarp::os::Searchable &config)
Change parameters.
virtual Prediction predict(const yarp::sig::Vector &input)=0
Ask the learning machine to predict the output for a given input.
virtual std::string getInfo()
Asks the learning machine to return a string containing information on its operation so far.
virtual void feedSample(const yarp::sig::Vector &input, const yarp::sig::Vector &output)=0
Provide the learning machine with an example of the desired mapping.
virtual bool configure(yarp::os::Searchable &config)
Definition: ITransformer.h:168
virtual yarp::sig::Vector transform(const yarp::sig::Vector &input)
Transforms an input vector.
Definition: ITransformer.h:104
virtual std::string getInfo()
Asks the transformer to return a string containing statistics on its operation so far.
Definition: ITransformer.h:115
T & getWrapped() const
The accessor for the wrapped object.
Definition: PortableT.h:215
bool writeToFile(std::string filename)
Writes a wrapped object to a file.
Definition: PortableT.h:161
bool readFromFile(std::string filename)
Reads a wrapped object from a file.
Definition: PortableT.h:182
A class that represents a prediction result.
Definition: Prediction.h:44
yarp::sig::Vector getPrediction()
Accessor for the expected value of the prediction.
Definition: Prediction.h:106
exp(-x3 *T)]
PortableT< IMachineLearner > MachinePortable
A portable wrapper around an IMachineLearner.
PortableT< ITransformer > TransformerPortable
A portable wrapper around an ITransformer.
#define NO_TEST
#define MIN(a, b)
int main(int argc, char **argv)
#define NOISE_MAX
double cross(double x1, double x2)
Vector elementDiv(const Vector &v, double d)
std::pair< Vector, Vector > createSample()
#define NOISE_MIN
void elementProd(const Vector &v1, Vector &v2)
double sin2d(double x1, double x2)
#define NO_TRAIN