1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        追溯Ceres-Solver中CostFunction類方法

        共 3543字,需瀏覽 8分鐘

         ·

        2021-11-27 10:57

        本文作為《徹底搞懂視覺-慣性SLAM:VINS-Fusion原理精講與源碼剖析》課程補(bǔ)充材料
        作者:Kehan
        平臺:3D視覺工坊
        日期:2021/11/19
        在使用Ceres-Solver進(jìn)行解析求導(dǎo)時,需要繼承CostFunction類,并重寫virtual bool Evaluate(double const* const* parameters, double* residuals, double** jacobians) const函數(shù),以來在殘差項計算的同時給出對應(yīng)的雅克比矩陣。
        顯而易見,在構(gòu)建殘差項的時候,我們通過AddResidualBlock(...)函數(shù)將上述構(gòu)建的CostFunction傳入ceres::Problem中。那么,上述重寫的bool Evaluate(...)函數(shù)在何時被調(diào)用呢?追溯、閱讀這個過程,會讓我們對非線性優(yōu)化問題的求解、以及函數(shù)實現(xiàn)方面有更深入的理解。
        下面以Ceres-Solver的1.14.0版本源碼(源碼鏈接:https://github.com/ceres-solver/ceres-solver/releases/tag/1.14.0)為例,給出用Ceres做優(yōu)化、求解問題時,其調(diào)用我們所實現(xiàn)的virtual bool Evaluate(double const* const* parameters, double* residuals, double** jacobians) const函數(shù)的過程。

        1.internal/ceres/solver.cc文件

        在求解問題時,我們調(diào)用了
        ceres::Solve(options, &problem, &summary);
        該函數(shù)的實現(xiàn)在文件internal/ceres/solver.cc的631行中。簡單可以看到,它又調(diào)用了Solver::Solve(...)函數(shù)。
        void Solver::Solve(const Solver::Options& options,                  Problem* problem,                  Solver::Summary* summary);
        在Solver::Solve(...)函數(shù)中,首先對問題進(jìn)行了預(yù)處理。然后在代碼的第602行,調(diào)用了Minimize(...)函數(shù)。
        void Minimize(internal::PreprocessedProblem* pp,             Solver::Summary* summary);
        Minimize(...)函數(shù)根據(jù)求解配置中的選擇,選擇不同類型的優(yōu)化器。在代碼464行minimizer->Minimize(...)(基類的虛函數(shù),所以去找子類的實現(xiàn))時調(diào)用所選擇的求解器進(jìn)行求解。求解器以的實現(xiàn)主要有三種,下文以Levenberg-Marquadt法所屬的TrustRegionMinimizer求解器為例。

        2. internal/ceres/trust_region_minimizer.h文件

        我們看主要流程。
        TrustRegionMinimizer在internal/ceres/trust_region_minimizer.h文件中重寫實現(xiàn)的方法Minimize(...):
        void TrustRegionMinimizer::Minimize(const Minimizer::Options& options,                                   double* parameters,                                   Solver::Summary* solver_summary)
        第113行調(diào)用HandleSuccessfulStep()函數(shù)。在HandleSuccessfulStep()函數(shù)的實現(xiàn)代碼777行中,調(diào)用了EvaluateGradientAndJacobian(...)函數(shù)。
        EvaluateGradientAndJacobian(...)這個函數(shù)是一個重要的函數(shù),就是在這里算的一系列東西,我們看源代碼的注釋便可知。
        internal/ceres/trust_region_minimizer.cc文件第214行開始:
        // For the current x_, compute////  1. Cost//  2. Jacobian//  3. Gradient//  4. Scale the Jacobian if needed (and compute the scaling if we are//     in iteration zero).//  5. Compute the 2 and max norm of the gradient.//// Returns true if all computations could be performed// successfully. Any failures are considered fatal and the// Solver::Summary is updated to indicate this.bool TrustRegionMinimizer::EvaluateGradientAndJacobian(   bool new_evaluation_point) {...}
        EvaluateGradientAndJacobian(...)的實現(xiàn)中,在代碼230行調(diào)用了evaluator_->Evaluate(...)。這又是一個基類的虛函數(shù)。我們看ProgramEvaluator類的實現(xiàn),在internal/ceres/program_evaluator.h文件中。

        3.internal/ceres/program_evaluator.h文件

        ProgramEvaluator類所實現(xiàn)的Evaluate(...)函數(shù)中,internal/ceres/program_evaluator.h文件第254行,我們看到調(diào)用了residual_block->Evaluate(...),這里是不是有些眼熟了。我們就是將自己所實現(xiàn)的CostFunction類添加到了殘差塊ResidualBlock中去了。所以接下來我們看residual_block->Evaluate(...)的實現(xiàn)。

        4.internal/ceres/residual_block.cc文件

        residual_block->Evaluate(...)的實現(xiàn)在文件internal/ceres/residual_block.cc中,自第68行開始。
        bool ResidualBlock::Evaluate(const bool apply_loss_function,                            double* cost,                            double* residuals,                            double** jacobians,                            double* scratch) const {...}
        在實現(xiàn)代碼里的第111行,我們發(fā)現(xiàn)調(diào)用了我們所實現(xiàn)的virtual bool Evaluate(double const* const* parameters, double* residuals, double** jacobians) const函數(shù):
        if (!cost_function_->Evaluate(parameters.get(), residuals, eval_jacobians)) {   return false; }
        在這里調(diào)用,實現(xiàn)了待優(yōu)化變量的傳入,并計算出了殘差項與雅克比矩陣。
        至此,我們追溯了我們所實現(xiàn)的virtual bool Evaluate(double const* const* parameters, double* residuals, double** jacobians) const函數(shù)是如何在Ceres-Solver做優(yōu)化時被調(diào)用的。
        瀏覽 105
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            美女搞黄网站 | 黄色片网站学生妹妹久久久 | 猛男裸体xvideoscom | 欧洲成人免费视频 | 亚洲无码中文字幕强奸乱伦 | 豆花视频在线资源福利总站 | 欧美成人三级精品 | 99豆花视频 | 午夜爱爱爱爱爱爽爽爽爽爽? | 美女羞羞视频在线观看 |