利用eig实现SVD

2024-10-01 22:43:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试使用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方法有什么问题,请告诉我。你知道吗


Tags: 方法图像defnparraysigmalasvd
1条回答
网友
1楼 · 发布于 2024-10-01 22:43:02

奇异值分解和特征向量都不是完全唯一的。在奇异值分解中,只要对V中相应的向量做同样的操作,就可以对U中的任何向量进行符号翻转。得到的特征向量不是以这种方式耦合的,因此很有可能出现符号不匹配。你可以通过使用U。T@A@V.T.公司是sigma,所以检查U的对角线元素的符号。T@A@V.T.公司对于每一个负数,翻转U或V中相应的向量(但不是同时翻转)。你知道吗

其他建议:

因为你只需要对角线元素,所以计算全积U是浪费的。T@A@V.T;只计算对角线元素的最简单方法是np.einsum('ij,ik,jk->j',U,A,V)。你知道吗

使用eigh而不是eig,因为你知道A@A.T.公司和A。T@A公司是对称的。你知道吗

你可以保存一个特征分解,因为西格玛@V=U。T@A公司sigma是对角线很容易颠倒。这还有一个好处,就是上面的符号问题不会发生。你知道吗

相关问题 更多 >

    热门问题