Содержание курса 02 / 33

02 / 33 · Основы

Многомерные гауссовские распределения

Вектор средних, ковариационная матрица, двумерная плотность и сэмплирование любой гауссианы из стандартного шума с помощью квадратного корня из матрицы, а также параметризация в PyTorch, которая используется в первых экспериментах по подгонке распределений.

На этой странице 7

Генеративная модель — это распределение, из которого можно сэмплировать и, в идеале, вычислять его плотность (Что такое генеративное моделирование). Пока нейронные сети не появились, курс работает с простейшим распределением, которое остаётся интересным в нескольких измерениях: многомерным гауссовским (multivariate Gaussian). Оно служит сквозным примером первых заметок и выступает там в двух ролях: это и цель, из которой мы берём данные, и модель, которую мы под эти данные подгоняем. Оно же возвращается почти в каждой следующей модели: априорное распределение VAE, шум диффузионной модели, базовое распределение нормализующего потока (normalizing flow) и статистики признаков, на которых построен FID.

Вводный блок курса состоит из трёх шагов:

  1. сгенерировать данные из известного распределения (эта заметка);
  2. измерить, насколько далеки друг от друга два распределения (Энтропия, кросс-энтропия и KL-дивергенция);
  3. подогнать параметризованное двумерное распределение к данным градиентным спуском по такому расстоянию (Подгонка распределений с помощью KL).

Обозначения. Заглавные буквы, например XX и ZZ, обозначают случайные векторы; полужирные строчные, например x\mathbf x и z\mathbf z, — точки плоскости, то есть значения, которые эти векторы принимают. Полужирные заглавные, например Σ\boldsymbol\Sigma, A\mathbf A и L\mathbf L, — матрицы, I\mathbf I — единичная матрица, A⊤\mathbf A^{\top} — транспонированная матрица, ∣Σ∣|\boldsymbol\Sigma| — определитель. Запись X∼N(μ,σ2)X \sim \mathcal N(\mu, \sigma^2) означает одномерное нормальное распределение со средним μ\mu и дисперсией σ2\sigma^2, а X∼N(μ,Σ)X \sim \mathcal N(\boldsymbol\mu, \boldsymbol\Sigma) — многомерное нормальное распределение с вектором средних μ\boldsymbol\mu и ковариационной матрицей Σ\boldsymbol\Sigma: второй аргумент — всегда дисперсия или ковариация, а не стандартное отклонение. Плотности обозначаются pp и qq; начиная с раздела про PyTorch, PP — фиксированное целевое распределение с плотностью pp, а QQ — обучаемая модель с плотностью qq.

Ковариационная матрица#

Возьмём случайный вектор-столбец в двух измерениях и его среднее:

X=(X1X2),μ=E[X]=(μ1μ2).X = \begin{pmatrix} X_1 \\ X_2 \end{pmatrix}, \qquad \boldsymbol{\mu} = \mathbb E[X] = \begin{pmatrix} \mu_{1} \\ \mu_{2} \end{pmatrix}.

Его разброс описывает матрица дисперсий и ковариаций размера 2×22 \times 2, Σ=E[(X−μ)(X−μ)⊤]\boldsymbol\Sigma = \mathbb E\bigl[(X-\boldsymbol\mu)(X-\boldsymbol\mu)^{\top}\bigr]:

Σ=(Var⁡(X1)Cov⁡(X1,X2)Cov⁡(X1,X2)Var⁡(X2))=(σ12ρ σ1σ2ρ σ1σ2σ22),\begin{aligned} \boldsymbol{\Sigma} &= \begin{pmatrix} \operatorname{Var}(X_1) & \operatorname{Cov}(X_1, X_2) \\ \operatorname{Cov}(X_1, X_2) & \operatorname{Var}(X_2) \end{pmatrix} \\[4pt] &= \begin{pmatrix} \sigma_{1}^2 & \rho\,\sigma_{1}\sigma_{2} \\ \rho\,\sigma_{1}\sigma_{2} & \sigma_{2}^2 \end{pmatrix}, \end{aligned}

где ρ\rho — коэффициент корреляции между X1X_1 и X2X_2. Матрица симметрична, потому что Cov⁡(X1,X2)=Cov⁡(X2,X1)\operatorname{Cov}(X_1, X_2) = \operatorname{Cov}(X_2, X_1). Кроме того, она положительно полуопределённая (positive semidefinite): для любого фиксированного вектора a\mathbf a дисперсия Var⁡(a⊤X)=a⊤Σ a\operatorname{Var}(\mathbf a^{\top}X) = \mathbf a^{\top}\boldsymbol\Sigma\,\mathbf a не может быть отрицательной. Все дисперсии и ковариации вектора умещаются в три свободных числа.

Пример, который проходит через всю заметку, — гауссиана с центром в начале координат и

μ=(00),Σ=(10.50.51):\boldsymbol{\mu} = \begin{pmatrix} 0 \\ 0 \end{pmatrix}, \qquad \boldsymbol{\Sigma} = \begin{pmatrix} 1 & 0.5 \\ 0.5 & 1 \end{pmatrix}:

