Ceres Solver のチュートリアルを進めています。
パウエル関数
Powell の関数は からマッピングされるため、4 要素の配列を取り、4 要素の配列を埋める1 つの残差ブロックR^4 -> R^4
を定義するのは直感的に思えます。x
residual
代わりに、チュートリアルの例では、マッピングする 4 つの異なる残差ブロックを定義していますR^2 -> R^1
。
もちろん、 を最小化しようとしている場合1/2 || F(x) ||^2
、 の各要素を最小化すると、直接F
最小化するのと同じ解決策が暗黙的に得られます (つまり、私の提案は、 ...を個別にではなく1/2 || F(x) ||^2
単一の残差ベクトルを返すことです)。(以下のコスト関数を使用してこれを確認しました)。F
F1
F4
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;
}
};
残差ベクトルの要素ごとに個別の残差ブロック (および暗黙的なパラメーター ブロック) を定義する利点は何
F
ですか?残差
F1
がパラメータx1
およびに依存しx2
、残差がおよびに依存する場合、 に関する のコストはの値に影響しますか?F2
x3
x4
F
x1
x3
カーブフィッティング
もう 1 つの例では、パラメーターを見つけて曲線を作成しようとしてm
いc
ます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);
}
- 私は怠惰すぎてこの例を自分で再現できませんでしたが、1D 残差がすべてのすべての合計にすぎない 1 つの残差ブロックをマップするだけでも実現できるの
R^2 -> R^1
ではないかと思います。観測ごとに残差ブロックを定義する必要がありましたか?T(y_) - exp(m[0] * T(x_) + c[0])
(x_, y_)
この長い投稿を読んでくれてありがとう!