Когда определять несколько остаточных блоков в Церере? - PullRequest
0 голосов
/ 27 октября 2019

Я прохожу учебник по Ceres Solver .

Функция Пауэлла

Карты функций Пауэлла из R^4 -> R^4, поэтому определение кажется интуитивно понятнымодин остаточный блок, который принимает массив из 4 элементов x и заполняет массив из 4 элементов 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;
    }
};
  1. В чем преимущество определения отдельных остаточных блоков (и неявно блоков параметров) для каждого элемента остаточного вектора F?

  2. Если остаток 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);
}
  1. Хотя мне было лень воспроизводить этот пример сам, я подозреваю, что это также может быть достигнуто только с одним остаточным блоком, который отображает R^2 -> R^1, где 1DОстаток - это просто сумма всех T(y_) - exp(m[0] * T(x_) + c[0]) для всех (x_, y_)? Было ли необходимо определять остаточный блок для каждого наблюдения?

Спасибо за чтение этого длинного поста!

1 Ответ

0 голосов
/ 30 октября 2019

Основная причина заключается в том, что Ceres рассматривает разреженность только на уровне параметра, а остаточные блоки , а не отдельные термины. Для действительно плотной задачи, где каждый остаточный член зависит от каждого параметра, то, как проблема представляется, не оказывает существенного влияния на производительность среды выполнения.

Однако Ceres предназначен для обработки очень больших разреженных проблемы, в которых каждый остаточный член зависит только от нескольких параметров, но существует много параметров и остатков. Абсолютно важно использовать разреженную структуру этих проблем, чтобы иметь возможность эффективно их решать - т.е. избегать множества бессмысленных вычислений, где все слагаемые равны нулю. Хотя линейная алгебра математически идентична, подход, с помощью которого линейная система представляется и решается, сильно отличается при работе с разреженными матрицами.

Вторая причина заключается в том, что она облегчает моделирование задачи. Функции потерь применяются к результату: r ^ T * r (где r - остаточный блок). Если у вас есть только один остаточный блок, функция потерь эффективно масштабирует общую стоимость, а не понижает вес только части проблемы с большими ошибками (отклонение выброса). Ceres также может обрабатывать остаточные блоки, что ускоряет оценку больших проблем.

Последняя часть вашего вопроса отличается. В примере подбора кривой есть два параметра и остатки kNumObservations, проблема сильно переопределена. Однако, если вместо этого у вас был один остаток, который внутренне вычислял ошибки для точек kNumObservations, но только возвращал их сумму, то проблема как решенная имеет два параметра, но только один остаток, и она не определена. В качестве отдельного примечания возврат их суммы также будет другим, поскольку вы не возвращаете возведенную в квадрат сумму, поэтому ошибки разных знаков в разных остатках могут эффективно взаимно компенсировать друг друга - ни один из них не будет наблюдаться решающим.

...