Powell’s Function
考虑一个略微复杂点的例子,最小化 Powell's 函数。 其中 残差项为:
则在该例子中 就是 ResidualBlock, 就是整个参数块,例如 对应的参数块为 。Cost 的计算方式为 。 拥有四个参数,拥有四个残差项,我们想要最小化 。接下来我们使用 Ceres 来解决该问题。
同样,第一步是定义评估目标函数中每个残差项的 functor。评估 的 functor 如下:
struct F4 {
template <typename T>
bool operator()(const T* const x1, const T* const x4, T* residual) const {
residual[0] = sqrt(10.0) * (x1[0] - x4[0]) * (x1[0] - x4[0]);
return true;
}
};类似的我们可以定义 F1,F2,F3 去评估 。最终构建优化问题的方式如下:
double x1 = 3.0; double x2 = -1.0; double x3 = 0.0; double x4 = 1.0;
Problem problem;
// Add residual terms to the problem using the autodiff
// wrapper to get the derivatives automatically.
problem.AddResidualBlock(
new AutoDiffCostFunction<F1, 1, 1, 1>(), nullptr, &x1, &x2);
problem.AddResidualBlock(
new AutoDiffCostFunction<F2, 1, 1, 1>(), nullptr, &x3, &x4);
problem.AddResidualBlock(
new AutoDiffCostFunction<F3, 1, 1, 1>(), nullptr, &x2, &x3);
problem.AddResidualBlock(
new AutoDiffCostFunction<F4, 1, 1, 1>(), nullptr, &x1, &x4);AutoDiffCostFunction<F1, 1, 1, 1>() 的模板参数分别代表 Cost 的计算方式,残差的维度,第一个参数的维度,第二个参数的维度。这里需要注意的是,每个 ResidualBlock 仅依赖于相应残差函数所依赖的两个参数,而不依赖于所有四个参数,例如 仅仅依赖于 。编译并运行 examples/powell.cc 可以得到如下结果:
不难看出,当目标函数值为 0 时,最优解位于 处。 经过 15 次迭代,Ceres 得到的 cost 为 。
Footnotes
Last updated