единичные дисперсии и корреляция ρ=0.5\rho = 0.5, поэтому облако точек вытянуто вдоль диагонали x1=x2x_1 = x_2.

Почему нужна полная матрица, а не две дисперсии?#

Две дисперсии говорят, насколько облако разбросано вдоль каждой координатной оси. Этого достаточно, только когда координаты некоррелированы, и тогда облако вытянуто вдоль осей. Внедиагональный элемент хранит то, чего дисперсии передать не могут: как координаты меняются совместно. Именно он наклоняет облако.

На рисунке 1 правое облако — это левое, повёрнутое на 45°. У двух облаков одинаковые собственные значения (1.5 и 0.5), но обе дисперсии правого облака вдоль осей равны 1. Ровно такие же дисперсии вдоль осей у круглого облака N(0,I)\mathcal N(\mathbf 0, \mathbf I), так что по одним двум дисперсиям наклонённое облако нельзя отличить от круга. Наклон фиксирует только Cov⁡(X1,X2)=0.5\operatorname{Cov}(X_1, X_2) = 0.5.

Рисунок

Диагональная матрица растягивает облако только вдоль осей; ковариация его наклоняет

Гауссовское облако, вытянутое вдоль осей, рядом с наклонённым коррелированным облакомДве диаграммы рассеяния двумерных гауссовских сэмплов с эллипсами 1 сигма и 2 сигма. Левое облако имеет ковариацию diag(1.5, 0.5): оно шире, чем выше, и вытянуто вдоль осей. Фигурные скобки под горизонтальной осью и рядом с вертикальной отмечают разброс: каждая охватывает плюс-минус одно стандартное отклонение и подписана как плюс-минус корень из Var(X1) = 1.5 и из Var(X2) = 0.5. Правое облако имеет единичные дисперсии и ковариацию 0.5. Оно наклонено вдоль диагонали x1 = x2. Его скобки охватывают плюс-минус 1 по обеим осям, потому что Var(X1) = Var(X2) = 1, как у ненаклонённого круга. Стрелки вдоль собственных векторов показывают полуоси эллипса 1 сигма длиной корень из 1.5 вдоль диагонали и корень из 0.5 поперёк неё.Только дисперсииCov(X₁, X₂) = 0x₁x₂1σ2σ±√Var(X₁) = ±√1.5±√Var(X₂)= ±√0.5С ковариациейCov(X₁, X₂) = 0.5x₁x₂1σ2σ±√Var(X₁) = ±1±√Var(X₂)= ±1x₁ = x₂√1.5√0.5Гауссовское облако, вытянутое вдоль осей, рядом с наклонённым коррелированным облакомДве диаграммы рассеяния двумерных гауссовских сэмплов с эллипсами 1 сигма и 2 сигма. Левое облако имеет ковариацию diag(1.5, 0.5): оно шире, чем выше, и вытянуто вдоль осей. Фигурные скобки под горизонтальной осью и рядом с вертикальной отмечают разброс: каждая охватывает плюс-минус одно стандартное отклонение и подписана как плюс-минус корень из Var(X1) = 1.5 и из Var(X2) = 0.5. Правое облако имеет единичные дисперсии и ковариацию 0.5. Оно наклонено вдоль диагонали x1 = x2. Его скобки охватывают плюс-минус 1 по обеим осям, потому что Var(X1) = Var(X2) = 1, как у ненаклонённого круга. Стрелки вдоль собственных векторов показывают полуоси эллипса 1 сигма длиной корень из 1.5 вдоль диагонали и корень из 0.5 поперёк неё.Только дисперсииCov(X₁, X₂) = 0x₁x₂1σ2σ±√Var(X₁) = ±√1.5±√Var(X₂)= ±√0.5С ковариациейCov(X₁, X₂) = 0.5x₁x₂1σ2σ±√Var(X₁) = ±1±√Var(X₂)= ±1x₁ = x₂√1.5√0.5
Оба облака построены по одним и тем же парам из стандартного нормального распределения (260 пар, без немногих, выходящих за пределы любого из окон). Слева: Σ = diag(1.5, 0.5), координаты независимы, поэтому разброс описывается одними Var(X₁) и Var(X₂). Справа: Σ = [[1, 0.5], [0.5, 1]], сквозной пример заметки. Её собственные значения 1.5 и 0.5, поэтому это левое облако, повёрнутое на 45°. Дисперсии вдоль обеих осей равны 1, и наклон фиксирует только внедиагональный элемент. Фигурные скобки охватывают ±1 стандартное отклонение, ±√Var; пунктирные направляющие опущены к ним из точек, где эллипс 1σ достигает крайних значений. Сплошная и пунктирная кривые — эллипсы 1σ и 2σ.

Двумерная плотность#

Когда Σ\boldsymbol\Sigma обратима (положительно определена, а не только полуопределена), совместная плотность на всей плоскости R2\mathbb R^2 равна

