TWo default param sets

release/4.3a0
Frank Dellaert 2015-06-18 09:51:22 -07:00
parent 9f209e441f
commit 879e66a63a
2 changed files with 85 additions and 74 deletions

View File

@ -52,76 +52,84 @@ public:
double lambdaLowerBound; ///< The minimum lambda used in LM (default: 0) double lambdaLowerBound; ///< The minimum lambda used in LM (default: 0)
VerbosityLM verbosityLM; ///< The verbosity level for Levenberg-Marquardt (default: SILENT), see also NonlinearOptimizerParams::verbosity VerbosityLM verbosityLM; ///< The verbosity level for Levenberg-Marquardt (default: SILENT), see also NonlinearOptimizerParams::verbosity
double minModelFidelity; ///< Lower bound for the modelFidelity to accept the result of an LM iteration double minModelFidelity; ///< Lower bound for the modelFidelity to accept the result of an LM iteration
std::string logFile; ///< an optional CSV log file, with [iteration, time, error, labda] std::string logFile; ///< an optional CSV log file, with [iteration, time, error, lambda]
bool diagonalDamping; ///< if true, use diagonal of Hessian bool diagonalDamping; ///< if true, use diagonal of Hessian
bool useFixedLambdaFactor; ///< if true applies constant increase (or decrease) to lambda according to lambdaFactor bool useFixedLambdaFactor; ///< if true applies constant increase (or decrease) to lambda according to lambdaFactor
double minDiagonal; ///< when using diagonal damping saturates the minimum diagonal entries (default: 1e-6) double minDiagonal; ///< when using diagonal damping saturates the minimum diagonal entries (default: 1e-6)
double maxDiagonal; ///< when using diagonal damping saturates the maximum diagonal entries (default: 1e32) double maxDiagonal; ///< when using diagonal damping saturates the maximum diagonal entries (default: 1e32)
LevenbergMarquardtParams() LevenbergMarquardtParams()
: lambdaInitial(1e-5), : verbosityLM(SILENT),
lambdaFactor(10.0),
lambdaUpperBound(1e5),
lambdaLowerBound(0.0),
verbosityLM(SILENT),
minModelFidelity(1e-3),
diagonalDamping(false), diagonalDamping(false),
useFixedLambdaFactor(true),
minDiagonal(1e-6), minDiagonal(1e-6),
maxDiagonal(1e32) {} maxDiagonal(1e32) {
SetLegacyDefaults(this);
}
static void SetLegacyDefaults(LevenbergMarquardtParams* p) {
// Relevant NonlinearOptimizerParams:
p->maxIterations = 100;
p->relativeErrorTol = 1e-5;
p->absoluteErrorTol = 1e-5;
// LM-specific:
p->lambdaInitial = 1e-5;
p->lambdaFactor = 10.0;
p->lambdaUpperBound = 1e5;
p->lambdaLowerBound = 0.0;
p->minModelFidelity = 1e-3;
p->diagonalDamping = false;
p->useFixedLambdaFactor = true;
}
// these do seem to work better for SFM
static void SetCeresDefaults(LevenbergMarquardtParams* p) {
// Relevant NonlinearOptimizerParams:
p->maxIterations = 50;
p->absoluteErrorTol = 0; // No corresponding option in CERES
p->relativeErrorTol = 1e-6; // This is function_tolerance
// LM-specific:
p->lambdaUpperBound = 1e32;
p->lambdaLowerBound = 1e-16;
p->lambdaInitial = 1e-04;
p->lambdaFactor = 2.0;
p->minModelFidelity = 1e-3; // options.min_relative_decrease in CERES
p->diagonalDamping = true;
p->useFixedLambdaFactor = false; // This is important
}
static LevenbergMarquardtParams LegacyDefaults() {
LevenbergMarquardtParams p;
SetLegacyDefaults(&p);
return p;
}
static LevenbergMarquardtParams CeresDefaults() { static LevenbergMarquardtParams CeresDefaults() {
LevenbergMarquardtParams p; LevenbergMarquardtParams p;
SetCeresDefaults(&p);
// Termination condition, same as options.max_num_iterations
p.maxIterations = 50;
// Termination condition, turn off because no corresponding option in CERES
p.absoluteErrorTol = 0; // Frank thinks this is not tolerance (was 1e-6)
// Termination condition, turn off because no corresponding option in CERES
p.errorTol = 0; // 1e-6;
// Termination condition, same as options.function_tolerance
p.relativeErrorTol = 1e-6; // This is function_tolerance (was 1e-03)
// Change lambda parameters to be the same as Ceres
p.lambdaUpperBound = 1e32;
p.lambdaLowerBound = 1e-16;
p.lambdaInitial = 1e-04;
p.lambdaFactor = 2.0;
p.useFixedLambdaFactor = false; // Luca says this is important
p.diagonalDamping = true;
p.minModelFidelity = 1e-3; // options.min_relative_decrease in CERES
return p; return p;
} }
virtual ~LevenbergMarquardtParams() {} virtual ~LevenbergMarquardtParams() {}
virtual void print(const std::string& str = "") const; virtual void print(const std::string& str = "") const;
inline double getlambdaInitial() const { return lambdaInitial; } std::string getVerbosityLM() const { return verbosityLMTranslator(verbosityLM);}
inline double getlambdaFactor() const { return lambdaFactor; } void setVerbosityLM(const std::string& s) { verbosityLM = verbosityLMTranslator(s);}
inline double getlambdaUpperBound() const { return lambdaUpperBound; }
inline double getlambdaLowerBound() const { return lambdaLowerBound; }
inline std::string getVerbosityLM() const {
return verbosityLMTranslator(verbosityLM);
}
inline std::string getLogFile() const { return logFile; }
inline bool getDiagonalDamping() const { return diagonalDamping; }
inline void setlambdaInitial(double value) { lambdaInitial = value; } // @deprecated (just use fields)
inline void setlambdaFactor(double value) { lambdaFactor = value; } #ifdef GTSAM_ALLOW_DEPRECATED
inline void setlambdaUpperBound(double value) { lambdaUpperBound = value; } bool getDiagonalDamping() const { return diagonalDamping; }
inline void setlambdaLowerBound(double value) { lambdaLowerBound = value; } double getlambdaFactor() const { return lambdaFactor; }
inline void setVerbosityLM(const std::string& s) { double getlambdaInitial() const { return lambdaInitial; }
verbosityLM = verbosityLMTranslator(s); double getlambdaLowerBound() const { return lambdaLowerBound; }
} double getlambdaUpperBound() const { return lambdaUpperBound; }
inline void setLogFile(const std::string& s) { logFile = s; } std::string getLogFile() const { return logFile; }
inline void setDiagonalDamping(bool flag) { diagonalDamping = flag; } void setDiagonalDamping(bool flag) { diagonalDamping = flag; }
inline void setUseFixedLambdaFactor(bool flag) { void setlambdaFactor(double value) { lambdaFactor = value; }
useFixedLambdaFactor = flag; void setlambdaInitial(double value) { lambdaInitial = value; }
} void setlambdaLowerBound(double value) { lambdaLowerBound = value; }
void setlambdaUpperBound(double value) { lambdaUpperBound = value; }
void setLogFile(const std::string& s) { logFile = s; }
void setUseFixedLambdaFactor(bool flag) { useFixedLambdaFactor = flag;}
#endif
}; };
/** /**
@ -180,12 +188,12 @@ public:
* @param initialValues The initial variable assignments * @param initialValues The initial variable assignments
* @param params The optimization parameters * @param params The optimization parameters
*/ */
LevenbergMarquardtOptimizer(const NonlinearFactorGraph& graph, LevenbergMarquardtOptimizer(
const Values& initialValues, const LevenbergMarquardtParams& params = const NonlinearFactorGraph& graph, const Values& initialValues,
LevenbergMarquardtParams()) : const LevenbergMarquardtParams& params = LevenbergMarquardtParams())
NonlinearOptimizer(graph), params_(ensureHasOrdering(params, graph)), state_( : NonlinearOptimizer(graph),
graph, initialValues, params_) { params_(ensureHasOrdering(params, graph)),
} state_(graph, initialValues, params_) {}
/** Standard constructor, requires a nonlinear factor graph, initial /** Standard constructor, requires a nonlinear factor graph, initial
* variable assignments, and optimization parameters. For convenience this * variable assignments, and optimization parameters. For convenience this
@ -194,9 +202,11 @@ public:
* @param graph The nonlinear factor graph to optimize * @param graph The nonlinear factor graph to optimize
* @param initialValues The initial variable assignments * @param initialValues The initial variable assignments
*/ */
LevenbergMarquardtOptimizer(const NonlinearFactorGraph& graph, LevenbergMarquardtOptimizer(
const Values& initialValues, const Ordering& ordering) : const NonlinearFactorGraph& graph, const Values& initialValues,
NonlinearOptimizer(graph) { const Ordering& ordering,
const LevenbergMarquardtParams& params = LevenbergMarquardtParams())
: NonlinearOptimizer(graph), params_(params) {
params_.ordering = ordering; params_.ordering = ordering;
state_ = LevenbergMarquardtState(graph, initialValues, params_); state_ = LevenbergMarquardtState(graph, initialValues, params_);
} }

