我根据Ian Goodfellow and co。的“深度学习书”第45页编写了以下函数来执行SVD。
def SVD(A):
#A^T
AT = np.transpose(A)
#AA^T
AAT = A.dot(AT)
#A^TA
ATA = AT.dot(A)
#Left single values
LSV = np.linalg.eig(AAT)[1]
U = LSV #some values of U have the wrong sign
#Right single values
RSV = np.linalg.eig(ATA)[1]
V = RSV
V[:,0] = V[:,0] #V isnt arranged properly
values = np.sqrt(np.linalg.eig(ata)[0])
#descending order
values = np.sort(values)[::-1]
rows = A.shape[0]
columns = A.shape[1]
D = np.zeros((rows,columns))
np.fill_diagonal(D,values)
return U, D, V
但是对于任何给定的矩阵,结果与使用的结果不同
np.linalg.svd(A)
我不知道为什么。
我通过说来测试了我的算法
abs(UDV^T - A) < 0.0001
检查其是否正确分解。问题似乎出在V和U组件上,但我看不到出了什么问题。 D似乎是正确的。
如果任何人都能看到问题,将不胜感激。
答案 0 :(得分:0)
我认为您对eig(ATA)和eig(AAT)返回的特征对的顺序有疑问。 np.linalg.eig的文档告诉我们,不能保证任何订单。用eigh替换eig,这将以升序返回特征对。另外,请勿重新排列值。
顺便说一句,eigh是对称矩阵(例如您要传递的矩阵)所特有的,如果原始矩阵是实数,则不会返回复数。