p(x)=12π∣Σ∣×exp⁡ ⁣(−12 (x−μ)⊤ Σ−1 (x−μ)),\begin{aligned} p(\mathbf x) &= \frac{1}{2\pi\sqrt{|\boldsymbol\Sigma|}} \\[4pt] &\times \exp\!\left(-\tfrac12\, (\mathbf{x}-\boldsymbol\mu)^{\top}\,\boldsymbol\Sigma^{-1}\,(\mathbf{x}-\boldsymbol\mu)\right), \end{aligned}

где x=(x1,x2)⊤\mathbf x = (x_1, x_2)^{\top}, Σ−1\boldsymbol\Sigma^{-1} — обратная матрица, а ∣Σ∣|\boldsymbol\Sigma| — определитель ковариационной матрицы. Размеры сомножителей в квадратичной форме таковы:

(x−μ)⊤⏟1×2  Σ−1⏟2×2  (x−μ)⏟2×1,\underbrace{(\mathbf{x}-\boldsymbol\mu)^{\top}}_{1\times 2}\; \underbrace{\boldsymbol\Sigma^{-1}}_{2\times 2}\; \underbrace{(\mathbf{x}-\boldsymbol\mu)}_{2\times 1},

поэтому показатель экспоненты — скаляр. В dd измерениях нормирующая константа становится равной (2π)−d/2∣Σ∣−1/2(2\pi)^{-d/2}|\boldsymbol\Sigma|^{-1/2}, и при d=2d = 2 получается выражение выше (Bishop, 2006, §2.3).

Линии уровня плотности, на которых квадрат расстояния Махаланобиса (Mahalanobis distance) (x−μ)⊤Σ−1(x−μ)(\mathbf{x}-\boldsymbol\mu)^{\top}\boldsymbol\Sigma^{-1}(\mathbf{x}-\boldsymbol\mu) равен k2k^2, — эллипсы (Murphy, 2022, §3.2). Рисунки 1 и 3 показывают их как линии уровня 1σ1\sigma (k=1k = 1) и 2σ2\sigma (k=2k = 2). Вероятность попасть внутрь такого эллипса следует из преобразования, описанного ниже в разделе о сэмплировании. Запишем X=μ+Σ1/2ZX = \boldsymbol\mu + \boldsymbol\Sigma^{1/2} Z, где Z∼N(0,I)Z \sim \mathcal N(\mathbf 0, \mathbf I). Поскольку Σ1/2\boldsymbol\Sigma^{1/2} симметрична и Σ1/2Σ−1Σ1/2=I\boldsymbol\Sigma^{1/2}\boldsymbol\Sigma^{-1}\boldsymbol\Sigma^{1/2} = \mathbf I, квадрат расстояния превращается в Z⊤Z=Z12+Z22Z^{\top}Z = Z_1^2 + Z_2^2 — квадрат длины стандартного шума. Стандартная плотность 12πe−r2/2\frac{1}{2\pi}e^{-r^2/2} зависит только от радиуса rr, поэтому в полярных координатах

Pr⁡(Z12+Z22≤k2)=∫0kr e−r2/2 dr=1−e−k2/2.\begin{aligned} \Pr\bigl(Z_1^2 + Z_2^2 \le k^2\bigr) &= \int_0^{k} r\,e^{-r^2/2}\,dr \\[4pt] &= 1 - e^{-k^2/2}. \end{aligned}

Это функция распределения χ2\chi^2 с двумя степенями свободы в точке k2k^2. Значит, эллипс 1σ1\sigma содержит 1−e−1/2≈39%1 - e^{-1/2} \approx 39\% вероятности, а эллипс 2σ2\sigma — 1−e−2≈86%1 - e^{-2} \approx 86\%, а не 68% и 95%, как одномерные интервалы.

Для сквозного примера

∣Σ∣=1−0.52=0.75,Σ−1=10.75(1−0.5−0.51)=(4/3−2/3−2/34/3),\begin{aligned} |\boldsymbol\Sigma| &= 1 - 0.5^2 = 0.75, \\[4pt] \boldsymbol\Sigma^{-1} &= \frac{1}{0.75}\begin{pmatrix} 1 & -0.5 \\ -0.5 & 1 \end{pmatrix} \\[4pt] &= \begin{pmatrix} 4/3 & -2/3 \\ -2/3 & 4/3 \end{pmatrix}, \end{aligned}

а максимальное значение плотности равно p(μ)=1/(2π0.75)≈0.184p(\boldsymbol\mu) = 1/(2\pi\sqrt{0.75}) \approx 0.184.

Сэмплирование: от стандартного шума к любой гауссиане#

Коротко. Чтобы сэмплировать N(μ,Σ)\mathcal N(\boldsymbol\mu, \boldsymbol\Sigma), возьмём Z∼N(0,I)Z \sim \mathcal N(\mathbf 0, \mathbf I) и вернём μ+AZ\boldsymbol\mu + \mathbf A Z для любой матрицы A\mathbf A с AA⊤=Σ\mathbf A\mathbf A^{\top} = \boldsymbol\Sigma; в коде A\mathbf A — множитель Холецкого. Остальная часть раздела строит квадратный корень и доказывает рецепт дважды: заменой переменных и через моменты. Кто знает аффинные преобразования гауссиан из курса теории вероятностей, может считать эти два доказательства дополнительными и сразу перейти к разобранному примеру.

