torch.svd 向量计算奇异值分解

这篇博客介绍了PyTorch中的奇异值分解(SVD)函数torch.svd(),包括其功能、参数选项以及如何计算矩阵的SVD。文章强调了some参数对简化和完整分解的影响,以及compute_uv参数是否计算U和V矩阵的选择。还提到了不同平台或库可能产生的U和V矩阵的不唯一性,并警告了在某些情况下梯度计算的不稳定性。最后,通过示例展示了如何使用torch.svd()并验证SVD的正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

torch.svd(input, some=True, compute_uv=True, *, out=None) -> (Tensor, Tensor, Tensor)

计算一个矩阵或一批矩阵 input 的奇异值分解。
奇异值分解表示为namedtuple( U,S,V ),使得 input = U DIAG( S ) Vᴴ ,其中 Vᴴ 是的转置 V 为实数值的输入,或共轭转置 V 为复值输入。如果 input 是一批张量,则 U 、 S 和 V 也使用与 input 相同的批维度进行批处理。

  • 如果 some 为 True (默认),则该方法返回简化的奇异值分解,即,如果 input 的最后两个维度是 m 和 n ,则返回的 U 和 V 矩阵将仅包含 min( n, m ) 正交列。

  • 如果 compute_uv 为 False ,则返回的 U 和 V 将分别是形状为 (m × m) 和 (n × n) 的零填充矩阵,并且与 input 具有相同的设备。当 compute_uv 为 False 时, some 参数无效。

  • 支持 float、double、cfloat 和 cdouble 数据类型的输入。 U 和 V 的 dtypes与 input 的相同。 S 将始终为实值,即使 input 是复数。

Warning

torch.svd() 已弃用。请改用 torch.linalg.svd() ,它类似于 NumPy 的 numpy.linalg.svd 。

Note1

与 torch.linalg.svd() 的区别:

  • some 与 torch.linalg.svd() 的 full_matricies 相反。请注意,两者的默认值都是 True ,因此默认行为实际上是相反的。

  • torch.svd() 返回 V ,而 torch.linalg.svd() 返回 Vᴴ 。

  • 如果 compute_uv=False , torch.svd() 返回 U 和 Vh 的零填充张量,而 torch.linalg.svd() 返回空张量。
    Note

奇异值以降序返回。如果 input 是一批矩阵,则该批中每个矩阵的奇异值将按降序返回。

Note2

CPU 上的 SVD 实现使用 LAPACK 例程 ?gesdd (一种分而治之的算法)而不是 ?gesvd 来提高速度。类似地,GPU 上的 SVD 在CUDA 10.1.243 及更高版本上使用 cuSOLVER 例程 gesvdj 和 gesvdjBatched ,并在早期版本的 CUDA 上使用 MAGMA 例程 gesdd 。

Note3

返回的矩阵 U 将被转置,即步幅为 U.contiguous().transpose(-2, -1).stride() 。

Note4

如果 input 不是满秩或具有非唯一奇异值,则使用 U 和 V 计算的梯度可能不稳定。

Note5

当 some = False 时, U[…, :, min(m, n):] 和 V[…, :, min(m, n):] 和U […,:,min(m,n):]上的梯度将被向后忽略,因为这些向量可以是子空间的任意基数。

Note6

该 S 张量只能用来计算梯度,如果 compute_uv 为True。

Note7

对于复值输入,反向操作仅适用于规范不变损失函数。请查看AD中的仪表问题以获取更多详细信息。

Note8

由于SVD 的 U 和 V 不是唯一的,每个向量可以乘以任意相位因子e^{i \phi} 而 SVD 结果仍然正确。不同的平台,如 Numpy,或不同设备类型的输入,可能会产生不同的 U 和 V 张量。

Parameters

  • input ( Tensor ) – 大小为 (*, m, n) 的输入张量,其中 * 是零个或多个由 (m × n) 矩阵组成的批量维度。
  • some ( bool , optional ) – 控制是计算简化分解还是完全分解,从而控制返回的 U 和 V 的形状。默认为真。
  • compute_uv ( bool , optional ) – 是否计算 U 和 V 的选项。默认为真。
  • 關鍵字參數
    out(元组,可选)–张量的输出元组

Example:

>>> a = torch.randn(5, 3)
>>> a
tensor([[ 0.2364, -0.7752,  0.6372],
        [ 1.7201,  0.7394, -0.0504],
        [-0.3371, -1.0584,  0.5296],
        [ 0.3550, -0.4022,  1.5569],
        [ 0.2445, -0.0158,  1.1414]])
>>> u, s, v = torch.svd(a)
>>> u
tensor([[ 0.4027,  0.0287,  0.5434],
        [-0.1946,  0.8833,  0.3679],
        [ 0.4296, -0.2890,  0.5261],
        [ 0.6604,  0.2717, -0.2618],
        [ 0.4234,  0.2481, -0.4733]])
>>> s
tensor([2.3289, 2.0315, 0.7806])
>>> v
tensor([[-0.0199,  0.8766,  0.4809],
        [-0.5080,  0.4054, -0.7600],
        [ 0.8611,  0.2594, -0.4373]])
>>> torch.dist(a, torch.mm(torch.mm(u, torch.diag(s)), v.t()))
tensor(8.6531e-07)
>>> a_big = torch.randn(7, 5, 3)
>>> u, s, v = torch.svd(a_big)
>>> torch.dist(a_big, torch.matmul(torch.matmul(u, torch.diag_embed(s)), v.transpose(-2, -1)))
tensor(2.6503e-06)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值