SVD分解理论

##矩阵SVD分解的理论基础

首先,我们先说明什么是矩阵的奇异值分解(single value decomposition),简称SVD。

给定一个矩阵A∈Rm×nA \in R^{m \times n}ARm×n, 设它的秩为r,则它具有以下的分解形式
Am×n=Um×mΣm×nVn×nTA_{m \times n} = U_{m \times m} \Sigma_{m \times n} V_{n \times n}^TAm×n=Um×mΣm×nVn×nT
其中,U是正交矩阵,其列向量是AATAA^TAAT的单位特征向量,V 也是正交矩阵,其列向量是对应的ATAA^TAATA的单位特征向量,Σ\SigmaΣ具有下述的形式
Σ=(Σ1OOO)\Sigma = \left( \begin{array}{cc} \Sigma_1 & O \\ O & O\end{array} \right)Σ=(Σ1OOO)
Σ1=diag(σ1,σ2,…,σr)\Sigma_1 = diag(\sigma_1,\sigma_2,\ldots,\sigma_r)Σ1=diag(σ1,σ2,,σr),r是矩阵A的秩,σi(i=1,2,…,r)\sigma_i(i=1,2,\ldots,r)σi(i=1,2,,r) 是矩阵AATAA^TAAT (或ATAA^TAATA)的非零特征值的正平方根,也叫做A的\textbf{奇异值},当然A还可能包括零奇异值。
在我们知道了什么是SVD后,接下来看一下SVD是怎么来的,在开始之前我们先介绍一下矩阵的四个基本子空间的基本性质。

###四个基本子空间
设矩阵A∈Rm×nA \in R^{m \times n}ARm×n,秩rank(A) = r,
A的行空间 R(AT)R(A^T)R(AT) 为A 的行向量张成集合,
A的列空间 R(A)为A 的列向量的张成集合,
A的的零空间 N(A)为满足Ax = 0 的所有x 组成的集合,
ATA^TAT零空间N(AT)N(A^T)N(AT) 为满足ATy=0A^Ty = 0ATy=0的所有y 组成的集合。
\par 四个基本子空间的维数分别为dim(R(A)) = r,dim(R(AT)R(A^T)R(AT)) = r,dim(N(A)) = n-r,dim(N(AT)N(A^T)N(AT)) = m - r,而且R(A)⊥N(AT)R(A) \perp N(A^T)R(A)N(AT)R(AT)⊥N(A)R(A^T) \perp N(A)R(AT)N(A)

####有关特征值的结论

  • AATAA^TAATATAA^TAATA具有相同的非零特征值,而且所有特征值均大于等于0
  • $A = U \land U^T 为对称矩阵A的特征值分解(对称性保证特征向量正交),为对称矩阵A的特征值分解(对称性保证特征向量正交),A\land$是对角线元素A的特征值的对角矩阵,U的列向量为对应的A的特征向量。
  • rank(A) = r,则ATAA^TAATA的正特征值有r个

##SVD的由来

