我正在阅读 Ceres Solver教程。
鲍威尔函数
Powell 函数映射自,因此定义一个接收 4 元素数组并填充 4元素数组的残差块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
曲线拟合
另一个示例尝试查找参数m
和c
曲线y=e^(mx + c)
。
它定义了一些简单地ExponentialResidual
输出数据点的位置。T(y_) - exp(m[0] * T(x_) + c[0])
(x_, y_)
然后他们继续为每个观察添加一个残差块
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);
}
- 虽然我懒得自己重现这个例子,但我怀疑这也可以用一个映射的残差块来完成
R^2 -> R^1
,其中一维残差只是所有的T(y_) - exp(m[0] * T(x_) + c[0])
总和(x_, y_)
?是否有必要为每个观察定义一个残差块?
感谢您阅读这篇长文!