В одномерном случае стандартизация и обратное к ней преобразование имеют вид

Z=X−μσ∼N(0,1)для X∼N(μ,σ2),X=μ+σZ∼N(μ,σ2)для Z∼N(0,1).\begin{aligned} Z &= \frac{X - \mu}{\sigma} \sim \mathcal N(0, 1) \quad \text{для } X \sim \mathcal N(\mu, \sigma^2),\\[4pt] X &= \mu + \sigma Z \sim \mathcal N(\mu, \sigma^2) \quad \text{для } Z \sim \mathcal N(0, 1). \end{aligned}

Поэтому, чтобы сэмплировать любое нормальное распределение, достаточно сэмплировать стандартное, растянуть результат в σ\sigma раз и сдвинуть на μ.\mu.

Рисунок

Стандартизация и обратное преобразование в одномерном случае

Плотность стандартного нормального распределения и сдвинутая, растянутая нормальная плотностьДве колоколообразные кривые на одной оси. Более высокая серая кривая — стандартное нормальное распределение Z ~ N(0, 1) с центром в 0. Более низкая и широкая красная кривая — X ~ N(2, 1.5²) с центром в mu = 2; на высоте точки перегиба нарисована горизонтальная стрелка длиной sigma = 1.5. Точка z = 1 на оси соединена изогнутой стрелкой с подписью X = mu + sigma Z с точкой x = 3.5, а вторая стрелка под осью с подписью Z = (X − mu) / sigma ведёт обратно.−3−2−101234567Z ~ N(0, 1)X ~ N(μ, σ²)μ = 2, σ = 1.5μσX = μ + σZZ = (X − μ) / σПлотность стандартного нормального распределения и сдвинутая, растянутая нормальная плотностьДве колоколообразные кривые на одной оси. Более высокая серая кривая — стандартное нормальное распределение Z ~ N(0, 1) с центром в 0. Более низкая и широкая красная кривая — X ~ N(2, 1.5²) с центром в mu = 2; на высоте точки перегиба нарисована горизонтальная стрелка длиной sigma = 1.5. Точка z = 1 на оси соединена изогнутой стрелкой с подписью X = mu + sigma Z с точкой x = 3.5, а вторая стрелка под осью с подписью Z = (X − mu) / sigma ведёт обратно.−20246Z ~ N(0, 1)X ~ N(μ, σ²)μ = 2, σ = 1.5μσX = μ + σZZ = (X − μ) / σ
Точка z = 1 стандартного нормального распределения переходит в x = μ + σz = 3.5 при μ = 2, σ = 1.5; деление (x − μ) на σ возвращает её обратно. Обе точки лежат на одно стандартное отклонение выше своего среднего.

В двумерном случае нужна матрица, которая играет роль σ\sigma.

Спектральное разложение. По спектральной теореме любую вещественную симметричную матрицу, в частности любую ковариационную матрицу, можно записать как

Σ=U Λ U⊤,\boldsymbol\Sigma = \mathbf U\,\boldsymbol\Lambda\,\mathbf U^{\top},

где Λ\boldsymbol\Lambda — диагональная матрица из собственных значений Σ\boldsymbol\Sigma, а столбцы ортогональной матрицы U\mathbf U — соответствующие нормированные собственные векторы. Собственные значения неотрицательны, потому что Σ\boldsymbol\Sigma положительно полуопределена, и можно определить квадратный корень из матрицы

Σ1/2=U Λ1/2 U⊤,\boldsymbol\Sigma^{1/2} = \mathbf U\,\boldsymbol\Lambda^{1/2}\,\mathbf U^{\top},

где Λ1/2\boldsymbol\Lambda^{1/2} содержит квадратные корни из собственных значений. Корень сам симметричен, потому что (UΛ1/2U⊤)⊤=UΛ1/2U⊤(\mathbf U\boldsymbol\Lambda^{1/2}\mathbf U^{\top})^{\top} = \mathbf U\boldsymbol\Lambda^{1/2}\mathbf U^{\top}. Так как U⊤U=I\mathbf U^{\top}\mathbf U = \mathbf I, получаем Σ1/2Σ1/2=UΛU⊤=Σ\boldsymbol\Sigma^{1/2}\boldsymbol\Sigma^{1/2} = \mathbf U\boldsymbol\Lambda\mathbf U^{\top} = \boldsymbol\Sigma.

Преобразование. Если Z∼N(0,I)Z \sim \mathcal N(\mathbf 0, \mathbf I), то

X=μ+Σ1/2Z∼N(μ,Σ).X = \boldsymbol\mu + \boldsymbol\Sigma^{1/2} Z \sim \mathcal N(\boldsymbol\mu, \boldsymbol\Sigma).