View File

@ -187,7 +187,9 @@ TEST( NonlinearOptimizer, Factorization )
ordering.push_back(X(1)); ordering.push_back(X(1));
ordering.push_back(X(2)); ordering.push_back(X(2));
LevenbergMarquardtOptimizer optimizer(graph, config, ordering); LevenbergMarquardtParams params;
LevenbergMarquardtParams::SetLegacyDefaults(&params);
LevenbergMarquardtOptimizer optimizer(graph, config, ordering, params);
optimizer.iterate(); optimizer.iterate();
Values expected; Values expected;
@ -260,13 +262,13 @@ TEST_UNSAFE(NonlinearOptimizer, MoreOptimization) {
expectedGradient.insert(2,zero(3)); expectedGradient.insert(2,zero(3));
// Try LM and Dogleg // Try LM and Dogleg
LevenbergMarquardtParams params; LevenbergMarquardtParams params = LevenbergMarquardtParams::LegacyDefaults();
// params.setVerbosityLM("TRYDELTA"); // params.setVerbosityLM("TRYDELTA");
// params.setVerbosity("TERMINATION"); // params.setVerbosity("TERMINATION");
params.setlambdaUpperBound(1e9); params.lambdaUpperBound = 1e9;
// params.setRelativeErrorTol(0); // params.relativeErrorTol = 0;
// params.setAbsoluteErrorTol(0); // params.absoluteErrorTol = 0;
//params.setlambdaInitial(10); //params.lambdaInitial = 10;
{ {
LevenbergMarquardtOptimizer optimizer(fg, init, params); LevenbergMarquardtOptimizer optimizer(fg, init, params);
@ -290,7 +292,7 @@ TEST_UNSAFE(NonlinearOptimizer, MoreOptimization) {
initBetter.insert(2, Pose2(11,7,M_PI/2)); initBetter.insert(2, Pose2(11,7,M_PI/2));
{ {
params.setDiagonalDamping(true); params.diagonalDamping = true;
LevenbergMarquardtOptimizer optimizer(fg, initBetter, params); LevenbergMarquardtOptimizer optimizer(fg, initBetter, params);
// test the diagonal // test the diagonal
@ -399,7 +401,7 @@ public:
/// Constructor /// Constructor
IterativeLM(const NonlinearFactorGraph& graph, const Values& initialValues, IterativeLM(const NonlinearFactorGraph& graph, const Values& initialValues,
const ConjugateGradientParameters &p, const ConjugateGradientParameters &p,
const LevenbergMarquardtParams& params = LevenbergMarquardtParams()) : const LevenbergMarquardtParams& params = LevenbergMarquardtParams::LegacyDefaults()) :
LevenbergMarquardtOptimizer(graph, initialValues, params), cgParams_(p) { LevenbergMarquardtOptimizer(graph, initialValues, params), cgParams_(p) {
} }
@ -446,8 +448,7 @@ TEST( NonlinearOptimizer, logfile )
// Levenberg-Marquardt // Levenberg-Marquardt
LevenbergMarquardtParams lmParams; LevenbergMarquardtParams lmParams;
static const string filename("testNonlinearOptimizer.log"); static const string filename("testNonlinearOptimizer.log");
lmParams.setLogFile(filename); lmParams.logFile = filename;
CHECK(lmParams.getLogFile()==filename);
LevenbergMarquardtOptimizer(fg, c0, lmParams).optimize(); LevenbergMarquardtOptimizer(fg, c0, lmParams).optimize();
// stringstream expected,actual; // stringstream expected,actual;