在进行轻量级sfm拼图开发时联想到神经网络的优化,实际上绝大多数算法问题都可以表述为优化问题。两者的异同点以及最小二乘法优化的一些相关知识记载如下:
很多建模问题都可以写成一个统一形式:
min θ L ( θ ) \min_\theta L(\theta) θminL(θ)
也就是寻找一组参数 θ \theta θ,让目标函数或损失函数 L ( θ ) L(\theta) L(θ) 尽可能小。
理解优化问题时,可以把它拆成三个层次:
| 层次 | 回答的问题 | 例子 |
|---|---|---|
| 损失函数 | 我们要最小化什么? | 残差平方和、MSE、交叉熵 |
| 正则 / 约束 | 我们希望解具有什么性质? | 平滑约束、权重衰减、bounds |
| 优化算法 | 用什么方法把目标函数降下来? | SGD、Adam、Gauss-Newton、LM |
因此,最小二乘、平滑约束、SGD、Adam、least_squares 并不是同一类概念。它们处在优化问题的不同层次里。
1. 残差、RSS、MSE 与最小二乘
假设真实观测值是 y i y_i yi,模型预测值是 y ^ i \hat y_i y^i,那么残差就是:
r i = y i − y ^ i r_i = y_i - \hat y_i ri=yi−y^i
残差表示模型预测和真实观测之间的误差。
残差平方和为:
R S S = ∑ i = 1 N r i 2 RSS = \sum_{i=1}^N r_i^2 RSS=i=1∑Nri2
最小二乘就是选择参数,让残差平方和最小:
min θ ∑ i r i ( θ ) 2 \min_\theta \sum_i r_i(\theta)^2 θmini∑ri(θ)2
所以可以简单理解为:
最小二乘 = 以残差平方和作为目标函数,并最小化它。
例如线性回归中:
y ^ i = w x i + b \hat y_i = wx_i + b y^i=wxi+b
目标函数是:
min w , b ∑ i ( y i − w x i − b ) 2 \min_{w,b} \sum_i (y_i - wx_i - b)^2 w,bmini∑(yi−wxi−b)2
这里的"二乘"指残差平方,"最小"指让平方和最小。
如果把 RSS 除以样本数量 N N N,就得到均方误差 MSE:
M S E = 1 N ∑ i = 1 N r i 2 MSE = \frac{1}{N}\sum_{i=1}^N r_i^2 MSE=N1i=1∑Nri2
当 N N N 固定时,RSS 和 MSE 只差一个常数倍,因此不会改变最优解。但 MSE 更方便比较不同数据集或不同 batch 的平均误差,所以在机器学习中更常见。
需要注意的是,机器学习并不等于最小二乘。
如果损失函数是 MSE,那么它本质上是最小二乘思想;但分类任务常用交叉熵,排序任务有 ranking loss,对比学习也有 contrastive loss 或 triplet loss。
更准确地说:
机器学习是在优化损失函数;如果损失函数是平方残差,它就是最小二乘思想。
2. 正则项与约束
实际优化问题中,除了希望模型拟合观测数据,还常常希望解满足一些额外性质,例如:
- 更平滑;
- 不要偏离某个先验值;
- 参数不要过大;
- 参数不要超出某个范围。
这些额外要求通常通过正则项或约束项加入目标函数:
L ( θ ) = L data ( θ ) + λ L reg ( θ ) \begin{aligned} L(\theta) &= L_{\text{data}}(\theta) + \lambda L_{\text{reg}}(\theta) \end{aligned} L(θ)=Ldata(θ)+λLreg(θ)
其中:
- L data L_{\text{data}} Ldata 是数据项,要求结果符合观测;
- L reg L_{\text{reg}} Lreg 是正则项,要求解满足某种偏好;
- λ \lambda λ 是权重,用来控制正则项的重要程度。
λ \lambda λ 越大,约束越强; λ \lambda λ 越小,约束越弱。
3. 平滑约束
平滑约束是一类常见正则项,用来惩罚"不平滑"的解。
一阶平滑约束惩罚相邻变量之间的差:
L smooth = ∑ i ( x i + 1 − x i ) 2 L_{\text{smooth}} = \sum_i (x_{i+1}-x_i)^2 Lsmooth=i∑(xi+1−xi)2
它希望相邻值不要差太多,常用于图像去噪、深度图平滑、时间序列平滑等问题。
二阶平滑约束惩罚相邻差分的变化:
L smooth = ∑ i ( x i + 1 − 2 x i + x i − 1 ) 2 L_{\text{smooth}} = \sum_i (x_{i+1}-2x_i+x_{i-1})^2 Lsmooth=i∑(xi+1−2xi+xi−1)2
它不一定要求相邻值接近,而是希望变化趋势不要突然改变,常用于曲线拟合、轨迹平滑、运动规划等问题。
二者的区别可以这样理解:
| 类型 | 惩罚什么 | 适合场景 |
|---|---|---|
| 一阶平滑 | 相邻值差异 | 避免跳变 |
| 二阶平滑 | 变化量的变化 | 避免弯曲或加速度突变 |
简单判断:
希望相邻值接近,用一阶平滑;
希望变化趋势平滑,用二阶平滑。
4. 先验项、bounds 与额外残差
如果希望某个参数 x x x 不要离常数 c c c 太远,可以加入先验项:
L prior = ( x − c ) 2 L_{\text{prior}} = (x-c)^2 Lprior=(x−c)2
总损失变为:
L = L data + λ prior ( x − c ) 2 L = L_{\text{data}} + \lambda_{\text{prior}}(x-c)^2 L=Ldata+λprior(x−c)2
它表示希望 x x x 接近先验值 c c c,但不一定强制等于 c c c。
bounds 约束则要区分硬约束和软约束。
如果要求:
a ≤ x ≤ b a \le x \le b a≤x≤b
并且绝对不能越界,这就是硬约束,通常交给带约束优化器处理。
如果只是希望参数尽量留在范围内,可以写成软约束惩罚项:
L bound = max ( 0 , a − x ) 2 + max ( 0 , x − b ) 2 \begin{aligned} L_{\text{bound}} &= \max(0, a-x)^2 + \max(0, x-b)^2 \end{aligned} Lbound=max(0,a−x)2+max(0,x−b)2
软约束不会绝对禁止越界,只是让越界付出代价。
在最小二乘框架里,正则项通常也可以写成额外残差。比如先验项:
λ ( x − c ) 2 \lambda(x-c)^2 λ(x−c)2
可以写成:
r prior = λ ( x − c ) r_{\text{prior}} = \sqrt{\lambda}(x-c) rprior=λ (x−c)
因为:
r prior 2 = λ ( x − c ) 2 r_{\text{prior}}^2 = \lambda(x-c)^2 rprior2=λ(x−c)2
因此,许多正则项都可以被看作往最小二乘问题里添加新的 residual block。
这也是 BA、图优化、Ceres、g2o、GTSAM 等框架中常见的建模方式:数据项、先验项、平滑项都可以表示成 residual、factor 或 edge。
5. 优化算法:least_squares、SGD 与 Adam
一个优化问题可以拆成两部分:
目标函数是什么 + 用什么算法求解。
例如:
min θ ∑ i r i ( θ ) 2 \min_\theta \sum_i r_i(\theta)^2 θmini∑ri(θ)2
这是一个最小二乘问题。
它可以用 Gauss-Newton、Levenberg-Marquardt、Dogleg、Trust Region 等方法求解,也可以用 SGD 或 Adam 求解。
区别在于,不同算法适合的问题结构不同。
least_squares 通常表示一类求解最小二乘问题的方法或接口,它面向的问题形式是:
min x ∑ i r i ( x ) 2 \min_x \sum_i r_i(x)^2 xmini∑ri(x)2
对于非线性最小二乘,常见方法包括:
- Gauss-Newton;
- Levenberg-Marquardt;
- Dogleg;
- Trust Region;
- Schur Complement;
- PCG。
SGD 和 Adam 则是更通用的梯度优化器。它们不要求目标函数必须是残差平方和,只要损失函数可以计算梯度即可:
θ ← θ − η ∇ θ L ( θ ) \theta \leftarrow \theta - \eta \nabla_\theta L(\theta) θ←θ−η∇θL(θ)
二者可以这样对比:
| 项目 | least_squares 类方法 | SGD / Adam |
|---|---|---|
| 目标形式 | 残差平方和 | 任意可微损失 |
| 是否利用残差结构 | 是 | 通常否 |
| 主要信息 | 残差、雅可比、近似 Hessian | 梯度 |
| 数据使用方式 | 常用全量或局部全量 | 常用 mini-batch |
| 适合场景 | 曲线拟合、BA、图优化 | 深度学习、大规模训练 |
所以:
least_squares 类方法更适合结构明确的最小二乘问题;
SGD / Adam 更适合大规模、mini-batch、复杂网络训练。
6. 为什么深度学习常用 SGD / Adam?
即使用 MSE 作为损失函数,深度学习通常也不会使用传统 least_squares 求解器。
主要原因有三个。
第一,神经网络参数规模太大,可能有几百万、几千万甚至几十亿参数。显式构造残差雅可比矩阵或求解近似 Hessian 系统通常不可行。
第二,深度学习适合 mini-batch 训练。每次只用一小批数据估计梯度,就可以处理海量数据,而不需要每次使用全部样本。
第三,深度学习训练机制更复杂,包括 dropout、batch normalization、数据增强、非凸网络结构以及各种非平方损失。SGD / Adam 更容易和这些机制结合。
因此:
深度学习可以使用最小二乘损失,但通常用 SGD / Adam 优化,而不是传统 least_squares 求解器。
7. 为什么 BA / 图优化适合非线性最小二乘?
BA 和图优化虽然规模也可能很大,但它们的大和深度学习的大不一样。
关键在于:
BA / 图优化具有很强的稀疏结构。
Bundle Adjustment 的目标通常是最小化重投影误差:
min { T i } , { X j } ∑ i , j ∥ u i j − π ( T i , X j ) ∥ 2 \min_{\lbrace T_i\rbrace,\lbrace X_j\rbrace} \sum_{i,j} \left\lVert u_{ij} - \pi(T_i, X_j)\right\rVert^2 {Ti},{Xj}mini,j∑∥uij−π(Ti,Xj)∥2
其中:
- T i T_i Ti 是相机位姿;
- X j X_j Xj 是三维点;
- u i j u_{ij} uij 是图像观测点;
- π ( T i , X j ) \pi(T_i, X_j) π(Ti,Xj) 是投影模型。
这正是非线性最小二乘问题。
BA 的关键特点是:一个观测残差通常只依赖一个相机位姿和一个三维点,而不依赖所有相机和所有点。因此它的雅可比矩阵虽然很大,但大部分元素都是 0。
同时,BA 的变量天然具有块结构:
| 变量 | 常见维度 |
|---|---|
| 相机位姿 | 6 或 7 维 |
| 三维点 | 3 维 |
这种稀疏块结构使得 BA 可以使用 Schur Complement、稀疏线性求解器、PCG 等方法高效求解。
所以,判断一个问题是否适合 least_squares 类方法,不能只看参数数量,还要看:
- 残差数量;
- 雅可比是否稀疏;
- 变量是否有块结构;
- 线性化后的系统能否高效求解。
BA / 图优化虽然也很大,但因为结构清晰、雅可比稀疏,所以非常适合稀疏非线性最小二乘方法。
8. BA / 图优化通常使用专门求解器
BA / 图优化属于 least-squares 问题,但实际中通常不会使用普通通用接口,而是使用专门的图优化或非线性最小二乘库,例如:
- Ceres Solver;
- g2o;
- GTSAM;
- miniSAM。
这些工具通常支持:
- 稀疏块矩阵;
- 李群上的位姿更新;
- 鲁棒核函数;
- Schur Complement;
- 边缘化;
- 先验因子;
- 增量式优化。
因此更准确地说:
BA / 图优化使用的是 least-squares 思想和非线性最小二乘方法,但通常依赖专门的稀疏图优化求解器。
9. 总结
最小二乘是一类以残差平方和为目标的问题形式:
min θ ∑ i r i ( θ ) 2 \min_\theta \sum_i r_i(\theta)^2 θmini∑ri(θ)2
MSE 是残差平方和的平均形式,不改变固定样本数量下的最优解,但更方便比较不同数据集或 mini-batch 的误差水平。
平滑约束、先验约束、软 bounds 等正则项通常通过加权惩罚项加入损失函数;在最小二乘框架里,它们也可以写成额外 residual block。
least_squares 类方法会利用残差、雅可比和问题结构,适合曲线拟合、BA、图优化等结构化最小二乘问题。
SGD / Adam 是更通用的梯度优化器,适合深度学习这种参数巨大、数据巨大、适合 mini-batch 训练的问题。
BA / 图优化虽然规模也可能很大,但由于雅可比稀疏、变量有块结构,仍然非常适合稀疏非线性最小二乘方法。
一句话概括:
最小二乘描述的是"优化什么",正则项描述的是"希望解具有什么性质",而 SGD、Adam、GN、LM 等优化算法描述的是"怎么求解"。