Spec-Zone.ru › PyTorch 1

torch.linalg.svd

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

Вычисляет сингулярное разложение (SVD) матрицы.

Пусть K\mathbb{K} — R\mathbb{R} или C\mathbb{C}, полное сингулярное разложение матрицы A∈Km×nA \in \mathbb{K}^{m \times n}, если k = min(m,n), определяется как

A=Udiag⁡(S)VHU∈Km×m,S∈Rk,V∈Kn×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 вещественный. Матрицы UU, VV (и, следовательно, VHV^{\text{H}}) ортогональны в вещественном случае и унитарны в комплексном.

Когда m > n (соответственно m < n) мы можем опустить последние m - n (соответственно n - m) столбцы U (соответственно V) для получения сокращённого сингулярного разложения:

A=Udiag⁡(S)VHU∈Km×k,S∈Rk,V∈Kk×nA = 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}^{k \times n}}

где diag⁡(S)∈Kk×k\operatorname{diag}(S) \in \mathbb{K}^{k \times k}. В этом случае, столбцы UU и VV также ортонормированы.

Поддерживает типы данных float, double, cfloat и cdouble. Также поддерживает пакеты матриц, и если A является пакетом матриц, то вывод имеет те же размерности пакета.

Возвращаемое разложение — именованная кортеж (U, S, Vh) , который соответствует UU, SS, VHV^{\text{H}} выше.

Сингулярные значения возвращаются в порядке убывания.

Параметр full_matrices выбирает между полным (по умолчанию) и сокращённым SVD.

Ключевое слово driver может быть использовано в CUDA с бэкэндом cuSOLVER для выбора алгоритма вычисления SVD. Выбор драйвера — это компромисс между точностью и скоростью.

  • Если A хорошо обусловлена (ее число обусловленности не слишком велико) или вы не возражаете против некоторой потери точности.

    • Для общей матрицы: ‘gesvdj’ (метод Якоби)
    • Если A высокая или узкая (m >> n или m << 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):, :] игнорируются, так как эти векторы могут быть произвольными базисами соответствующих подпространств.

Предупреждение

Возвращаемые тензоры U и V не являются уникальными и не являются непрерывными относительно A. Из-за этого отсутствия уникальности различное аппаратное и программное обеспечение может вычислять различные сингулярные векторы.

Это отсутствие уникальности вызвано тем, что умножение любой пары сингулярных векторов uk,vku_k, v_k на -1 в вещественном случае или на eiϕ,ϕ∈Re^{i \phi}, \phi \in \mathbb{R} в комплексном случае порождает ещё две допустимые сингулярные вектора матрицы. По этой причине функция потерь не должна зависеть от этой величины eiϕe^{i \phi}, так как она не определена однозначно. Это проверяется для комплексных входных данных при вычислении градиентов этой функции. Таким образом, когда входные данные комплексные и находятся на устройстве CUDA, вычисление градиентов этой функции синхронизирует это устройство с процессором.

Предупреждение

Градиенты, вычисленные с помощью U или Vh , будут конечными только тогда, когда A не имеет повторяющихся сингулярных значений. Если A прямоугольная, дополнительно ноль также не должен быть одним из её сингулярных значений. Кроме того, если расстояние между любыми двумя сингулярными значениями близко к нулю, градиент будет численно неустойчивым, так как он зависит от сингулярных значений σi\sigma_i через вычисление 1min⁡i≠jσi2−σj2\frac{1}{\min_{i \neq j} \sigma_i^2 - \sigma_j^2}. В прямоугольном случае градиент также будет численно неустойчивым, когда A имеет малые сингулярные значения, так как он также зависит от вычисления 1σi\frac{1}{\sigma_i}.

См. также

torch.linalg.svdvals() вычисляет только сингулярные значения. В отличие от torch.linalg.svd(), градиенты svdvals() всегда численно устойчивы.

torch.linalg.eig() для функции, которая вычисляет другой тип спектрального разложения матрицы. Собственное разложение работает только с квадратными матрицами.

torch.linalg.eigh() для (более быстрой) функции, которая вычисляет разложение по собственным значениям для эрмитовых и симметричных матриц.

torch.linalg.qr() для другого (гораздо более быстрого) разложения, которое работает с общими матрицами.

Параметры:
  • A (Tensor) – тензор формы (*, m, n) , где * — нулевые или более размерностей пакетных данных.
  • full_matrices (bool, необязательно) – управляет вычислением полного или сокращенного SVD и, следовательно, формой возвращаемых тензоров U и Vh. По умолчанию: True.
Ключевые аргументы:
  • driver (str, необязательно) – имя метода cuSOLVER, который будет использоваться. Этот ключевой аргумент работает только с входными данными CUDA. Доступные варианты: None, gesvd, gesvdj, и gesvda. По умолчанию: None.
  • out (tuple, необязательно) – кортеж выходных тензоров. Игнорируется, если None.
Возвращает:

Именованный кортеж (U, S, Vh) , соответствующий UU, SS, VHV^{\text{H}} выше.

S всегда будет вещественного типа, даже когда A комплексное. Он также будет упорядочен по убыванию.

U и Vh будут иметь тот же тип данных, что и A . Левые/правые сингулярные векторы будут заданы столбцами 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)

© 2024, PyTorch Contributors
PyTorch has a BSD-style license, as found in the LICENSE file.
https://pytorch.org/docs/1.13/generated/torch.linalg.svd.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API