1. 程式人生 > >Ceres Solver 官方教程學習筆記(八)——數值微分法Numeric derivatives

Ceres Solver 官方教程學習筆記(八)——數值微分法Numeric derivatives

利用analytic derivatives的另一個極端形式是 numeric derivatives,即數值微分法。數值微分法的關鍵是,目標函式f(x)的微分方程可以被寫成一個極限形式:

Df(x)=limh0f(x+h)f(x)h

前向差分

當然,在計算機上h使不可能無限逼近0的,那就是選擇一個非常小的h的值並近似導數

Df(x)f(x+h)f(x)h
上面的公式是最簡單的最基本的數值微分。它被稱為 “正向差分公式”。

那麼,如何在Ceres中實際構建一個數值微分演算法過程的呢?主要可以分為兩個步驟:
1. 定義Functor

給定引數值,Ceres將通過它對給定的(xy)的進行殘值計算。
2. 用 NumericDiffCostFunction 來構造一個CostFunction 來封裝整個例項。

這裡我們仍然延用上一節解析微分演算法中的例子。

y=b1(1+eb2b3x)1/b4
(1)E(b1,b2,b3,b4)=if2(b1,b2,b3,b4;xi,yi)(2)=i(b1(1+eb2b3xi)1/b4
yi)2

(3)D1f(b1,b2,b3,b4;x,y)=1(1+eb2b3x)1/b4

具體程式碼如下:

struct Rat43CostFunctor {
  Rat43CostFunctor(const double x, const double y) : x_(x), y_(y) {}

  bool operator()(const double* parameters, double* residuals) const {
    const double b1 = parameters[0
]; const double b2 = parameters[1]; const double b3 = parameters[2]; const double b4 = parameters[3]; residuals[0] = b1 * pow(1.0 + exp(b2 - b3 * x_), -1.0 / b4) - y_; return true; } const double x_; const double y_; //Analytic演算法中手動求解Jacobians的部分被拿掉了。 } CostFunction* cost_function = new NumericDiffCostFunction<Rat43CostFunctor, FORWARD, 1, 4>( new Rat43CostFunctor(x, y));

這個生成微分的方法對於使用者來說工作量最小。使用者只需要關注殘差計算是否正確和有效。這是第一步。

在進一步深入之前,我們需要先探討一下前向查分的誤差。我們在x點附近對f進行泰勒展開。