В общем случае подходит любая квадратная матрица A\mathbf A с AA⊤=Σ\mathbf A\mathbf A^{\top} = \boldsymbol\Sigma; Σ1/2\boldsymbol\Sigma^{1/2} — одна из них, потому что она симметрична и в квадрате даёт Σ\boldsymbol\Sigma. Для положительно определённой Σ\boldsymbol\Sigma такая A\mathbf A обратима, поскольку (det⁡A)2=∣Σ∣>0(\det\mathbf A)^2 = |\boldsymbol\Sigma| > 0, и формула замены переменных (change of variables) даёт плотность X=μ+AZX = \boldsymbol\mu + \mathbf A Z (Murphy, 2022, §2.8). Подставим z=A−1(x−μ)\mathbf z = \mathbf A^{-1}(\mathbf x - \boldsymbol\mu) в стандартную плотность 12πe−z⊤z/2\frac{1}{2\pi}e^{-\mathbf z^{\top}\mathbf z/2} и разделим на ∣det⁡A∣=∣Σ∣1/2|\det\mathbf A| = |\boldsymbol\Sigma|^{1/2}:

p(x)=12π ∣det⁡A∣exp⁡ ⁣(−12 z⊤z)=12π∣Σ∣×exp⁡ ⁣(−12 (x−μ)⊤ Σ−1 (x−μ)),\begin{aligned} p(\mathbf x) &= \frac{1}{2\pi\,|\det\mathbf A|}\exp\!\left(-\tfrac12\,\mathbf z^{\top}\mathbf z\right) \\[4pt] &= \frac{1}{2\pi\sqrt{|\boldsymbol\Sigma|}} \\[4pt] &\times \exp\!\left(-\tfrac12\, (\mathbf{x}-\boldsymbol\mu)^{\top}\,\boldsymbol\Sigma^{-1}\,(\mathbf{x}-\boldsymbol\mu)\right), \end{aligned}

потому что z⊤z=(x−μ)⊤(A−1)⊤A−1(x−μ)\mathbf z^{\top}\mathbf z = (\mathbf x-\boldsymbol\mu)^{\top}(\mathbf A^{-1})^{\top}\mathbf A^{-1}(\mathbf x-\boldsymbol\mu) и (A−1)⊤A−1=(AA⊤)−1=Σ−1(\mathbf A^{-1})^{\top}\mathbf A^{-1} = (\mathbf A\mathbf A^{\top})^{-1} = \boldsymbol\Sigma^{-1}. Это плотность N(μ,Σ)\mathcal N(\boldsymbol\mu, \boldsymbol\Sigma) из предыдущего раздела. (Для вырожденной Σ\boldsymbol\Sigma то же преобразование задаёт вырожденную гауссиану, сосредоточенную на прямой; плотности на плоскости у неё нет.) Первые два момента дают быструю проверку. Среднее равно μ+A E[Z]=μ\boldsymbol\mu + \mathbf A\,\mathbb E[Z] = \boldsymbol\mu, а ковариация —

Cov⁡(μ+AZ)=A Cov⁡(Z) A⊤=A I A⊤=Σ.\begin{aligned} \operatorname{Cov}(\boldsymbol\mu + \mathbf A Z) &= \mathbf A\,\operatorname{Cov}(Z)\,\mathbf A^{\top} \\ &= \mathbf A\,\mathbf I\,\mathbf A^{\top} = \boldsymbol\Sigma . \end{aligned}

Симметричный корень Σ1/2\boldsymbol\Sigma^{1/2} — лишь один из вариантов. Для положительно определённой Σ\boldsymbol\Sigma существует ровно одна нижнетреугольная матрица L\mathbf L с положительной диагональю и LL⊤=Σ\mathbf L\mathbf L^{\top} = \boldsymbol\Sigma — множитель Холецкого (Cholesky factor) (Golub and Van Loan, 2013, §4.2). В коде обычно выбирают именно его: конечный алгоритм вычисляет его примерно за d3/3d^3/3 операций с плавающей точкой для матрицы d×dd \times d, тогда как спектральному разложению нужен итерационный метод. В отличие от симметричного корня, он требует положительной определённости: torch.linalg.cholesky завершается ошибкой на вырожденной ковариации, а MultivariateNormal принимает только положительно определённую covariance_matrix. MultivariateNormal в PyTorch сэмплирует ровно так: хранит множитель Холецкого переданной ковариации и возвращает μ+LZ\boldsymbol\mu + \mathbf L Z, где Z∼N(0,I)Z \sim \mathcal N(\mathbf 0, \mathbf I) (документация и исходный код PyTorch). Та же схема — на входе шум, на выходе детерминированное преобразование — лежит в основе трюка репараметризации (reparameterization trick) в VAE и формулы зашумления за один шаг в DDPM.

Рисунок

Сэмплирование любой гауссианы из стандартного шума

