到目前为止,我们看到的例子都是没有数据的简单优化问题。最小二乘法和非线性最小二乘法的最初目的是对数据进行曲线拟合。我们使用曲线方程 y=e0.3x+0.1 来生成样本数据,并且对每个样本都添加一个标准差为 σ=0.2 的高斯噪声,我们来拟合如下曲线方程:
其中 m,c 使我们要通过样本进行估计的参数。和前面一样,第一步仍然是定义一个模板函数去评估每一个参数块的残差,这里有多少个样本就有多少个残差项,但是每个残差项的 Cost 计算方式和 ParameterBlock 的维度都是一样的。
struct ExponentialResidual {
ExponentialResidual(double x, double y)
: x_(x), y_(y) {}
template <typename T>
bool operator()(const T* const m, const T* const c, T* residual) const {
residual[0] = y_ - exp(m[0] * x_ + c[0]);
return true;
}
private:
// Observations for a sample.
const double x_;
const double y_;
};
假定观测数据存放在一个 2n 大小的数组中,我们称为 data。然后进行优化问题的构造,就是为每个观测创建一个 CostFunction。
double m = 0.0;
double c = 0.0;
Problem problem;
for (int i = 0; i < kNumObservations; ++i) {
CostFunction* cost_function =
new AutoDiffCostFunction<ExponentialResidual, 1, 1, 1>
(data[2 * i], data[2 * i + 1]);
problem.AddResidualBlock(cost_function, nullptr, &m, &c);
}
编译并运行 examples/curve_fitting.cc 可以得到如下结果:
iter cost cost_change |gradient| |step| tr_ratio tr_radius ls_iter iter_time total_time
0 1.211734e+02 0.00e+00 3.61e+02 0.00e+00 0.00e+00 1.00e+04 0 5.34e-04 2.56e-03
1 1.211734e+02 -2.21e+03 0.00e+00 7.52e-01 -1.87e+01 5.00e+03 1 4.29e-05 3.25e-03
2 1.211734e+02 -2.21e+03 0.00e+00 7.51e-01 -1.86e+01 1.25e+03 1 1.10e-05 3.28e-03
3 1.211734e+02 -2.19e+03 0.00e+00 7.48e-01 -1.85e+01 1.56e+02 1 1.41e-05 3.31e-03
4 1.211734e+02 -2.02e+03 0.00e+00 7.22e-01 -1.70e+01 9.77e+00 1 1.00e-05 3.34e-03
5 1.211734e+02 -7.34e+02 0.00e+00 5.78e-01 -6.32e+00 3.05e-01 1 1.00e-05 3.36e-03
6 3.306595e+01 8.81e+01 4.10e+02 3.18e-01 1.37e+00 9.16e-01 1 2.79e-05 3.41e-03
7 6.426770e+00 2.66e+01 1.81e+02 1.29e-01 1.10e+00 2.75e+00 1 2.10e-05 3.45e-03
8 3.344546e+00 3.08e+00 5.51e+01 3.05e-02 1.03e+00 8.24e+00 1 2.10e-05 3.48e-03
9 1.987485e+00 1.36e+00 2.33e+01 8.87e-02 9.94e-01 2.47e+01 1 2.10e-05 3.52e-03
10 1.211585e+00 7.76e-01 8.22e+00 1.05e-01 9.89e-01 7.42e+01 1 2.10e-05 3.56e-03
11 1.063265e+00 1.48e-01 1.44e+00 6.06e-02 9.97e-01 2.22e+02 1 2.60e-05 3.61e-03
12 1.056795e+00 6.47e-03 1.18e-01 1.47e-02 1.00e+00 6.67e+02 1 2.10e-05 3.64e-03
13 1.056751e+00 4.39e-05 3.79e-03 1.28e-03 1.00e+00 2.00e+03 1 2.10e-05 3.68e-03
Ceres Solver Report: Iterations: 13, Initial cost: 1.211734e+02, Final cost: 1.056751e+00, Termination: CONVERGENCE
Initial m: 0 c: 0
Final m: 0.291861 c: 0.131439
从 m=0,c=0 为初值进行优化,目标函数值为 1.211734e+02。最终 Ceres 找到的解为 m=0.291861,c=0.131439,目标函数值为 1.056。和真值 m=0.3,c=0.1 比起来有略微的差别,但是由于噪声的存在,结果其实在可接受的范围内。实际上,如果用m=0.3,c=0.1 来评估目标函数会发现 Cost 比 1.056 还要大。下图展示了拟合结果。
Last updated