PyTorch中torch.linalg.svd返回U与V^T非正交的问题咨询
问题分析与解决方案
核心问题
你遇到的torch.linalg.svd返回的U/Vh正交性误差过大的问题,主要源于数据类型精度限制和可能的设备/实现差异,而非操作错误。你的测试代码逻辑本身没问题,但默认的float32精度不足以支撑4096×4096矩阵的SVD运算,导致误差累积远超MATLAB的double精度结果。
验证与修复步骤
切换到双精度(double)计算
MATLAB默认使用double(64位浮点数),而PyTorch的torch.randn默认生成float32(32位浮点数)。32位浮点数的机器epsilon约为1e-7,对于高维矩阵,运算误差会被放大。修改代码使用double类型后,正交性误差会显著降低:import torch # 生成双精度随机矩阵 matrix = torch.randn(4096, 4096, dtype=torch.double) u, s, vh = torch.linalg.svd(matrix) # 直接检查U的正交性 u_ortho_error = torch.norm(u @ u.t() - torch.eye(u.shape[0], dtype=torch.double)) print('norm ||U U^T - I||:', u_ortho_error) # 检查Vh的正交性 vh_ortho_error = torch.norm(vh @ vh.t() - torch.eye(vh.shape[0], dtype=torch.double)) print('norm ||Vh Vh^T - I||:', vh_ortho_error)运行后误差会降到
1e-10量级,接近MATLAB的结果。检查设备差异
如果在GPU上运行,CUDA的CuSOLVER库在float32下的SVD精度可能略低于CPU的LAPACK实现。若必须使用单精度,可尝试切换到CPU运行,或升级PyTorch到最新版本(优化了CUDA SVD的精度)。避免间接误差累积
你的原代码中通过matrix = torch.mm(u, vh)间接计算正交性,会引入额外的矩阵乘法误差。直接检查u @ u.t()和vh @ vh.t()的误差,能更准确反映SVD的正交性结果。
补充说明
- PyTorch的
torch.linalg.svd默认参数full_matrices=True,返回的U和Vh在理论上是正交矩阵,误差仅来自数值计算精度。 - 高维矩阵的数值运算误差是正常现象,选择合适的精度类型是平衡性能与精度的关键。
内容的提问来源于stack exchange,提问作者Bhartendu Kumar
相关产品推荐
相关产品推荐

