2

Ceres Solver のチュートリアルを進めています。

パウエル関数

Powell の関数は からマッピングされるため、4 要素の配列を取り、4 要素の配列を埋める1 つの残差ブロックR^4 -> R^4を定義するのは直感的に思えます。xresidual

代わりに、チュートリアルの例では、マッピングする 4 つの異なる残差ブロックを定義していますR^2 -> R^1

もちろん、 を最小化しようとしている場合1/2 || F(x) ||^2、 の各要素を最小化すると、直接F最小化するのと同じ解決策が暗黙的に得られます (つまり、私の提案は、 ...を個別にではなく1/2 || F(x) ||^2単一の残差ベクトルを返すことです)。(以下のコスト関数を使用してこれを確認しました)。FF1F4

struct F {
    template<typename T>
    bool operator() (const T* const x, T* residual) const {

        residual[0] = x[0] + 10.0 * x[1];
        residual[1] = sqrt(5.0) * (x[2] - x[3]);
        residual[2] = (x[1] - 2.0*x[2]) * (x[1] - 2.0*x[2]);
        residual[3] = T(sqrt(10.0)) * (x[0]  - x[3]) * (x[0] - x[3]);

        return true;
    }
};
  1. 残差ベクトルの要素ごとに個別の残差ブロック (および暗黙的なパラメーター ブロック) を定義する利点は何Fですか?

  2. 残差F1がパラメータx1およびに依存しx2、残差がおよびに依存する場合、 に関する のコストはの値に影響しますか?F2x3x4Fx1x3

カーブフィッティング

もう 1 つの例では、パラメーターを見つけて曲線を作成しようとしてmcますy=e^(mx + c)

データポイントの場所ExponentialResidualを単純に出力するものを定義します。T(y_) - exp(m[0] * T(x_) + c[0])(x_, y_)

次に、観測ごとに 1 つの残差ブロックを追加します。

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>(
           new ExponentialResidual(data[2 * i], data[2 * i + 1]));
  problem.AddResidualBlock(cost_function, NULL, &m, &c);
}
  1. 私は怠惰すぎてこの例を自分で再現できませんでしたが、1D 残差がすべてのすべての合計にすぎない 1 つの残差ブロックをマップするだけでも実現できるのR^2 -> R^1ではないかと思います。観測ごとに残差ブロックを定義する必要がありましたか?T(y_) - exp(m[0] * T(x_) + c[0])(x_, y_)

この長い投稿を読んでくれてありがとう!

4

1 に答える 1