Spec-Zone.ru › PyTorch 2

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 (Тензор) – тензор формы (*, m, n) , где * — ноль или более размерностей пакетов.
  • full_matrices (bool, необязательно) – управляет вычислением полного или сокращенного SVD, а следовательно, и формой возвращаемых тензоров U и Vh. По умолчанию: True.
Ключевые аргументы
  • driver (строка, необязательно) – имя метода cuSOLVER, который будет использоваться. Этот ключевой аргумент работает только с входными данными CUDA. Доступные варианты: None, gesvd, gesvdj, и gesvda. По умолчанию: None.
  • out (кортеж, необязательно) – кортеж вывода из трёх тензоров. Игнорируется, если 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/2.1/generated/torch.linalg.svd.html

Spec-Zone.ru

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