使用eig实现SVD

问题描述 投票:0回答:1

我正在尝试使用np.linalg.eig方法来实现SVD进行图像压缩分配。我们不允许直接使用np.linalg.svd方法。

这是我的svd方法:

def svd(A):
    evals, U = LA.eig(A @ A.T)
    evals2, V = LA.eig(A.T @ A)
    idx = evals.argsort()[::-1]
    evals = evals[idx]
    U = U[:, idx]
    idx = evals2.argsort()[::-1]
    V = V[ :, idx]
    sigma = np.array(list(map(math.sqrt, evals)))
    return U, sigma, V.T

但是当我尝试使用上述svd返回的U和V重建图像时,错误率是如此之高,甚至在使用所有奇异矢量后,图像也完全模糊。而当我对np.linalg.svd返回的U&V矩阵尝试相同的重建过程时,我能够清晰地重建图像。

请让我知道我的svd方法是否有问题。

python numpy svd
1个回答
0
投票

SVD和特征向量都不完全唯一。在SVD中,您可以对U中的任何向量进行符号翻转,只要对V中的相应向量进行翻转即可。获得的特征向量不以这种方式耦合,因此,符号失配的可能性很大。您可以通过使用UT @ A @ VT是sigma的事实来进行检查和校正,因此请检查UT @ A @ VT的对角元素的符号,并对每个负数翻转U或V中的对应矢量(但两者都不是。

其他建议:

由于只需要对角线元素,因此计算完整乘积U.T @ A @ V.T是浪费的;仅计算对角线元素的最简单方法是np.einsum('ij,ik,jk->j',U,A,V)

使用eigh而不是eig,因为您知道[email protected]和A.T@A是对称的。

您可以保存一个特征分解,因为sigma @ V = U.T@A并且sigma对角线很容易反转。这还具有不会发生上述标志问题的优点。

© www.soinside.com 2019 - 2024. All rights reserved.