使用torch.det计算奇异矩阵行列式未返回0值的问题咨询
问题原因
- 该现象既不是操作错误也不是
torch.det的函数缺陷,属于32位浮点数(float32)数值计算的固有舍入误差。PyTorch中.float()默认对应float32精度,行列式计算底层依赖LU分解等数值算法,计算过程中多步浮点运算的舍入误差会累积,导致理论上行列式为0的奇异矩阵输出极小的非零值,量级通常在1e-6到1e-5区间,和观测到的1.2517e-06完全吻合。 - 第一个2×2测试用例结构简单,计算路径的误差刚好可以被抵消,因此得到了精确的0值;3×3矩阵的计算步骤更多,误差累积后就出现了可观测的极小非零输出。
解决方法
- 方案1:提升计算精度,改用float64(双精度)进行计算,可将误差量级降低到1e-12以下,多数场景下可近似视为0:
import torch a = torch.tensor([2, -1, 1], dtype=torch.float64) b = torch.tensor([3, -4, -2], dtype=torch.float64) c = torch.tensor([5, -10, -8], dtype=torch.float64) d = torch.stack([a,b,c], dim = 1) print(torch.det(d)) # 输出量级通常为1e-16,可直接判定为0
- 方案2:业务逻辑中判断矩阵是否奇异时,不要直接使用
det == 0的判据,设置适配精度的容差阈值即可:
det_val = torch.det(d) # float32场景使用1e-5作为阈值,float64场景可调整为1e-10 is_singular = torch.abs(det_val) < 1e-5
- 方案3:如果仅需要判断矩阵是否奇异,相比计算行列式更推荐使用矩阵秩计算,可直接指定容差参数,结果更稳定:
# atol参数对应容差,和浮点精度匹配即可 rank = torch.linalg.matrix_rank(d, atol=1e-5) is_singular = rank < d.shape[0]
内容的提问来源于stack exchange,提问作者Penguin
相关产品推荐
相关产品推荐

