快捷方式

torch.linalg.svd

torch.linalg.svd(A, full_matrices=True, *, driver=None, out=None)

計算矩陣的奇異值分解 (SVD)。

K\mathbb{K}R\mathbb{R}C\mathbb{C},矩陣 AKm×nA \in \mathbb{K}^{m \times n}完全 SVD,如果 k = min(m,n),定義為:

A=Udiag(S)VHUKm×m,SRk,VKn×nA = U \operatorname{diag}(S) V^{\text{H}} \mathrlap{\qquad U \in \mathbb{K}^{m \times m}, S \in \mathbb{R}^k, V \in \mathbb{K}^{n \times n}}

其中 diag(S)Km×n\operatorname{diag}(S) \in \mathbb{K}^{m \times n}VHV^{\text{H}}VV 為複數時是共軛轉置,在 VV 為實數時是轉置。矩陣 UUVV (以及 VHV^{\text{H}}) 在實數情況下是正交矩陣,在複數情況下是酉矩陣。

m > n (或 m < n) 時,我們可以丟棄 U 的後 m - n 列 (或 V 的後 n - m 列),形成 簡化 SVD

A=Udiag(S)VHUKm×k,SRk,VKn×kA = U \operatorname{diag}(S) V^{\text{H}} \mathrlap{\qquad U \in \mathbb{K}^{m \times k}, S \in \mathbb{R}^k, V \in \mathbb{K}^{n \times k}}

其中 diag(S)Kk×k\operatorname{diag}(S) \in \mathbb{K}^{k \times k}。在這種情況下,UUVV 也具有標準正交列。

支援 float、double、cfloat 和 cdouble dtypes 輸入。也支援批次矩陣輸入,如果 A 是一個批次矩陣,則輸出具有相同的批次維度。

返回的分解是一個命名元組 (U, S, Vh),分別對應於上面的 UUSSVHV^{\text{H}}

奇異值按降序返回。

引數 full_matrices 選擇完全 (預設) SVD 或簡化 SVD。

driver 關鍵字引數可用於 CUDA,使用 cuSOLVER 後端選擇計算 SVD 的演算法。驅動的選擇是在精度和速度之間權衡。

  • 如果 A 條件良好 (其條件數 不太大),或者您不介意一些精度損失。

    • 對於一般矩陣:‘gesvdj’ (Jacobi 方法)

    • 如果 A 是高或寬矩陣 (m >> nm << n):‘gesvda’ (近似方法)

  • 如果 A 條件不好或精度要求高:‘gesvd’ (基於 QR)

預設情況下 (driver= None),我們呼叫 ‘gesvdj’,如果失敗,則回退到 ‘gesvd’

numpy.linalg.svd 的差異

  • numpy.linalg.svd 不同,此函式始終返回一個包含三個張量的元組,並且不支援 compute_uv 引數。請使用 torch.linalg.svdvals() (僅計算奇異值) 代替 compute_uv=False

注意

full_matrices= True 時,將忽略相對於 U[…, :, min(m, n):]Vh[…, min(m, n):, :] 的梯度,因為這些向量可以是相應子空間的任意基。

警告

返回的張量 UV 不是唯一的,也不是關於 A 連續的。由於這種非唯一性,不同的硬體和軟體可能會計算出不同的奇異向量。

這種非唯一性是由於以下事實造成的:在實數情況下,將任意一對奇異向量 uk,vku_k, v_k 乘以 -1,或者在複數情況下乘以 eiϕ,ϕRe^{i \phi}, \phi \in \mathbb{R} 會產生另外兩個有效的矩陣奇異向量。因此,損失函式不應依賴於此 eiϕe^{i \phi} 數量,因為它沒有良好定義。當計算此函式的梯度時,對於複數輸入會檢查這一點。因此,當輸入為複數且位於 CUDA 裝置上時,此函式的梯度計算會將該裝置與 CPU 同步。

警告

使用 UVh 計算的梯度只有在 A 沒有重複奇異值時才是有限的。如果 A 是矩形矩陣,則額外要求零也不能是其奇異值之一。此外,如果任意兩個奇異值之間的距離接近於零,則梯度在數值上會不穩定,因為它依賴於透過計算 1minijσi2σj2\frac{1}{\min_{i \neq j} \sigma_i^2 - \sigma_j^2} 中的奇異值 σi\sigma_i。在矩形矩陣的情況下,當 A 具有較小的奇異值時,梯度在數值上也會不穩定,因為它也依賴於計算 1σi\frac{1}{\sigma_i}

另請參閱

torch.linalg.svdvals() 僅計算奇異值。與 torch.linalg.svd() 不同,svdvals() 的梯度始終是數值穩定的。

torch.linalg.eig() 計算矩陣的另一種譜分解。特徵值分解僅適用於方陣。

torch.linalg.eigh() 是一個 (更快地) 函式,用於計算 Hermitian 矩陣和對稱矩陣的特徵值分解。

torch.linalg.qr() 是另一種 (快得多地) 分解,適用於一般矩陣。

引數
  • A (Tensor) – 形狀為 (*, m, n) 的張量,其中 * 表示零個或多個批次維度。

  • full_matrices (bool, optional) – 控制計算完全 SVD 還是約減 SVD,因此也決定了返回張量 UVh 的形狀。預設值: True

關鍵字引數
  • driver (str, optional) – 要使用的 cuSOLVER 方法名稱。此關鍵字引數僅適用於 CUDA 輸入。可用選項為: None, gesvd, gesvdj, 和 gesvda。預設值: None

  • out (tuple, optional) – 包含三個張量的輸出元組。如果為 None 則忽略。預設值: None

返回

一個命名元組 (U, S, Vh),對應於上面提到的 UUSSVHV^{\text{H}}

S 即使當 A 為複數時,也始終是實值。它也將按降序排列。

UVh 將與 A 具有相同的資料型別 (dtype)。左/右奇異向量分別由 U 的列和 Vh 的行給出。

示例

>>> A = torch.randn(5, 3)
>>> U, S, Vh = torch.linalg.svd(A, full_matrices=False)
>>> U.shape, S.shape, Vh.shape
(torch.Size([5, 3]), torch.Size([3]), torch.Size([3, 3]))
>>> torch.dist(A, U @ torch.diag(S) @ Vh)
tensor(1.0486e-06)

>>> U, S, Vh = torch.linalg.svd(A)
>>> U.shape, S.shape, Vh.shape
(torch.Size([5, 5]), torch.Size([3]), torch.Size([3, 3]))
>>> torch.dist(A, U[:, :3] @ torch.diag(S) @ Vh)
tensor(1.0486e-06)

>>> A = torch.randn(7, 5, 3)
>>> U, S, Vh = torch.linalg.svd(A, full_matrices=False)
>>> torch.dist(A, U @ torch.diag_embed(S) @ Vh)
tensor(3.0957e-06)

文件

訪問 PyTorch 全面的開發者文件

檢視文件

教程

獲取面向初學者和高階開發者的深度教程

檢視教程

資源

查詢開發資源並獲取問題解答

檢視資源