使用U,S, VT = torch.linalg.svd(M),矩阵'M'很大,因此我得到矩阵U和VT是非正交的。当我计算火炬。规范(火炬。mm(matrix, matrix. T ()) - identity_matrix))是0.004,而且当我打印mm ^T时,对角线项不是1,而是0.2或0.4,非对角线项不是0,而是0.0023。是否有一种方法可以得到U和V^T正交的SVD ?但是奇异值,即S的对角元素只能小于1。
matrix = torch.randn(4096, 4096)
u, s, vh = torch.linalg.svd(matrix)
matrix = torch.mm(u, vh)
print('norm ||WTW - I||: ',torch.norm(torch.mm(matrix, matrix.t()) - torch.eye(matrix.shape[0])))
print(matrix)
我做了一些数值分析,似乎Pytorch的linalg_svd没有返回正交的u和vh。其他人能证实这种行为是与他人还是我做错了什么?
Matlab:我尝试在matlab中内置svd分解,那里是norm(u*transpose(u) - eye(4096))
,那里是1E-13。
为什么你期望matrix @ matrix.T
接近I
?
SVD
是输入矩阵matrix
的分解。它不改变它,它只产生三个矩阵u
,s
和vh
s.tmatrix = u @ s @ vh
。SVD
的特殊之处在于矩阵u
、s
和vh
不是任意的,而是唯一的:u
和v
是正交的,s
是对角的。
你应该期望的是:
matrix = torch.randn(4096, 4096)
u, s, vh = torch.linalg.svd(matrix)
print(f'||uuT - I|| = {torch.norm(u@u.t() - torch.eye(u.shape[0]))}')
print(f'||vvT - I|| = {torch.norm(vh.t()@vh - torch.eye(vh.shape[0]))}')
请注意,由于数字问题,差异||uuT -I||
不太可能完全为零,而是一些小数字,这取决于矩阵的维度(矩阵越大,误差越大),以及您使用的dtype
的精度:float32
(又名single
)与float64
(又名double
)相比可能会产生更大的误差。
PS,运算符@
代表矩阵乘法。