General Unconstrained Minimization
Ceres 求解器除了能求解非线性最小二乘法问题外,还能使用目标函数值和梯度求解一般无约束问题。在本章中,我们将了解如何做到这一点。
Rosenbrock’s Function
考虑尝试最小化 Rosenbrock’s function。最简单方法是定义一个模板函数来评估误差函数,然后使用 Ceres Solver 的自动微分来计算其导数。我们首先定义一个模板化的函数,然后使用 AutoDiffFirstOrderFunction 构造一个 FirstOrderFunction 接口的实例。这个对象负责计算目标函数值和梯度(如果需要)。这与 Ceres 中定义非线性最小二乘法问题时的 CostFunction类似。
// f(x,y) = (1-x)^2 + 100(y - x^2)^2;
struct Rosenbrock {
template <typename T>
bool operator()(const T* parameters, T* cost) const {
const T x = parameters[0];
const T y = parameters[1];
cost[0] = (1.0 - x) * (1.0 - x) + 100.0 * (y - x * x) * (y - x * x);
return true;
}
static ceres::FirstOrderFunction* Create() {
constexpr int kNumParameters = 2;
return new ceres::AutoDiffFirstOrderFunction<Rosenbrock, kNumParameters>();
}
};然后,只需构建一个 GradientProblem 对象并调用 Solve() 即可将其最小化。
执行该代码,使用 limited memory BFGS算法解决问题。
如果由于某种原因无法使用自动微分(例如因为需要调用外部库),那么可以使用数值微分。在这种情况下,函数的定义如下
最后,如果你更愿意手工计算导数(比如因为参数向量太大而无法自动微分)。那么就应该定义 FirstOrderFunction 的实例,它与 CostFunction 类似,适用于非线性最小二乘法问题
Footnotes
Last updated