在矩阵A的行空间,我们选择一组标准正交基v1,v2,…,vrv_1,v_2,\ldots,v_rv1,v2,,vr,经过A 变换,得到列空间的r个元素u1,u2,…,uru_1,u_2,\ldots,u_ru1,u2,,ur,我们希望变换后的u1,u2,…,uru_1,u_2,\ldots,u_ru1,u2,,ur也是正交的,所以我们在行空间选择的标准正交基就不能是任意的,它需要满足使得变换后的u1,u2,…,uru_1,u_2,\ldots,u_ru1,u2,,ur也正交。写成矩阵形式
A[v1,v2,…,vr]=[u1,u2,…,ur]A[v_1,v_2,\ldots,v_r] = [u_1,u_2,\ldots,u_r]A[v1,v2,,vr]=[u1,u2,,ur]
我们把u1,u2,…,uru_1,u_2,\ldots,u_ru1,u2,,ur单位化,设其长度分别为σ1,σ2,…,σr\sigma_1,\sigma_2,\ldots,\sigma_rσ1,σ2,,σr,并记单位化后的向量重新记为u1,u2,…,uru_1,u_2,\ldots,u_ru1,u2,,ur,则
A[v1,v2,…,vr]=[σ1u1,σ2u2,…,σrur]=[u1,u2,…,ur][σ10000σ20000…0000σr]A[v_1,v_2,\ldots,v_r] = [\sigma_1 u_1,\sigma_2 u_2,\ldots,\sigma_r u_r] = [u_1,u_2,\ldots,u_r]\left[ \begin{array}{cccc} \sigma_1 & 0 & 0 & 0 \\ 0 & \sigma_2 & 0 & 0 \\ 0 & 0 & \ldots & 0 \\ 0 & 0 & 0 & \sigma_r \end{array} \right]A[v1,v2,,vr]=[σ1u1,σ2u2,,σrur]=[u1,u2,,ur]σ10000σ200000000σr
我们把零空间也考虑进来,记A的零空间的一组标准正交基vr+1,vr+2,…,vnv_{r+1},v_{r+2},\ldots,v_nvr+1,vr+2,,vnATA^TAT的零空间的一组标准正交基为ur+1,ur+2,…,unu_{r+1},u_{r+2},\ldots,u_nur+1,ur+2,,un,则
A[v1,v2,…,vr,vr+1,vr+2,…,vn]=[σ1u1,σ2u2,…,σrur,0,0,…,0]A[v_1,v_2,\ldots,v_r,v_{r+1},v_{r+2},\ldots,v_n] = [\sigma_1 u_1,\sigma_2 u_2,\ldots,\sigma_r u_r,0,0,\ldots,0] A[v1,v2,,vrvr+1,vr+2,,vn]=[σ1u1,σ2u2,,σrur,0,0,,0]
=[u1,u2,…,ur,ur+1,ur+2,…,um][σ10000σ20000…0000σrO] = [u_1,u_2,\ldots,u_r,u_{r+1},u_{r+2},\ldots,u_m]\left[ \begin{array}{ccccc} \sigma_1 & 0 & 0 & 0 & \quad \\ 0 & \sigma_2 & 0 & 0 & \quad \\ 0 & 0 & \ldots & 0 & \quad \\ 0 & 0 & 0 & \sigma_r & \quad \\ \quad & \quad & \quad & \quad & \textbf{O} \end{array} \right]=[u1,u2,,ur,ur+1,ur+2,,um]σ10000σ200000000σrO
写成矩阵形式如下
KaTeX parse error: Undefined control sequence: \mbox at position 14: AV = U\Sigma,\̲m̲b̲o̲x̲{即,}A = U \Sigm…
什么样的U,V,Σ\SigmaΣ满足上面的要求呢?我们需要解出来。
首先,左乘ATA^TAT,我们得到,
ATA=VΣTUTUΣVT=VΣTΣVTA^TA = V \Sigma^TU^TU\Sigma V^T = V \Sigma^T \Sigma V^T ATA=VΣTUTUΣVT=VΣTΣVT
由对称矩阵的特征值分解,我们可以知道,Σ\SigmaΣ中的σ1,σ2,…,σr\sigma_1,\sigma_2,\ldots,\sigma_rσ1,σ2,,σrATAA^TAATA的非零(即正)特征值的正平方根,也是做A正
奇异值,的正V 的列向量取对应的特征向量。
然后,右乘ATA^TAT,我们得到,
AAT=UΣVTVΣTUT=UΣΣTUTAA^T = U\Sigma V^TV \Sigma^TU^T = U \Sigma \Sigma^T U^T AAT=UΣVTVΣTUT=UΣΣTUT
由对称矩阵的特征值分解,我们可以知道,Σ\SigmaΣ中的σ1,σ2,…,σr\sigma_1,\sigma_2,\ldots,\sigma_rσ1,σ2,,σrAATAA^TAAT的非零(即正)特征值正平方根,U的列向量取对应的特征向量。
由于AATAA^TAATATAA^TAATA具有相同的非零特征值,而且所有特征值均大于等于0,所以上述结论是成立的。

####再看SVD

从上面的推导我们可以看出,

  • V的前r列组成R(AT)R(A^T)R(AT)的标准正交基
  • U的前r列组成R(A)R(A)R(A)的标准正交基
  • V的后n-r列组成N(A)的标准正交基
  • U的后m-r列组成N(AT)N(A^T)N(AT)的标准正交基

我们把矩阵A的SVD展开

\begin{eqnarray*}
A & = & U \Sigma V^T \ & = & [u_1,u_2,\ldots,u_r,u_{r+1},u_{r+2},\ldots,u_m] \left[ \begin{array}{ccccc}
\sigma_1 & 0 & 0 & 0 & \quad \
0 & \sigma_2 & 0 & 0 & \quad \
0 & 0 & \ldots & 0 & \quad \
0 & 0 & 0 & \sigma_r & \quad \
\quad & \quad & \quad & \quad & \textbf{O}
\end{array} \right][v_1,v_2,\ldots,v_r,v_{r+1},v_{r+2},\ldots,v_n]^T \
& = & \sigma_1 u_1v_1^T + \sigma_2 u_1v_1^T + \ldots + \sigma_r u_1v_1^T \
& = & \sum_{i=1}^r \sigma_i u_iv_i^T
\end{eqnarray*}

