1、Ceres簡介
Ceres是一個非常優秀的非線性優化庫(谷歌出品)。能完成很複雜的優化功能,選項也非常的多,本篇博客就來梳理下這些選項。Ceres的參數主要有三類,一類通用參數,比如迭代次數什麼的;第二類是和優化算法的參數;第三類是和線性求解器(在信任域算法中被使用)有關的參數。
我在調Ceres Solver的優化的參數時,我首先會調最大迭代次數,然後換優化算法,調優化算法的參數,最後再調線性求解器的參數。
並不是所有的參數我都列出來了,我只列出常用的參數。
參考:solver-options。
2、常用通用參數
-
bool Solver::Options::IsValid(string *error) const
檢查options是否合法,不合法的話返回false,並將錯誤信息存到error裏面。 -
int Solver::Options::max_num_iterations
默認值:50
最大迭代次數。 -
double Solver::Options::max_solver_time_in_seconds
默認值:1e6
最長運行時間,單位爲秒。 -
int Solver::Options::num_threads
默認值:1
Ceres用於評估Jacobian的線程數,越多優化速度越快。 -
DenseLinearAlgebraLibrary Solver::Options::dense_linear_algebra_library_type
默認值:EIGEN
Ceres支持使用多個密集線性代數庫進行稠密矩陣分解。 目前可選的爲EIGEN和LAPACK。 EIGEN始終可用;LAPACK指的是BLAS + LAPACK庫,可能有也可能沒有(得看編譯Ceres庫時有沒有加入BLAS + LAPACK的支持)。
此設置會影響DENSE_QR,DENSE_NORMAL_CHOLESKY和DENSE_SCHUR求解器。 對於小到中等大小的求解器(這裏的大小應該是指運算量,也就是問題規模的大小),EIGEN是一個很好的選擇,但對於大問題,LAPACK + BLAS實現可以在性能上優勢很大。 -
SparseLinearAlgebraLibrary Solver::Options::sparse_linear_algebra_library_type
默認值:SUITE_SPARSE > CX_SPARSE > EIGEN_SPARSE > NO_SPARSE
Ceres支持使用三個稀疏線性代數庫SuiteSparse、CXSparse、EIGEN_SPARSE ,NO_SPARSE意味着不應使用稀疏線性求解器。
SuiteSparse是一個非常複雜的稀疏線性代數庫(就是一羣非常牛*的人寫的),性能最好,推薦使用。如果SuiteSparse不可用(編譯Ceres的時候沒有加入SuiteSparse支持),請考慮使用CXSparse,這是一個更小,更容易編譯的庫。但是,它在大問題上的性能與SuiteSparse的性能相差巨大。也可以使用Eigen中稀疏線性代數庫。目前,這個庫的表現是三個中最差的。說不定在不久的將來性能會有改善。 -
int Solver::Options::num_linear_solver_threads
默認值:-1
這是一個廢棄的選項,將在1.15中刪除。 -
LoggingType Solver::Options::logging_type
默認值:PER_MINIMIZER_ITERATION
每次迭代都打印信息,另一個可選的爲SILENT。 -
bool Solver::Options::minimizer_progress_to_stdout
默認值:false
默認情況下,Minimizer(優化器)進度會記錄到stderr,具體取決於vlog級別。 如果此標誌設置爲true,並且Solver::Option:: logging_type不是SILENT,則日誌記錄輸出將發送到stdout(在終端打印出信息)。
對於TRUST_REGION_MINIMIZER,進度顯示如下:
iter cost cost_change |gradient| |step| tr_ratio tr_radius ls_iter iter_time total_time
0 4.185660e+06 0.00e+00 1.09e+08 0.00e+00 0.00e+00 1.00e+04 0 7.59e-02 3.37e-01
1 1.062590e+05 4.08e+06 8.99e+06 5.36e+02 9.82e-01 3.00e+04 1 1.65e-01 5.03e-01
2 4.992817e+04 5.63e+04 8.32e+06 3.19e+02 6.52e-01 3.09e+04 1 1.45e-01 6.48e-01
1. cost 是目標函數的值。
2. cost_change 是目標函數值的變化。
3. |gradient| 是梯度的最大範數。
4. |step| 是參數向量的變化。
5. tr_ratio是目標函數值的實際變化與信賴域模型值的變化之比。
6. tr_radius是信任區域半徑的大小。
7. ls_iter是用於計算信任區域步驟的線性求解器迭代次數。
8. total_time是所用的總時間。
對於LINE_SEARCH_MINIMIZER,進度顯示如下:
0: f: 2.317806e+05 d: 0.00e+00 g: 3.19e-01 h: 0.00e+00 s: 0.00e+00 e: 0 it: 2.98e-02 tt: 8.50e-02
1: f: 2.312019e+05 d: 5.79e+02 g: 3.18e-01 h: 2.41e+01 s: 1.00e+00 e: 1 it: 4.54e-02 tt: 1.31e-01
2: f: 2.300462e+05 d: 1.16e+03 g: 3.17e-01 h: 4.90e+01 s: 2.54e-03 e: 1 it: 4.96e-02 tt: 1.81e-01
1. f是目標函數的值。
2. d是目標函數的值的變化。
3. g是梯度的最大範數。
4. h是參數向量的變化。
5. s是線搜索計算的最佳步長。
6. it是當前迭代所花費的時間。
7. tt是最小化器所用的總時間。
-
bool Solver::Options::check_gradients
默認值:false
檢查由具有有限差分的每個殘差塊計算的所有雅可比行列式,比較結果,如果它們大不相同,則優化失敗。如果設置爲true的花比較耗費性能,一般保持默認。 -
double Solver::Options::gradient_check_relative_precision
默認值: 1e8
在gradient checker中檢查的精度。 如果雅可比行列式中的元素之間的相對差異超過此數字,則dump該cost term的雅可比行列式。 -
vector Solver::Options::callbacks
在Minimizer的每次迭代結束時執行的回調。 它們按照在此vector中指定的順序執行。 默認情況下,參數僅在優化結束時更新。 如果希望在執行回調時訪問更新的參數,則將Solver::Options::update_state_every_iteration需要設置爲true。 -
bool Solver::Options::update_state_every_iteration
默認值:false
如果爲true,則在每個迭代結束時更新參數,否則在優化終止時才更新參數。更多細節請參考鏈接。
3、與優化算法相關的參數
在Ceres中,求解優化問題有兩類方法:信任域(TRUST_REGION)和線性搜索(LINE_SEARCH,尚不支持邊界約束),和它們相關的主要的參數如下圖所示(小寫的是選項):
上面的參數應該就是本篇文檔中重要的幾個參數。
3.1、優化方法無關參數
-
MinimizerType Solver::Options::minimizer_type
默認值:TRUST_REGION
可選的爲LINE_SEARCH和TRUST_REGION,這是非線性優化的兩類算法。參考:Trust Region Methods 、 Line Search Methods。 -
double Solver::Options::gradient_tolerance
默認值:1e-10
求解器會在滿足
時停止求解。其中||⋅||∞是指最大範數,Π是對邊界約束的投影,⊞是與參數矢量相關的整體局部參數化的加法運算。
3.2、TRUST_REGION
-
double Solver::Options::function_tolerance
默認值:1e-6
求解器會在滿足:
時停止求解,其中Δcost是Levenberg-Marquardt方法中當前迭代中目標函數值(也就是損失函數)的變化。上面的公式可以這樣理解,Δcost/cost非常小了,就說明cost基本沒啥變化,就認爲已經得到一個解了,故停止優化。 -
TrustRegionStrategyType Solver::Options::trust_region_strategy_type
默認值:LEVENBERG_MARQUARDT
可選的爲LEVENBERG_MARQUARDT和DOGLEG。更多細節請參考: Levenberg-Marquardt 和 Dogleg。 -
DoglegType Solver::Options::dogleg_type
默認值:TRADITIONAL_DOGLEG
可選的爲TRADITIONAL_DOGLEG和SUBSPACE_DOGLEG。更多細節請參考: Dogleg。 -
bool Solver::Options::use_nonmonotonic_steps
默認值:false
更多細節請參考原文檔。 -
double Solver::Options::initial_trust_region_radius
默認值:1e4
初始信任區域的大小。 當使用LEVENBERG_MARQUARDT策略時,該數字的倒數是初始正則化參數。 -
double Solver::Options::max_trust_region_radius
默認值:1e16
信任區域半徑最大值。 -
double Solver::Options::min_trust_region_radius
默認值:1e-32
信任區域的最小值。當信任區域小於此值,會停止優化。 -
double Solver::Options::min_relative_decrease
默認值:1e-3
信任域步長(trust region step)相對減少的最小值。 -
double Solver::Options::min_lm_diagonal
默認值:1e6
LEVENBERG MARQUARDT算法使用對角矩陣來規範(regularize)信任域步長。 這是該對角矩陣的值的下限。 -
double Solver::Options::max_lm_diagonal
默認值:1e32
LEVENBERG MARQUARDT算法使用對角矩陣來規範(regularize)信任域步長。這是該對角矩陣的值的上限。 -
int Solver::Options::max_num_consecutive_invalid_steps
默認值:5
信任區域策略返回的步驟有時可能在數值上無效,通常是因爲條件問題。 優化器可以繼續嘗試使用較小的信任區域/更好的條件問題來解決,而不是崩潰或停止優化。 此參數設置最小化器停止優化之前的連續重試次數。
3.3、LINE_SEARCH
-
LineSearchDirectionType Solver::Options::line_search_direction_type
默認值:LBFGS
可選的爲STEEPEST_DESCENT、NONLINEAR_CONJUGATE_GRADIENT、BFGS和LBFGS,都屬於LINE_SEARCH類的算法。 -
LineSearchType Solver::Options::line_search_type
默認值:WOLFE
選擇是ARMIJO和WOLFE(強WOLFE條件)。 爲了保證BFGS和LBFGS線搜索方向算法的基本假設得到滿足,應使用WOLFE線性搜索。 -
int Solver::Options::max_lbfgs_rank
默認值:20
L-BFGS的Hessian矩陣是對Hessian矩陣的逆的低秩近似。 近似的秩的大小與近似算法的空間和時間複雜度線性相關。 秩越高,近似的質量越好。 然而,由於以下兩種原因,質量的提高受到限制。
~The method only uses secant information and not actual derivatives.
~The Hessian approximation is constrained to be positive definite.
因此,將該秩增加到一個特別大的數字將大量將花費時間和空間而不會相應地提高求解的質量。不同的問題,可能最佳的秩也不同。 -
bool Solver::Options::use_approximate_eigenvalue_bfgs_scaling
默認值:false
更多細節請參考原文檔。 -
LineSearchIterpolationType Solver::Options::line_search_interpolation_type
默認值:CUBIC
用於近似目標函數的多項式的次數。 可選的爲BISECTION,QUADRATIC和CUBIC。 -
double Solver::Options::min_line_search_step_size
線性搜索將在滿足
時停止搜索。其中||⋅||∞是指無窮範數,Δxk是第k次迭代時參數值的step的變化量。這是線性線性搜索算法的一個終止條件。 -
double Solver::Options::line_search_sufficient_function_decrease
默認值:1e-4
完全解決線搜索問題在計算上是令人望而卻步的。 幸運的是,基於行搜索的優化算法仍然可以保證收斂,如果不是精確的解決方案,行搜索算法返回一個充分降低目標函數值(cost)的解。 更準確地說,尋找步長s.t.
上面的就是Armijo條件。 -
double Solver::Options::max_line_search_step_contraction
默認值: 1e-3
在線性搜索算法的每次迭代中,
根據定義,滿足約束:
-
double Solver::Options::min_line_search_step_contraction
默認值:0.6
在線性搜索算法的每次迭代中,
根據定義,滿足約束:
-
int Solver::Options::max_num_line_search_step_size_iterations
默認值:20
每次線搜索期間的最大試驗步長迭代次數,如果在此次試驗次數內無法找到滿足搜索條件的步長(step size),則線性搜索將停止。
由於這是一個“人爲”約束,如果正在使用WOLFE線性搜索,並且在當前搜索期間找到了滿足Armijo條件的的點(in < = max_num_line_search_step_size_iterations)。 然後,具有滿足Armijo條件的最低函數值的步長將作爲新的有效步長返回,即使它不滿足強Wolfe條件。可防止優化器在次優解處提前終止。 -
int Solver::Options::max_num_line_search_direction_restarts
默認值:5
線性搜索方向算法的最大重啓次數,超過此數值時,求解就停止了。 噹噹前算法未能產生新的下降方向時,線性搜索方向算法會重新開始。 -
double Solver::Options::line_search_sufficient_curvature_decrease
默認值:0.9
更多細節請參考原文檔。 -
double Solver::Options::max_line_search_step_expansion
默認值:10.0
和Wolfe線性搜索相關。更多細節請參考原文檔。
4、與線性求解器有關的參數
-
double Solver::Options::parameter_tolerance
默認值:1e-8
求解器會在
其中Δx是當前迭代中線性求解器(Linear Solver)計算的步長。 -
LinearSolverType Solver::Options::linear_solver_type
默認值:SPARSE_NORMAL_CHOLESKY / DENSE_QR
線性求解器的類型,用於計算Levenberg-Marquardt算法每次迭代中線性最小二乘問題的解。 如果編譯Ceres時加入了SuiteSparse或CXSparse或Eigen的稀疏Cholesky分解選項,則默認爲SPARSE_NORMAL_CHOLESKY,否則爲DENSE_QR。 -
PreconditionerType Solver::Options::preconditioner_type
默認值:JACOBI
迭代線性求解器使用的預處理器(Preconditioner)。 默認是塊Jacobi預處理器。 有效值是IDENTITY,JACOBI,SCHUR_JACOBI,CLUSTER_JACOBI和CLUSTER_TRIDIAGONAL(複雜程度依次遞增)。 更多細節請參考Preconditioner。 -
DenseLinearAlgebraLibrary Solver::Options::dense_linear_algebra_library_type
默認值:EIGEN -
shared_ptr Solver::Options::linear_solver_ordering
默認值:NULL
更多細節請參考原文檔。
還有很多關於求解器的參數,用的少,我懶得列了。