Сэмплирование в три шага: Z, затем A Z, затем μ + A ZТри диаграммы рассеяния в одном и том же окне. Сначала круглое облако стандартного нормального шума Z с центром в начале координат и круговыми линиями уровня 1 сигма и 2 сигма. Стрелка с подписью «умножить на A», растяжение и сдвиг, ведёт ко второй панели, где облако A Z наклонено вдоль диагонали и линии уровня — эллипсы; A — множитель Холецкого L со строками (1, 0) и (0.5, 0.866). Стрелка с подписью «плюс mu», перенос, ведёт к третьей панели, где то же наклонённое облако имеет центр mu = (1.5, 1), отмеченный крестиком и стрелкой из начала координат. Одна выделенная точка переходит из z = (2, 1) в A z = (2, 1.87), а затем в μ + A z = (3.5, 2.87).стандартный шумzZ ~ N(0, I)растяжение и сдвигAzAZ ~ N(0, AAᵀ)переносμμ + Azμ + AZ ~ N(μ, Σ)× A+ μA = L =100.50.866μ = (1.5, 1)LLᵀ = Σ = [[1, 0.5], [0.5, 1]]Сэмплирование в три шага: Z, затем A Z, затем μ + A ZТри диаграммы рассеяния в одном и том же окне. Сначала круглое облако стандартного нормального шума Z с центром в начале координат и круговыми линиями уровня 1 сигма и 2 сигма. Стрелка с подписью «умножить на A», растяжение и сдвиг, ведёт ко второй панели, где облако A Z наклонено вдоль диагонали и линии уровня — эллипсы; A — множитель Холецкого L со строками (1, 0) и (0.5, 0.866). Стрелка с подписью «плюс mu», перенос, ведёт к третьей панели, где то же наклонённое облако имеет центр mu = (1.5, 1), отмеченный крестиком и стрелкой из начала координат. Одна выделенная точка переходит из z = (2, 1) в A z = (2, 1.87), а затем в μ + A z = (3.5, 2.87).стандартный шумzZ ~ N(0, I)растяжение и сдвигAzAZ ~ N(0, AAᵀ)переносμμ + Azμ + AZ ~ N(μ, Σ)× A+ μA = L =100.50.866μ = (1.5, 1)LLᵀ = Σ = [[1, 0.5], [0.5, 1]]
Независимые пары Z из стандартного нормального распределения умножаются на матрицу A с AAᵀ = Σ (здесь это множитель Холецкого L для Σ = [[1, 0.5], [0.5, 1]] из сквозного примера), а затем сдвигаются на μ = (1.5, 1). Янтарная точка z = (2, 1) прослежена через оба шага: она переходит в Az = (2, 1.87), а затем в μ + Az = (3.5, 2.87). Кривые — линии уровня 1σ и 2σ; у всех панелей одно и то же окно.

Разобранный пример#

Для Σ=(10.50.51)\boldsymbol\Sigma = \begin{pmatrix} 1 & 0.5 \\ 0.5 & 1\end{pmatrix} характеристическое уравнение имеет вид (1−λ)2=0.25(1 - \lambda)^2 = 0.25, поэтому собственные значения равны λ1=1.5\lambda_1 = 1.5 и λ2=0.5\lambda_2 = 0.5. Собственные векторы — 12(1,1)⊤\tfrac{1}{\sqrt2}(1, 1)^{\top} и 12(1,−1)⊤\tfrac{1}{\sqrt2}(1, -1)^{\top}. Дисперсия максимальна вдоль диагонали x1=x2x_1 = x_2: полуоси эллипса 1σ1\sigma равны 1.5≈1.225\sqrt{1.5} \approx 1.225 вдоль неё и 0.5≈0.707\sqrt{0.5} \approx 0.707 поперёк. Два допустимых квадратных корня:

Σ1/2=12(1.5+0.51.5−0.51.5−0.51.5+0.5)≈(0.9660.2590.2590.966),\begin{aligned} \boldsymbol\Sigma^{1/2} &= \frac12\begin{pmatrix} \sqrt{1.5}+\sqrt{0.5} & \sqrt{1.5}-\sqrt{0.5} \\ \sqrt{1.5}-\sqrt{0.5} & \sqrt{1.5}+\sqrt{0.5} \end{pmatrix} \\[4pt] &\approx \begin{pmatrix} 0.966 & 0.259 \\ 0.259 & 0.966 \end{pmatrix}, \end{aligned} L=(100.50.75)≈(100.50.866).\mathbf L = \begin{pmatrix} 1 & 0 \\ 0.5 & \sqrt{0.75} \end{pmatrix} \approx \begin{pmatrix} 1 & 0 \\ 0.5 & 0.866 \end{pmatrix}.

Проверка: 0.9662+0.2592≈10.966^2 + 0.259^2 \approx 1 и 2⋅0.966⋅0.259≈0.52 \cdot 0.966 \cdot 0.259 \approx 0.5. Для множителя Холецкого LL⊤=(10.50.50.25+0.75)=Σ\mathbf L\mathbf L^{\top} = \begin{pmatrix} 1 & 0.5 \\ 0.5 & 0.25 + 0.75 \end{pmatrix} = \boldsymbol\Sigma. Обе матрицы превращают независимый стандартный шум в сэмплы одного и того же коррелированного облака.