求矩阵A = (44−33)\left( \begin{array}{cc} 4 & 4 \\ -3 & 3 \end{array} \right)(4343)的奇异值分解。

ATA=(257725)A^TA = \left( \begin{array}{cc} 25 & 7 \\ 7 & 25 \end{array} \right)ATA=(257725),特征值λ1=32,λ2=18,\lambda_1 = 32, \lambda_2 = 18,λ1=32,λ2=18,对应的单位正交向量分别为(1212)\left( \begin{array}{c} \frac{1}{\sqrt{2}} \\ \frac{1}{\sqrt{2}} \end{array} \right)(2121),
(12−12)\left( \begin{array}{c} \frac{1}{\sqrt{2}} \\ \frac{-1}{\sqrt{2}} \end{array} \right)(2121)
所以 V = (121212−12)\left( \begin{array}{cc} \frac{1}{\sqrt{2}} & \frac{1}{\sqrt{2}} \\ \frac{1}{\sqrt{2}} & \frac{-1}{\sqrt{2}} \end{array} \right)(21212121),
Σ=(320018)\Sigma = \left( \begin{array}{cc} \sqrt{32} & 0 \\ 0 & \sqrt{18} \end{array} \right)Σ=(320018).

AV=(8200−62)AV = \left( \begin{array}{cc} \frac{8}{\sqrt{2}} & 0 \\ 0 & \frac{-6}{\sqrt{2}} \end{array} \right)AV=(280026).

因此U=(8213200−62118)=(100−1)U = \left( \begin{array}{cc} \frac{8}{\sqrt{2}}\frac{1}{\sqrt{32}} & 0 \\ 0 & \frac{-6}{\sqrt{2}}\frac{1}{\sqrt{18}} \end{array} \right) = \left( \begin{array}{cc} 1 & 0 \\ 0 & -1 \end{array} \right)U=(283210026181)=(1001)

所以A=(100−1)(320018)(121212−12)A = \left( \begin{array}{cc} 1 & 0 \\ 0 & -1 \end{array} \right)\left( \begin{array}{cc} \sqrt{32} & 0 \\ 0 & \sqrt{18} \end{array} \right)\left( \begin{array}{cc} \frac{1}{\sqrt{2}} & \frac{1}{\sqrt{2}} \\ \frac{1}{\sqrt{2}} & \frac{-1}{\sqrt{2}} \end{array} \right)A=(1001)(320018)(21212121).

OpenCV可用于实现SVD奇异值分解),并利用SVD理论对二维图像矩阵进行分解和重构,主要使用OpenCV第三方视觉库完成SVD应用过程 [^1]。 ### 方法 OpenCV中使用`cv::SVD::compute`函数进行SVD分解,该函数的原型如下: ```cpp static void cv::SVD::compute( InputArray src, OutputArray w, OutputArray u, OutputArray vt, int flags = 0 ); ``` - `src`:输入矩阵,通常为二维图像矩阵。 - `w`:输出奇异值矩阵,是一个一维向量。 - `u`:输出左奇异向量矩阵。 - `vt`:输出右奇异向量矩阵的转置。 - `flags`:操作标志,默认为0。 ### 示例 以下是一个使用OpenCV进行SVD分解和图像重构的示例代码: ```cpp #include <opencv.hpp> using namespace cv; // 参数分别为输入图像,输出图像,压缩比例 void SVDRESTRUCT(const cv::Mat &inputImg, cv::Mat &outputImg, double theratio) { cv::Mat tempt; cv::Mat U, W, V; inputImg.convertTo(tempt, CV_32FC1); cv::SVD::compute(tempt, W, U, V); cv::Mat w = Mat::zeros(Size(W.rows, W.rows), CV_32FC1); int len = theratio * W.rows; for (int i = 0; i < len; ++i) w.ptr<float>(i)[i] = W.ptr<float>(i)[0]; cv::Mat result = U * w * V; result.convertTo(outputImg, CV_8UC1); } int _tmain(int argc, _TCHAR* argv[]) { cv::Mat scrX = imread("1.png", 0); cv::Mat result; SVDRESTRUCT(scrX, result, 0.1); cv::imshow("1", result); waitKey(0); } ``` 上述代码定义了一个`SVDRESTRUCT`函数,用于对输入图像进行SVD分解和重构。在`_tmain`函数中,读取一张灰度图像,调用`SVDRESTRUCT`函数进行处理,并显示重构后的图像 [^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值