Curve Fitting

到目前为止,我们看到的例子都是没有数据的简单优化问题。最小二乘法和非线性最小二乘法的最初目的是对数据进行曲线拟合。我们使用曲线方程 y=e0.3x+0.1y=e^{0.3x+0.1} 来生成样本数据,并且对每个样本都添加一个标准差为 σ=0.2\sigma=0.2 的高斯噪声,我们来拟合如下曲线方程:

y=emx+cy=e^{mx+c}

其中 m,cm,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。

编译并运行 examples/curve_fitting.cc 可以得到如下结果:

m=0,c=0m=0,c=0 为初值进行优化,目标函数值为 1.211734e+02。最终 Ceres 找到的解为 m=0.291861,c=0.131439m=0.291861,c=0.131439,目标函数值为 1.056。和真值 m=0.3,c=0.1m=0.3,c=0.1 比起来有略微的差别,但是由于噪声的存在,结果其实在可接受的范围内。实际上,如果用m=0.3,c=0.1m=0.3,c=0.1 来评估目标函数会发现 Cost 比 1.056 还要大。下图展示了拟合结果。

Least Square Curve Fitting

Footnotes

Last updated