Проверьте себя. Возьмём Σ=(1−0.8−0.81)\boldsymbol\Sigma = \begin{pmatrix} 1 & -0.8 \\ -0.8 & 1\end{pmatrix}. Вдоль какой диагонали вытянуто облако и каков его множитель Холецкого? Ответ: собственные значения равны 1.81.8 и 0.20.2, длинная ось идёт вдоль x1=−x2x_1 = -x_2, полуоси равны 1.8≈1.342\sqrt{1.8} \approx 1.342 и 0.2≈0.447\sqrt{0.2} \approx 0.447, а L=(10−0.80.6)\mathbf L = \begin{pmatrix} 1 & 0 \\ -0.8 & 0.6 \end{pmatrix}, поскольку LL⊤=(1−0.8−0.80.64+0.36)=Σ\mathbf L\mathbf L^{\top} = \begin{pmatrix} 1 & -0.8 \\ -0.8 & 0.64 + 0.36 \end{pmatrix} = \boldsymbol\Sigma.

Гауссианы в PyTorch#

torch.distributions содержит параметризуемые распределения с методами для вычисления (логарифма) плотности и для сэмплирования. Двумерная гауссиана — это MultivariateNormal. Экспериментам по подгонке в заметке Подгонка распределений с помощью KL нужна гауссиана, параметры которой оптимизатор может менять свободно. Мешает ковариация: произвольная матрица 2×22\times 2, вообще говоря, не является допустимой ковариационной матрицей.

Выход — обучать не Σ\boldsymbol\Sigma, а множитель Холецкого. При

L=(ea0bec),LL⊤=(e2ab eab eab2+e2c),\begin{gathered} \mathbf L = \begin{pmatrix} e^{a} & 0 \\ b & e^{c} \end{pmatrix}, \\[4pt] \mathbf L\mathbf L^{\top} = \begin{pmatrix} e^{2a} & b\,e^{a} \\ b\,e^{a} & b^2 + e^{2c} \end{pmatrix}, \end{gathered}

три исходных числа a,b,ca, b, c могут принимать любые вещественные значения. Диагональ L\mathbf L хранится через логарифм, поэтому остаётся положительной, и треугольная матрица L\mathbf L обратима. Тогда LL⊤\mathbf L\mathbf L^{\top} симметрична и положительно определена: для v≠0\mathbf v \ne \mathbf 0 имеем v⊤LL⊤v=∥L⊤v∥2>0\mathbf v^{\top}\mathbf L\mathbf L^{\top}\mathbf v = \|\mathbf L^{\top}\mathbf v\|^2 > 0, поскольку L⊤\mathbf L^{\top} обратима. Сквозной пример получается при a=0a = 0, b=0.5b = 0.5 и c=ln⁡0.75≈−0.144c = \ln\sqrt{0.75} \approx -0.144; инициализация a=b=c=0a = b = c = 0 даёт Σ=I\boldsymbol\Sigma = \mathbf I.

Обучаемые параметры создаются с requires_grad=True: это говорит механизму автоматического дифференцирования PyTorch (autograd) записывать операции над ними и вычислять их градиенты. У модельного распределения QQ обучаются среднее и исходные элементы L\mathbf L. Целевое распределение PP создаётся с requires_grad=False, потому что оно фиксировано. Рисунок 4 показывает начальную точку первого эксперимента по подгонке; каждое облако окрашено по своей собственной плотности.

Рисунок

Целевое распределение P и модель Q до обучения

Два облака гауссовских сэмплов, нарисованные точкамиКвадратный график, обе оси от −10 до 10. Красное облако из 400 точек с центром в (−5, −5) подписано как целевое распределение P со средним (−5, −5), единичной ковариацией и requires_grad False. Синее облако из 400 точек с центром в начале координат подписано как обучаемое распределение Q со средним (0, 0) и ковариацией L L транспонированное, равной единичной матрице при инициализации; у его параметров requires_grad True. Точки у центра каждого облака нарисованы ярче, потому что плотность их облака, p(x) для P и q(x) для Q, там выше.−10−50510−10−50510обучаемое Qμ = (0, 0), Σ = LLᵀ = Irequires_grad=True:μ и L обучаютсяцелевое Pμ = (−5, −5), Σ = Irequires_grad=False:фиксированоx₁x₂ярче цвет — выше плотность:p(x) для P, q(x) для QДва облака гауссовских сэмплов, нарисованные точкамиКвадратный график, обе оси от −10 до 10. Красное облако из 400 точек с центром в (−5, −5) — фиксированное целевое распределение P с единичной ковариацией (requires_grad False). Синее облако с центром в начале координат — обучаемое распределение Q с ковариацией L L транспонированное, равной единичной матрице при инициализации (requires_grad True). Точки у центра каждого облака нарисованы ярче, по плотности p(x) для P и q(x) для Q.−10−50510−10−50510целевое Pμ = (−5, −5), Σ = Irequires_grad=False:фиксированообучаемое Qμ = (0, 0), Σ = LLᵀ = Irequires_grad=True:μ и L обучаютсяx₁x₂ярче цвет — выше плотность: p(x) для P, q(x) для Q
По 400 сэмплов из фиксированного целевого распределения P = N((−5, −5), I) и из обучаемой модели Q, инициализированной как N(0, I), в пределах графика (−10, 10). Каждая точка окрашена по плотности своего облака: p(x) для сэмплов цели и q(x) для сэмплов модели, так что более насыщенный цвет означает более высокую плотность.

