21 #include <yarp/math/Math.h>
22 #include <yarp/math/Rand.h>
27 #include <IpIpoptApplication.hpp>
29 #define CAST_IPOPTAPP(x) (static_cast<Ipopt::IpoptApplication*>(x))
32 using namespace yarp::os;
33 using namespace yarp::sig;
34 using namespace yarp::math;
42 namespace optimization
58 const deque<Vector> &
in;
59 const deque<Vector> &
out;
67 if (Bottle *b=bounds.find(tag).asList())
71 min=b->get(0).asFloat64();
72 max=b->get(1).asFloat64();
84 for (
size_t i=0; i<IW.size(); i++)
85 for (
size_t j=0; j<IW.front().length(); j++, k++)
88 for (
size_t i=0; i<LW.size(); i++)
89 for (
size_t j=0; j<LW.front().length(); j++, k++)
92 for (
size_t i=0; i<b1.length(); i++, k++)
95 for (
size_t i=0; i<b2.length(); i++, k++)
100 void fillVar(Ipopt::Number *
x,
const Ipopt::Number *x_l,
const Ipopt::Number *x_u)
103 for (
size_t i=0; i<IW.size(); i++)
104 for (
size_t j=0; j<IW.front().length(); j++, k++)
107 for (
size_t i=0; i<LW.size(); i++)
108 for (
size_t j=0; j<LW.front().length(); j++, k++)
111 for (
size_t i=0; i<b1.length(); i++, k++)
114 for (
size_t i=0; i<b2.length(); i++, k++)
121 const bool _randomInit,
const deque<Vector> &_in,
122 const deque<Vector> &_out, deque<Vector> &_pred) :
123 net(_net), bounds(_bounds), randomInit(_randomInit),
124 in(_in),
out(_out), pred(_pred),
125 IW(_net.get_IW()), LW(_net.get_LW()),
126 b1(_net.get_b1()), b2(_net.get_b2())
139 bool get_nlp_info(Ipopt::Index &
n, Ipopt::Index &m, Ipopt::Index &nnz_jac_g,
140 Ipopt::Index &nnz_h_lag, IndexStyleEnum &index_style)
142 n=IW.size()*IW.front().length()+LW.size()*LW.front().length()+b1.length()+b2.length();
143 m=nnz_jac_g=nnz_h_lag=0;
144 index_style=TNLP::C_STYLE;
151 Ipopt::Index m, Ipopt::Number *g_l, Ipopt::Number *g_u)
153 double min_IW,max_IW; getBounds(
"IW",min_IW,max_IW);
154 double min_LW,max_LW; getBounds(
"LW",min_LW,max_LW);
155 double min_b1,max_b1; getBounds(
"b1",min_b1,max_b1);
156 double min_b2,max_b2; getBounds(
"b2",min_b2,max_b2);
159 for (
size_t i=0; i<IW.size(); i++)
161 for (
size_t j=0; j<IW.front().length(); j++, k++)
168 for (
size_t i=0; i<LW.size(); i++)
170 for (
size_t j=0; j<LW.front().length(); j++, k++)
177 for (
size_t i=0; i<b1.size(); i++, k++)
183 for (
size_t i=0; i<b2.size(); i++, k++)
194 bool init_z, Ipopt::Number *z_L, Ipopt::Number *z_U,
195 Ipopt::Index m,
bool init_lambda, Ipopt::Number *lambda)
197 Ipopt::Number *x_l=
new Ipopt::Number[
n];
198 Ipopt::Number *x_u=
new Ipopt::Number[
n];
199 Ipopt::Number *g_l=
new Ipopt::Number[
n];
200 Ipopt::Number *g_u=
new Ipopt::Number[
n];
202 get_bounds_info(
n,x_l,x_u,m,g_l,g_u);
206 for (Ipopt::Index i=0; i<
n; i++)
207 x[i]=Rand::scalar(x_l[i],x_u[i]);
221 bool eval_f(Ipopt::Index
n,
const Ipopt::Number *
x,
bool new_x,
222 Ipopt::Number &obj_value)
227 for (
size_t i=0; i<in.size(); i++)
229 Vector pred=net.
predict(in[i]);
233 obj_value/=in.size();
239 Ipopt::Number *grad_f)
245 bool eval_g(Ipopt::Index
n,
const Ipopt::Number *
x,
bool new_x,
246 Ipopt::Index m, Ipopt::Number *g)
253 Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index *iRow,
254 Ipopt::Index *jCol, Ipopt::Number *values)
260 bool eval_h(Ipopt::Index
n,
const Ipopt::Number *
x,
bool new_x,
261 Ipopt::Number obj_factor, Ipopt::Index m,
const Ipopt::Number *lambda,
262 bool new_lambda, Ipopt::Index nele_hess, Ipopt::Index *iRow,
263 Ipopt::Index *jCol, Ipopt::Number *values)
270 const Ipopt::Number *
x,
const Ipopt::Number *z_L,
271 const Ipopt::Number *z_U, Ipopt::Index m,
272 const Ipopt::Number *g,
const Ipopt::Number *lambda,
273 Ipopt::Number obj_value,
const Ipopt::IpoptData *ip_data,
274 Ipopt::IpoptCalculatedQuantities *ip_cq)
278 for (
size_t i=0; i<in.size(); i++)
280 Vector pred=net.
predict(in[i]);
282 this->pred.push_back(pred);
294 ff2LayNNTrain::ff2LayNNTrain()
296 App=
new Ipopt::IpoptApplication();
298 CAST_IPOPTAPP(App)->Options()->SetIntegerValue(
"acceptable_iter",0);
299 CAST_IPOPTAPP(App)->Options()->SetStringValue(
"mu_strategy",
"adaptive");
300 CAST_IPOPTAPP(App)->Options()->SetIntegerValue(
"max_iter",300);
301 CAST_IPOPTAPP(App)->Options()->SetStringValue(
"nlp_scaling_method",
"gradient-based");
302 CAST_IPOPTAPP(App)->Options()->SetStringValue(
"hessian_approximation",
"limited-memory");
303 CAST_IPOPTAPP(App)->Options()->SetStringValue(
"jacobian_approximation",
"finite-difference-values");
304 CAST_IPOPTAPP(App)->Options()->SetIntegerValue(
"print_level",0);
305 CAST_IPOPTAPP(App)->Options()->SetStringValue(
"derivative_test",
"none");
311 void ff2LayNNTrain::setBounds(
const Property &bounds)
318 bool ff2LayNNTrain::train(
const unsigned int numHiddenNodes,
319 const deque<Vector> &in,
const deque<Vector> &
out,
320 deque<Vector> &pred,
double &
error)
322 if ((in.size()==0) || (in.size()!=
out.size()))
326 IW.assign(numHiddenNodes,Vector(in.front().length(),0.0));
327 b1.resize(numHiddenNodes,0.0);
330 LW.assign(
out.front().length(),Vector(numHiddenNodes,0.0));
331 b2.resize(
out.front().length(),0.0);
340 const Vector &in_front=in.front();
341 for (
size_t i=0; i<in_front.length(); i++)
344 range.
min=range.
max=in_front[i];
345 inMinMaxX.push_back(range);
346 range.
min=-1.0; range.
max=1.0;
347 inMinMaxY.push_back(range);
349 for (
size_t i=1; i<in.size(); i++)
351 for (
size_t j=0; j<in_front.length(); j++)
353 inMinMaxX[j].min=
std::min(inMinMaxX[j].
min,in[i][j]);
354 inMinMaxX[j].max=
std::max(inMinMaxX[j].
max,in[i][j]);
359 for (
size_t i=0; i<inMinMaxX.size(); i++)
361 inMinMaxX[i].min-=0.1*fabs(inMinMaxX[i].
min);
362 inMinMaxX[i].max+=0.1*fabs(inMinMaxX[i].
max);
366 const Vector &out_front=
out.front();
367 for (
size_t i=0; i<out_front.length(); i++)
370 range.
min=range.
max=out_front[i];
371 outMinMaxX.push_back(range);
372 range.
min=-1.0; range.
max=1.0;
373 outMinMaxY.push_back(range);
375 for (
size_t i=1; i<
out.size(); i++)
377 for (
size_t j=0; j<out_front.length(); j++)
385 for (
size_t i=0; i<outMinMaxX.size(); i++)
387 outMinMaxX[i].min-=0.1*fabs(outMinMaxX[i].
min);
388 outMinMaxX[i].max+=0.1*fabs(outMinMaxX[i].
max);
395 Ipopt::ApplicationReturnStatus status=
CAST_IPOPTAPP(App)->OptimizeTNLP(GetRawPtr(nlp));
397 error=nlp->get_error();
398 return (status==Ipopt::Solve_Succeeded);
403 bool ff2LayNNTrain::retrain(
const deque<Vector> &in,
const deque<Vector> &
out,
404 deque<Vector> &pred,
double &
error)
406 if ((in.size()==0) || (in.size()!=
out.size()) || !configured)
409 Ipopt::SmartPtr<ff2LayNNTrainNLP> nlp=
new ff2LayNNTrainNLP(*
this,bounds,
false,in,
out,pred);
410 Ipopt::ApplicationReturnStatus status=
CAST_IPOPTAPP(App)->OptimizeTNLP(GetRawPtr(nlp));
412 error=nlp->get_error();
413 return (status==Ipopt::Solve_Succeeded);
418 ff2LayNNTrain::~ff2LayNNTrain()
virtual yarp::sig::Vector predict(const yarp::sig::Vector &x) const
Predict the output given a certain input to the network.
const deque< Vector > & in
virtual double get_error() const
bool eval_g(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Index m, Ipopt::Number *g)
bool getBounds(const string &tag, double &min, double &max)
bool get_nlp_info(Ipopt::Index &n, Ipopt::Index &m, Ipopt::Index &nnz_jac_g, Ipopt::Index &nnz_h_lag, IndexStyleEnum &index_style)
bool get_bounds_info(Ipopt::Index n, Ipopt::Number *x_l, Ipopt::Number *x_u, Ipopt::Index m, Ipopt::Number *g_l, Ipopt::Number *g_u)
ff2LayNNTrainNLP(ff2LayNNTrain &_net, const Property &_bounds, const bool _randomInit, const deque< Vector > &_in, const deque< Vector > &_out, deque< Vector > &_pred)
void finalize_solution(Ipopt::SolverReturn status, Ipopt::Index n, const Ipopt::Number *x, const Ipopt::Number *z_L, const Ipopt::Number *z_U, Ipopt::Index m, const Ipopt::Number *g, const Ipopt::Number *lambda, Ipopt::Number obj_value, const Ipopt::IpoptData *ip_data, Ipopt::IpoptCalculatedQuantities *ip_cq)
bool eval_h(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Number obj_factor, Ipopt::Index m, const Ipopt::Number *lambda, bool new_lambda, Ipopt::Index nele_hess, Ipopt::Index *iRow, Ipopt::Index *jCol, Ipopt::Number *values)
void fillVar(Ipopt::Number *x, const Ipopt::Number *x_l, const Ipopt::Number *x_u)
const deque< Vector > & out
bool eval_jac_g(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index *iRow, Ipopt::Index *jCol, Ipopt::Number *values)
bool eval_f(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Number &obj_value)
bool get_starting_point(Ipopt::Index n, bool init_x, Ipopt::Number *x, bool init_z, Ipopt::Number *z_L, Ipopt::Number *z_U, Ipopt::Index m, bool init_lambda, Ipopt::Number *lambda)
bool eval_grad_f(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Number *grad_f)
void fillNet(const Ipopt::Number *x)
Class to deal with training of Feed-Forward 2 layers Neural Network using IpOpt.
double norm2(const yarp::sig::Matrix &M, int col)
Returns the squared norm of the vector given in the form: matrix(:,col).
This file contains the definition of unique IDs for the body parts and the skin parts of the robot.