前面一章讨论随机矩阵乘法时,我们把一个矩阵乘法拆成很多 rank-one terms 的总和:
AB=j=1∑najbj⊤
这种写法的重点是:大矩阵可以拆分为单独处理的小结构。随机算法利用这些小结构做抽样估计,而这一章要讨论的是另一个方向:如果一个大矩阵只发生了 rank-one 或 low-rank 的变化,那么能不能不重新求完整的逆矩阵?
答案就是 Sherman-Morrison formula 和 Woodbury formula。
它们背后的直觉是:
大矩阵的低秩更新⟶小矩阵的求逆或少量线性方程求解
这种思想会自然连接到 Recursive Least Squares,也就是 递归最小二乘;如果再往前走一步,则能看到它和 Kalman filter 的关系。
Rank-one 更新的逆
先从最简单的形式开始。设
u,v∈Rn
那么
uv⊤
是一个 n×n 矩阵,但它的 rank 最多只有 1。因为它把任意向量 x 变成
uv⊤x=u(v⊤x)
也就是说,输出结果永远落在 u 张成的一维方向上。
现在考虑
I−uv⊤
它看起来是一个完整的 n×n 矩阵,但实际上只是单位矩阵被一个 rank-one 矩阵修正了一下。
Sherman-Morrison formula 给出它的逆可以直接由下列表达式计算:
(I−uv⊤)−1=I+1−v⊤uuv⊤
前提是
1−v⊤u=0
这里最容易让人奇怪的地方是分母,为什么会出现
1−v⊤u
而不是别的东西?
关键在于 v⊤u 是一个标量:
v⊤u∈R
所以当两个 rank-one 矩阵连续相乘时,中间那一段可以被压缩成一个普通数:
uv⊤uv⊤=u(v⊤u)v⊤=(v⊤u)uv⊤
这就是整个公式能化简的核心,我们直接验证一下,将 I−uv⊤ 和它的逆 I+1−v⊤uuv⊤ 相乘,看看能否得到单位矩阵:
(I−uv⊤)(I+1−v⊤uuv⊤)=I+1−v⊤uuv⊤−uv⊤−1−v⊤uuv⊤uv⊤=I+1−v⊤uuv⊤−uv⊤−1−v⊤u(v⊤u)uv⊤
为了把最后三项看得更清楚,先记
a=v⊤u
于是上面的式子可以写成
I+1−auv⊤−uv⊤−1−aauv⊤=I+(1−a1−1−1−aa)uv⊤
现在只需要检查括号里的标量系数:
1−a1−1−1−aa=1−a1−a−1=1−1=0
也就是说,所有带有 uv⊤ 的项正好相互抵消,所以最后只剩下
I
这说明上面的式子确实是 (I−uv⊤)−1。
从这个验证过程可以看出,分母来自 rank-one 矩阵反复相乘以后,唯一留下来的那个标量反馈:
v⊤u
从 Sherman-Morrison 到 Woodbury
如果不是 rank-one 更新,而是 rank-k 更新,就把两个向量换成两个矩阵:
U,V∈Rn×k
于是
UV⊤∈Rn×n
但它的 rank 最多只有 k。当 k≪n 时,它仍然是一个低秩扰动。
对应的公式是
(I−UV⊤)−1=I+U(Ik−V⊤U)−1V⊤
这里默认小矩阵 Ik−V⊤U 可逆,否则右侧的逆不存在。
这可以看成 Sherman-Morrison 的 rank-k 版本。原来 rank-one 公式里的标量
1−v⊤u
现在变成了一个 k×k 小矩阵:
Ik−V⊤U
这就是低秩更新真正节省的地方。左边要求的是一个 n×n 矩阵的逆,而右边真正新增的求逆只是
(Ik−V⊤U)−1
如果 k≪n,这比重新处理一个大矩阵便宜得多。
更一般地,如果被更新的不是单位矩阵,而是一个可逆矩阵 A,则有
(A−UV⊤)−1=A−1+A−1U(Ik−V⊤A−1U)−1V⊤A−1
这里同样默认 Ik−V⊤A−1U 可逆。
这就是 Woodbury formula 的一种常见形式。
这里要特别注意:Woodbury formula 不是说我们完全不需要知道 A−1。它更准确的意思是:如果 A 的分解已经可用,或者至少我们已经有办法高效求解
Ax=b
那么当 A 被低秩扰动以后,就不必从头处理新的大矩阵。
这里的重点在于 矩阵分解可以复用。
例如如果已经做过 LU decomposition
A=LU
那么求解
Ax=b
会变成两步:
Ly=b
Ux=y
第一步是 forward substitution,第二步是 back substitution。真正昂贵的是得到 L 和 U 的分解过程,但是分解只需要进行一次;一旦分解已经有了,后面如果只是右端项从 b 换成另一个向量 c,就不需要重新分解 A,只需要再做一次代入求解:
Ly=c
Ux=y
如果 A 是 symmetric positive definite matrix,也可以用 Cholesky decomposition
A=LL⊤
道理一样:分解一次,之后面对不同右端项,只做三角系统的代入求解。
三角系统之所以容易解,是因为它的未知量之间有天然顺序。比如上三角系统
Ux=y
可以写成
u110⋮0u12u22⋮0⋯⋯⋱⋯u1nu2n⋮unnx1x2⋮xn=y1y2⋮yn
展开后最后一行只含有最后一个未知量:
unnxn=yn
所以可以先得到
xn=unnyn
倒数第二行只含有 xn−1 和已经求出的 xn,于是可以继续求出 xn−1。一直往上代回去,就能依次得到
xn−2,xn−3,…,x1
这就是 back substitution。
下三角系统
Ly=b
可以写成
ℓ11ℓ21⋮ℓn10ℓ22⋮ℓn2⋯⋯⋱⋯00⋮ℓnny1y2⋮yn=b1b2⋮bn
则刚好相反,第一行只含有第一个未知量,所以可以从 y1 开始一路向下求到 yn,这叫 forward substitution。
因此三角系统不需要重新做 Gaussian elimination。对于一个 n×n 三角矩阵,代入求解的代价大约是
O(n2)
而完整分解一个一般稠密矩阵通常需要大约
O(n3)
所以当同一个矩阵 A 要面对很多不同右端项时,先分解一次,再反复做三角回代,会比每次从头求解便宜很多。
所以在数值计算里,表达式
A−1b
通常不应该理解成“先显式形成 A−1,再乘 b”,而应该理解成:
用已经分解好的 A 去解 Ax=b
有了这个结论以后,我们再来看 Woodbury。原公式是
(A−UV⊤)−1=A−1+A−1U(Ik−V⊤A−1U)−1V⊤A−1
如果我们真正关心的是解线性方程
(A−UV⊤)x=b
也就是计算
x=(A−UV⊤)−1b
那么只要把 Woodbury 公式右边整体乘上 b:
x=(A−UV⊤)−1b=A−1b+A−1U(Ik−V⊤A−1U)−1V⊤A−1b
这一步只是公式代入,但它暴露出实际需要计算的对象:
A−1b,A−1U,(Ik−V⊤A−1U)−1
它们看起来写着 A−1,但根据我们前面介绍矩阵分解的结论,实际计算时不应该显式形成 A−1。按照前面矩阵分解的观点,A−1b 的意思就是解
Az=b
并把结果记作
z=A−1b
同理,A−1U 的意思就是解
AW=U
并把结果记作
W=A−1U
这里 U 有 k 列,所以 AW=U 可以理解成同时解 k 个右端项。由于 A 没变,这些求解都可以 复用 同一个 矩阵分解,只是更换右端项并做回代。
把
z=A−1b,W=A−1U
代回上面的式子,得到
x=z+W(Ik−V⊤W)−1V⊤z
现在再把小矩阵和小向量单独记出来:
S=Ik−V⊤W,y=V⊤z
那么上面的公式可以写成
x=z+WS−1y
这里的 S−1y 仍然不应该理解成先显式求出 S−1。它和前面的 A−1b 是同一种思想:要求的是逆矩阵作用在一个右端项上的结果。
所以令
t=S−1y
等价于解一个 k×k 小系统
St=y
这个小系统同样可以通过矩阵分解来解。只是这里的矩阵大小是 k×k,而不是 n×n;当 k≪n 时,这个分解和回代都比重新处理大矩阵便宜得多。
最后得到
x=z+Wt
这套流程里,大矩阵 A 的部分只是反复更换右端项,然后用已有分解回代。真正新出现的求解问题只有一个 k×k 的小系统。
所以我们并不
显式更新整个逆矩阵
而是
复用旧矩阵的分解,快速得到低秩更新后的新解
Rank-one 情况:Woodbury 退化为 Sherman-Morrison
上面讨论的是 rank-k 更新:
A−UV⊤
如果 k=1,那么 U 和 V 就各自只有一列。把它们写成向量
U=u,V=v
于是 low-rank update 就变成 rank-one update:
A−uv⊤
这时 Woodbury formula 会退化成 Sherman-Morrison formula。换句话说,Sherman-Morrison 是 Woodbury 在 k=1 时的特殊情况。
从这个角度也能解释为什么有时不直接写逆矩阵,而是直接讨论线性方程,rank-one 情况下,新的方程是
(A−uv⊤)x=b
这和 Woodbury 是同一件事
假设旧问题已经通过 A 的分解解过:
Aw=b
得到
w=A−1b
这里依旧不会显式形成 A−1,而是用已有分解回代得到 w。再额外更换右端项,解一个辅助问题:
Az=u
也就是
z=A−1u
这里同样不需要显式形成 A−1,只是复用 A 的分解,把右端项换成 u。
现在把新方程改写。因为
u=Az
并且
b=Aw
所以
(A−uv⊤)x(A−Azv⊤)xA(I−zv⊤)x=b=Aw=Aw
如果 A 可逆,两边消去 A,得到
(I−zv⊤)x=w
这就回到了最开始的 Sherman-Morrison 形式。也就是
(I−zv⊤)−1=I+1−v⊤zzv⊤
因此
x=(I−zv⊤)−1w
代入 rank-one 公式:
x=(I+1−v⊤zzv⊤)w=w+1−v⊤zzv⊤w=w+z1−v⊤zv⊤w
所以得到
x=w+z1−v⊤zv⊤w
这说明两种说法完全一致:
更新逆矩阵⟺更新线性方程的解
但在实际计算中,后者通常更重要。因为我们很多时候并不真的需要整个
(A−uv⊤)−1
而只需要它作用在 b 上的结果。
递归最小二乘
现在把这个思想应用到 least squares。
假设旧的 least squares 问题已经求解出来了:
Ax≈b
它的 normal equation 是
A⊤Ax^=A⊤b
也就是说,我们已经有了旧估计 x^old,并且旧的 normal matrix
A⊤A
的逆,或者它的分解,也已经可以复用。
这里默认 A 满列秩,因此 normal matrix A⊤A 可逆;实际 RLS 里也常通过初始协方差或正则化项保证这个逆稳定存在。
现在问题变成:如果此时新来了一条观测
v⊤x≈bnew
我们当然可以把它加入原数据,再从头求一次 least squares。但如果数据是一条一条来的,这样每次都重新构造 normal equation、重新分解矩阵,会很浪费。
RLS 想做的是:不从头重算,而是在旧解的基础上,用这条新观测做一次递归更新。
把新观测放进原数据,相当于在原来的数据矩阵下面增加一行:
Anew=[Av⊤],bnew all=[bbnew]
新的 normal matrix 是
Anew⊤Anew=[A⊤v][Av⊤]=A⊤A+vv⊤
右端项也变成
Anew⊤bnew all=[A⊤v][bbnew]=A⊤b+vbnew
所以新问题满足
(A⊤A+vv⊤)x^new=A⊤b+vbnew
这里的关键是
A⊤A⟶A⊤A+vv⊤
只是一个 rank-one update。
如果令
P=(A⊤A)−1
那么新增一条观测后,新的逆 normal matrix 是
Pnew=(A⊤A+vv⊤)−1
对
M=A⊤A
使用 Sherman-Morrison 的加号版本:
(M+vv⊤)−1=M−1−1+v⊤M−1vM−1vv⊤M−1
代入 P=M−1,得到
Pnew=P−1+v⊤PvPvv⊤P
这说明新逆矩阵可以从旧的 P 直接更新出来,而不是重新求
(Anew⊤Anew)−1
和前面讨论线性方程时一样,实际计算里也可以把这里的“乘以逆矩阵”理解成:复用旧 normal matrix 的分解,或者更新已有分解,然后通过解线性系统得到需要的结果,而不是显式形成完整逆矩阵。
为了把这个公式和估计量更新联系起来,先定义
K=1+v⊤PvPv
这个 K 叫 gain。它来自 Sherman-Morrison 公式里的低秩修正项。
因为
K=1+v⊤PvPv
所以 Pnew 的更新式也可以写成
Pnew=P−Kv⊤P
旧估计满足
x^old=PA⊤b
原因是旧 normal equation 为
A⊤Ax^old=A⊤b
两边左乘
P=(A⊤A)−1
就得到上面的式子。
而新估计是
x^new=Pnew(A⊤b+vbnew)
原因也一样:新 normal equation 为
(A⊤A+vv⊤)x^new=A⊤b+vbnew
两边左乘新的逆 normal matrix
Pnew=(A⊤A+vv⊤)−1
就得到新估计的表达式。
现在把 Pnew=P−Kv⊤P 代入:
x^new=(P−Kv⊤P)(A⊤b+vbnew)=PA⊤b+Pvbnew−Kv⊤PA⊤b−Kv⊤Pvbnew
现在先把能认出来的旧估计替换掉。因为
PA⊤b=x^old
所以
v⊤PA⊤b=v⊤x^old
代回展开式:
x^new=x^old−Kv⊤x^old+(Pv−Kv⊤Pv)bnew
现在只剩下括号里的系数需要处理。令
α=v⊤Pv
因为
K=1+αPv
所以有
Pv=(1+α)K
因此括号里的系数变成
Pv−Kv⊤Pv=(1+α)K−αK=K
于是
x^new=x^old−Kv⊤x^old+Kbnew=x^old+K(bnew−v⊤x^old)
这就得到 RLS 的核心形式:
x^new=x^old+K(bnew−v⊤x^old)
这里
bnew−v⊤x^old
叫 residual,也常叫 innovation。它表示“新观测”和“旧估计对这条观测的预测”之间差了多少。
而 K 控制这次 residual 应该怎样修正当前估计。
所以 RLS 的直觉形式是
新估计=旧估计+gain×新观测误差
这个形式非常重要。它说明 recursive least squares 并不是每来一条新数据就从头解一次 least squares,而是保存旧的信息,再根据新观测做一次低秩修正。
和 Kalman Filter 的关系
Kalman filter 可以看成 RLS 思想的进一步推广,但它估计的对象不再是固定参数,而是随时间变化的状态。
RLS 的典型目标是一个固定的未知向量:
x
每来一条观测,就把对 x 的估计更新一下。
Kalman filter 的目标是一个动态状态:
xt
例如位置、速度、姿态,或者某个系统在时刻 t 的隐藏状态。它会先根据模型预测当前状态,再用新观测修正这个预测。
只看更新部分,Kalman filter 的核心形式是
xt+=xt−+Kt(yt−Htxt−)
这里 xt− 是观测到来前的预测,xt+ 是观测修正后的估计。
观测模型通常写成
yt≈Htxt
所以
yt−Htxt−
就是新观测和旧预测之间的差,也就是 Kalman filter 里的 innovation。
对应的 gain 是
Kt=Pt−Ht⊤(HtPt−Ht⊤+R)−1
这和 RLS 的 gain 在结构上很像。它们都在做同一件事情:
根据不确定性决定这次新信息应该被相信多少
如果旧估计很不确定,或者新观测很可靠,那么 gain 会让新观测产生更大的修正;如果旧估计已经很可靠,或者新观测噪声很大,那么修正就会比较小。
更深一层看,Kalman filter 的测量更新也可以理解成一个加权 least squares 问题:
xmin∥x−xt−∥(Pt−)−12+∥yt−Htx∥R−12
第一项表示不要离原来的预测太远,第二项表示要解释新的观测。两项的权重由协方差控制。
对应的 normal matrix 会出现
(Pt−)−1+Ht⊤R−1Ht
如果观测维度远小于状态维度,那么
Ht⊤R−1Ht
就是一种低维观测带来的低秩或低维更新。Woodbury formula 可以把状态维度上的大矩阵求逆,转化成观测维度上的小矩阵求逆:
(HtPt−Ht⊤+R)−1
这就是 Kalman gain 里那个小矩阵逆出现的原因之一。
因此这条线可以总结为:
Woodbury→RLS→Kalman filter
它们共同的结构是一种反复出现的模式:
旧信息+低秩新信息⟹用小系统更新结果
总结
这一章的主线是:当矩阵只发生低秩变化时,不要急着重新求完整逆矩阵。
rank-one 情况下,Sherman-Morrison formula 把
(I−uv⊤)−1
写成一个单位矩阵加 rank-one 修正:
(I−uv⊤)−1=I+1−v⊤uuv⊤
rank-k 情况下,Woodbury formula 把 n×n 的大矩阵逆,转化成 k×k 的小矩阵逆:
(A−UV⊤)−1=A−1+A−1U(Ik−V⊤A−1U)−1V⊤A−1
但在数值计算中,更应该把它理解成复用 A 的矩阵分解:当右端项改变时,只需要做 forward substitution 和 back substitution,而不是显式构造 A−1。
在 least squares 里,每新增一条观测,normal matrix 发生 rank-one update:
A⊤A⟶A⊤A+vv⊤
于是 RLS 可以递归更新解:
x^new=x^old+K(bnew−v⊤x^old)
Kalman filter 则把这个结构推广到动态状态估计:
xt+=xt−+Kt(yt−Htxt−)
所以从 Woodbury 到 RLS,再到 Kalman filter,核心思想一直没有变:
不要从头重算;利用旧信息,用低秩更新吸收新信息