Минимальный пример обоих способов сэмплировать из распределения сквозного примера:

import torch
from torch import distributions as distrs

mu = torch.zeros(2)
cov = torch.tensor([[1.0, 0.5], [0.5, 1.0]])
target = distrs.MultivariateNormal(
    mu, covariance_matrix=cov)

# 1000 сэмплов, форма (1000, 2)
x = target.sample(torch.Size([1000]))
# L = [[1, 0], [0.5, 0.866]]
L = torch.linalg.cholesky(cov)
# то же распределение вручную
x_manual = mu + torch.randn(1000, 2) @ L.T

Каждая строка torch.randn(1000, 2) — один сэмпл z⊤\mathbf z^{\top}, поэтому @ L.T построчно вычисляет (Lz)⊤(\mathbf L\mathbf z)^{\top}.

Ноутбук#

Практическая часть заметки следует ноутбуку Distances between distributions из репозитория курса HSE-LAMBDA Deep Generative Models. Ссылка закреплена на конкретном коммите; ячейки нумеруются с 1, считая все ячейки подряд.

  • Ячейка 2 готовит окружение: импортирует Matplotlib со стилем fivethirtyeight, NumPy, PyTorch с torch.distributions под именем distrs и clear_output из IPython, с помощью которой циклы обучения потом перерисовывают графики.
  • Ячейка 4 определяет plot_2d_dots — диаграмму рассеяния массива N×2N \times 2 в пределах (−10,10)(-10, 10) по умолчанию для обеих осей (аргументы xlim и ylim), по одной маленькой точке на сэмпл; точки можно окрасить по необязательному массиву значений через цветовую карту cmap (по умолчанию viridis).
  • Ячейка 5 определяет три вспомогательные функции для описанной выше параметризации. get_parameters(mu, sigma, requires_grad) создаёт среднее (μ,μ)(\mu, \mu) и исходные элементы a=c=ln⁡σa = c = \ln\sigma, b=0b = 0. create_distr собирает L\mathbf L и возвращает MultivariateNormal(mu, L @ L.T), передавая LL⊤\mathbf L\mathbf L^{\top} как covariance_matrix. sample(distr, n) возвращает тензор n×2n \times 2. Поскольку L\mathbf L уже является корректным множителем Холецкого, MultivariateNormal(mu, scale_tril=L) задаёт то же распределение и обходится без повторного разложения, которое PyTorch выполняет для L @ L.T; по этой причине документация PyTorch рекомендует scale_tril.
  • Ячейки 8–11 создают фиксированное целевое распределение N((−5,−5),I)\mathcal N((-5,-5), \mathbf I) и обучаемую модель QQ, инициализированную как N(0,I)\mathcal N(\mathbf 0, \mathbf I), и рисуют оба облака, окрашенные по p(x)p(\mathbf x) и q(x)q(\mathbf x) (рисунок 4). Ячейки 8 и 11 берут по 1000 сэмплов из каждого распределения, а графики используют цветовые карты viridis и plasma; на рисунке 4 по 400 сэмплов на облако, а плотность передана насыщенностью цвета. Сама подгонка — тема заметки Подгонка распределений с помощью KL.

Дальше#

Когда есть целевое распределение и обучаемая модель, остаётся понять, что значит «подогнать»: нужно число, которое говорит, насколько QQ далеко от PP. Первый кандидат — KL-дивергенция, и чтобы понять её, мы начнём с энтропии в заметке Энтропия, кросс-энтропия и KL-дивергенция.

Литература#

  • C. M. Bishop. Pattern Recognition and Machine Learning. Springer, 2006. §2.3: гауссовское распределение и его моменты.
  • K. P. Murphy. Probabilistic Machine Learning: An Introduction. MIT Press, 2022. §2.8: преобразования случайных величин, включая формулу замены переменных; §3.2: многомерное гауссовское распределение и расстояние Махаланобиса.
  • G. H. Golub, C. F. Van Loan. Matrix Computations, 4th ed. Johns Hopkins University Press, 2013. §4.2: положительно определённые системы и разложение Холецкого.
  • Документация PyTorch: torch.distributions.MultivariateNormal; исходный код метода сэмплирования — multivariate_normal.py (PyTorch 2.5.0).
  • HSE-LAMBDA, репозиторий курса Deep Generative Models: distances.ipynb.