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

04 / 33 · Основы

Подгонка распределений с помощью KL

Обучение среднего и ковариации гауссианы минимизацией выборочной оценки KL(P‖Q), допущения, на которые неявно опирается KL-дивергенция, и поведение KL, обратной KL, JS и функции потерь наименьших квадратов, когда одна гауссиана должна описать две моды.

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

В заметке об энтропии мы вывели KL-дивергенцию (KL divergence) из неожиданности и показали, что минимизация DKL(P ∥ Q)D_{\mathrm{KL}}(P\,\|\,Q) по модели — то же самое, что максимизация правдоподобия. В этой заметке мы применяем её к гауссовской модели: градиентный спуск притягивает QQ с обучаемыми параметрами к целевому распределению PP. Заметка построена вокруг трёх вопросов:

  1. Как обучаются параметры? Что на самом деле происходит за одну итерацию цикла подгонки?
  2. Что предполагает KL? Что должно выполняться, чтобы формула имела смысл, и где каждое допущение проявляется в коде?
  3. Что, если модель не может представить целевое распределение? Одна гауссиана, подогнанная к двум модам, показывает, чем различаются KL, обратная KL (reverse KL), дивергенция Йенсена–Шеннона (Jensen–Shannon divergence, JS) и функция потерь наименьших квадратов (least-squares loss).

Обозначения. PP — истинное (целевое) распределение с плотностью pp, Q=QθQ = Q_\theta — модель с плотностью qq и параметрами θ\theta, η\eta — шаг обучения (learning rate). В одномерном случае θ=(μ,log⁡σ)\theta = (\mu, \log\sigma): σ\sigma хранится через свой логарифм, чтобы σ=elog⁡σ\sigma = e^{\log\sigma} оставалось положительным. В двумерном случае среднее равно μ\boldsymbol\mu, а ковариация — Σ=LL⊤\boldsymbol\Sigma = \mathbf L\mathbf L^\top, где L\mathbf L — нижнетреугольный множитель Холецкого (Cholesky factor) из заметки о гауссианах.

Как обучаются параметры#

Одна итерация цикла, шаг за шагом:

  • Оптимизатор получает список обучаемых тензоров. Каждый из них создан с requires_grad=True, чтобы backward() заполнял его .grad. В одномерном случае это среднее и log⁡σ\log\sigma; в двумерном — среднее и три исходных элемента множителя Холецкого из заметки о гауссианах. У параметров целевого распределения нет градиента, и они остаются фиксированными.
  • Q заново строится из текущих параметров на каждой итерации: Q=N(μ,σ2)Q = \mathcal N(\mu, \sigma^2) с σ=elog⁡σ\sigma = e^{\log\sigma}.
  • qx содержит плотность модели в точках выборки, q(xi)q(x_i); px содержит p(xi)p(x_i) — плотность истинного распределения в тех же точках.
  • loss — выборочная оценка KL-дивергенции, построенная по px и qx.
  • loss.backward() вычисляет градиенты ∂ loss/∂μ\partial\,\text{loss}/\partial\mu и ∂ loss/∂log⁡σ=σ ∂ loss/∂σ\partial\,\text{loss}/\partial\log\sigma = \sigma\,\partial\,\text{loss}/\partial\sigma методом обратного распространения ошибки и сохраняет их в .grad.
  • optimizer.step() сдвигает параметры против градиента. Для обычного SGD это
μ←μ−η ∂ loss∂μ,log⁡σ←log⁡σ−η ∂ loss∂log⁡σ.\begin{gathered} \mu \leftarrow \mu - \eta\,\frac{\partial\,\text{loss}}{\partial \mu}, \\ \log\sigma \leftarrow \log\sigma - \eta\,\frac{\partial\,\text{loss}}{\partial \log\sigma}. \end{gathered}

Adam (Kingma and Ba, 2015) движется в похожем направлении, но масштабирует шаг по каждой координате скользящими оценками среднего и величины градиента. Подгонки по KL ниже выполняются с помощью Adam.

Рисунок

Одна итерация цикла подгонки

Цикл обучения по KL как замкнутая схемаШесть блоков, соединённых по часовой стрелке. Обучаемые параметры mu и s, равное log sigma, с requires_grad, равным true, строят распределение Q — нормальное со средним mu и дисперсией sigma в квадрате, где sigma равна exp от s. Q вычисляется в сэмплах x_i из P, для которых известны и истинные плотности p от x_i. Функция потерь — среднее log p минус log q, оценка KL между P и Q. loss.backward даёт градиенты функции потерь по mu и s. optimizer.step сдвигает mu и s против градиента, и обновлённые параметры поступают на следующую итерацию.Параметры моделиμ, s = log σrequires_grad=TrueРаспределениеQ = 𝒩(μ, σ²)σ = exp(s)Плотности в xᵢq(xᵢ) и p(xᵢ)Функция потерьmean(log p(xᵢ) − log q(xᵢ))≈ KL(P ‖ Q)Градиенты∂loss/∂μ, ∂loss/∂soptimizer.step()μ ← μ − η·∂loss/∂μs ← s − η·∂loss/∂sфиксированные сэмплы xᵢ ~ Ppx = p(xᵢ), истинная плотностьстроим Qlog_probkl_loss(px, qx)loss.backward().gradновые μ, s:следующая итерация↻ повтор; сначала zero_grad()optimizer = Adam([train_mu, train_log_std])«оптимизируем эти тензоры по градиенту»Цикл обучения по KL как замкнутая схемаШесть блоков друг под другом, сверху вниз: обучаемые параметры mu и s, равное log sigma; распределение Q — нормальное со средним mu и дисперсией sigma в квадрате, где sigma равна exp от s; плотности q и p в сэмплах x_i из P; функция потерь, равная среднему log p минус log q; градиенты функции потерь по mu и s; optimizer.step, который сдвигает mu и s против градиента. Стрелка слева ведёт от последнего блока к первому: обновлённые параметры поступают на следующую итерацию.Adam([train_mu, train_log_std])оптимизируем эти тензоры по градиентуПараметры моделиμ, s = log σrequires_grad=Trueстроим QРаспределениеQ = 𝒩(μ, σ²)σ = exp(s)Q.log_prob(xᵢ)Плотности в xᵢq(xᵢ) и p(xᵢ)kl_loss(px, qx)Функция потерьmean(log p(xᵢ) − log q(xᵢ))≈ KL(P ‖ Q)loss.backward()Градиенты∂loss/∂μ, ∂loss/∂sградиентыoptimizer.step()μ ← μ − η·∂loss/∂μs ← s − η·∂loss/∂sxᵢ ~ P, p(xᵢ)новые μ, s → следующая итерация
Оптимизатор получает список обучаемых тензоров — здесь μ и s = log σ, чтобы σ = exp(s) оставалось положительным; каждый из них создан с requires_grad=True, чтобы backward() заполнял его .grad. На каждой итерации Q заново строится из текущих параметров и оценивается в фиксированных сэмплах xᵢ ~ P, затем вычисляется выборочная оценка KL(P‖Q), по ней выполняется обратное распространение ошибки и делается один шаг. Adam, который используется в ноутбуке, шагает вдоль скользящего среднего антиградиента с отдельным размером шага для каждой координаты; показано обновление обычного SGD.

Одномерная подгонка в коде:

# вспомогательные функции: kl_loss (оценка ниже), get_parameters_1d (mu = 0, log_std = 0),
# create_distr_1d и target_1d — одномерная смесь с двумя модами, определённая ниже
train_mu, train_log_std = get_parameters_1d()   # requires_grad=True
optimizer = torch.optim.Adam([train_mu, train_log_std], lr=0.01)

x  = target_1d.sample((1000,))      # фиксированные сэмплы x_i ~ P
px = target_1d.log_prob(x).exp()    # p(x_i), известна для игрушечной цели

for i in range(2000):
    optimizer.zero_grad()           # очищаем .grad от предыдущего шага
    Q  = create_distr_1d(train_mu, train_log_std)   # Normal(mu, exp(log_std))
    qx = Q.log_prob(x).exp()        # q(x_i); может обратиться в 0, см. «В коде»
    loss = kl_loss(px, qx)          # mean(log2 p(x_i) - log2 q(x_i))
    loss.backward()                 # d loss / d mu, d loss / d log_std
    optimizer.step()                # шаг против градиента

Функция потерь — оценка KL методом Монте-Карло#

KL — математическое ожидание по PP, поэтому её можно оценить усреднением по сэмплам x1,…,xN∼Px_1, \dots, x_N \sim P:

DKL(P ∥ Q)=∫p(x)log⁡p(x)q(x) dx=Ex∼P[log⁡p(x)−log⁡q(x)]≈1N∑i=1N[log⁡p(xi)−log⁡q(xi)].\begin{aligned} &D_{\mathrm{KL}}(P\,\|\,Q) = \int p(x)\log\frac{p(x)}{q(x)}\,dx \\ &\quad= \mathbb E_{x\sim P}\big[\log p(x) - \log q(x)\big] \\ &\quad\approx \frac1N\sum_{i=1}^{N}\big[\log p(x_i) - \log q(x_i)\big]. \end{aligned}

По закону больших чисел с ростом NN среднее сходится к математическому ожиданию. Код выше усредняет log⁡2p(xi)−log⁡2q(xi)\log_2 p(x_i) - \log_2 q(x_i), так что его функция потерь измеряется в битах; смена основания лишь умножает функцию потерь и её градиенты на константу 1/ln⁡2≈1.4431/\ln 2 \approx 1.443.

Рисунок

Выборочная оценка KL(P‖Q), используемая в ноутбуке

Оценка KL-дивергенции методом Монте-КарлоВерхний график: красная гауссиана P с центром в 3 и более широкая синяя гауссиана Q с центром в 1.5; сорок коротких красных штрихов вдоль оси отмечают сэмплы из P. Нижний график: кривая log p минус log q, положительная примерно между 2 и 6.4 и отрицательная по обе стороны от этого промежутка. Точки на кривой в позициях сэмплов лежат в основном в положительной области; их среднее, 0.72 ната, оценивает точную KL-дивергенцию, равную 0.63 ната.p(x)q(x)xᵢ ~ P−20246−2−1012среднее = 0.72 (точно 0.63)Q недооценивает p:log p − log q > 0Q переоценивает: < 0,но сэмплов здесь малоlog p − log qx−20246Оценка KL-дивергенции методом Монте-КарлоВерхний график: красная гауссиана P с центром в 3 и более широкая синяя гауссиана Q с центром в 1.5; сорок коротких красных штрихов вдоль оси отмечают сэмплы из P. Нижний график: кривая log p минус log q, положительная примерно между 2 и 6.4 и отрицательная по обе стороны от этого промежутка. Точки на кривой в позициях сэмплов лежат в основном в положительной области; их среднее, 0.72 ната, оценивает точную KL-дивергенцию, равную 0.63 ната.p(x)q(x)xᵢ ~ P−20246−2−1012среднее = 0.72точная KL = 0.63Q занижено:log p − log q > 0Q завышено: < 0сэмплов малоlog p − log qx−20246
Сверху: P = 𝒩(3, 1) — красным, Q = 𝒩(1.5, 1.5²) — синим, 40 сэмплов xᵢ ~ P — штрихами. Снизу: log p(x) − log q(x) с отмеченными сэмплами. Эта разность положительна примерно между 2.0 и 6.4, где Q недооценивает плотность P, и сэмплы попадают в основном туда. Их среднее, 0.723 ната, — шумная оценка (N = 40) точного значения KL(P‖Q) = 0.628 ната; ноутбук использует log₂ и поэтому выдаёт биты (значение в натах, делённое на ln 2).

Сэмплы из другого распределения. Если сэмплы взяты не из PP, а из распределения RR с плотностью rr, каждое слагаемое перевзвешивается множителем p/rp/r (выборка по значимости (importance sampling)):

DKL(P ∥ Q)≈1N∑i=1Nwi[log⁡p(xi)−log⁡q(xi)],wi=p(xi)r(xi),xi∼R,\begin{aligned} D_{\mathrm{KL}}(P\,\|\,Q) &\approx \frac1N\sum_{i=1}^{N} w_i\big[\log p(x_i) - \log q(x_i)\big], \\ w_i &= \frac{p(x_i)}{r(x_i)}, \qquad x_i \sim R , \end{aligned}

что требует r>0r > 0 всюду, где p>0p > 0. При R=PR = P все веса равны 11, и мы возвращаемся к обычной оценке.

Оценка может быть отрицательной. KL никогда не бывает отрицательной, но её оценка на конечной выборке может. При подгонке двумерной гауссианы QQ с полной ковариацией (пять параметров) к цели N((−5,−5),I)\mathcal N\big((-5,-5), \mathbf I\big) с помощью Adam на 1000 фиксированных сэмплах функция потерь после 4800 шагов равна −0.0020-0.0020 бита. Причина в том, что QQ подгоняется на тех же сэмплах, на которых вычисляется функция потерь. Сама цель входит в число гауссиан-кандидатов, поэтому в точке максимального правдоподобия среднее log⁡q\log q по сэмплам не меньше среднего log⁡p\log p, и оценка ≤0\le 0. Насколько она опускается ниже нуля, следует из теоремы Уилкса (Wilks’ theorem): удвоенный прирост суммарного логарифма правдоподобия подогнанной модели по сравнению с истинными параметрами приближённо имеет распределение χ2\chi^2 с kk степенями свободы, где kk — число подгоняемых параметров (Wilks, 1938), так что в среднем оценка лежит на k/(2N)k/(2N) ната ниже нуля. Здесь это 5/2000=0.00255/2000 = 0.0025 ната, или 0.00360.0036 бита. В симуляции 2000 таких подгонок оценка в среднем равна −0.0037-0.0037 бита со стандартным отклонением 0.00240.0024 бита, так что −0.0020-0.0020 — типичное значение. Честная оценка дивергенции подогнанной модели требует новых сэмплов — так же, как любой модели нужны отложенные данные (held-out data).

Чему равны градиенты#

Для одномерной гауссианы log⁡q(x)=−log⁡σ−12log⁡2π−(x−μ)22σ2\log q(x) = -\log\sigma - \tfrac12\log 2\pi - \frac{(x-\mu)^2}{2\sigma^2}. Слагаемое log⁡p(xi)\log p(x_i) не зависит от параметров, поэтому вклад даёт только −log⁡q-\log q (натуральные логарифмы):

∂ loss∂μ=−1N∑i=1Nxi−μσ2,∂ loss∂σ=1N∑i=1N[1σ−(xi−μ)2σ3].\begin{gathered} \frac{\partial\,\text{loss}}{\partial \mu} = -\frac1N\sum_{i=1}^{N}\frac{x_i-\mu}{\sigma^2}, \\ \frac{\partial\,\text{loss}}{\partial \sigma} = \frac1N\sum_{i=1}^{N}\left[\frac1\sigma - \frac{(x_i-\mu)^2}{\sigma^3}\right]. \end{gathered}

Оба градиента обращаются в ноль, когда μ\mu — выборочное среднее, а σ2=1N∑i(xi−μ)2\sigma^2 = \frac1N\sum_i (x_i-\mu)^2 — (смещённая) выборочная дисперсия. Это оценки максимального правдоподобия, как и предсказывала заметка об энтропии. Градиенту плотность pp вообще не нужна: значения p(xi)p(x_i) лишь делают выдаваемое число равным KL. На реальных данных, где pp неизвестна, мы отбрасываем эту константу и вместо KL минимизируем отрицательный логарифм правдоподобия −1N∑ilog⁡q(xi)-\frac1N\sum_i \log q(x_i).

Направление шагов проще всего увидеть на точной KL между двумя одномерными гауссианами:

DKL(N(μP,σP2) ∥ N(μ,σ2))=log⁡σσP+σP2+(μP−μ)22σ2−12.\begin{aligned} &D_{\mathrm{KL}}\big(\mathcal N(\mu_P, \sigma_P^2)\,\|\,\mathcal N(\mu, \sigma^2)\big) \\ &\quad= \log\frac{\sigma}{\sigma_P} + \frac{\sigma_P^2 + (\mu_P - \mu)^2}{2\sigma^2} - \frac12 . \end{aligned}

Она следует из DKL=EP[log⁡p(x)−log⁡q(x)]D_{\mathrm{KL}} = \mathbb E_P[\log p(x) - \log q(x)], если подставить выражение для log⁡q\log q выше и такое же выражение для log⁡p\log p (с μP,σP\mu_P, \sigma_P) и учесть, что EP[(x−μP)2]=σP2\mathbb E_P[(x-\mu_P)^2] = \sigma_P^2 и EP[(x−μ)2]=σP2+(μP−μ)2\mathbb E_P[(x-\mu)^2] = \sigma_P^2 + (\mu_P-\mu)^2. Константы 12log⁡2π\tfrac12\log 2\pi сокращаются, а слагаемое −12-\tfrac12 — это −σP2/(2σP2)-\sigma_P^2/(2\sigma_P^2) из log⁡p\log p.

Рисунок

Подгонка Q = 𝒩(μ, σ²) к P = 𝒩(3, 1) градиентным спуском по KL(P‖Q)

Траектория Q при минимизации KL к гауссовской целиСверху: красная целевая плотность P — нормальное распределение со средним 3 и стандартным отклонением 1 — и семь синих кривых Q на возрастающих итерациях, от бледных и тонких к сплошным и жирным. Первая Q — высокий узкий горб в минус 2. Следующие становятся очень широкими и плоскими, затем смещаются вправо и сужаются, пока последняя, самая жирная кривая почти не совпадает с P. Снизу: KL-дивергенция в логарифмическом масштабе падает примерно с 51 ната почти до нуля за 1600 итераций, с длинным плато около 1.5 ната, пока Q широкое.00.20.40.60.8−6−4−20246810xплотностьP = 𝒩(3, 1)старт: 𝒩(−2, 0.5²)итерация 50:очень широкое,σ = 3.83итерация 1600:μ = 2.92, σ = 1.0110⁻³10⁻²10⁻¹110¹10²040080012001600итерацияKL(P‖Q), натыплато ≈ 1.5: Q широкое и ещё смещеноТраектория Q при минимизации KL к гауссовской целиСверху: красная целевая плотность P — нормальное распределение со средним 3 и стандартным отклонением 1 — и семь синих кривых Q на возрастающих итерациях, от бледных и тонких к сплошным и жирным. Первая Q — высокий узкий горб в минус 2. Следующие становятся очень широкими и плоскими, затем смещаются вправо и сужаются, пока последняя, самая жирная кривая почти не совпадает с P. Снизу: KL-дивергенция в логарифмическом масштабе падает примерно с 51 ната почти до нуля за 1600 итераций, с длинным плато около 1.5 ната, пока Q широкое.00.20.40.60.8−4048xплотностьPстарт: 𝒩(−2, 0.5²)итер. 50:σ = 3.83итер. 1600:μ = 2.92σ = 1.0110⁻³10⁻²10⁻¹110¹10²08001600итерацияKL(P‖Q), натыплато ≈ 1.5:Q широкое, смещено
Q стартует с 𝒩(−2, 0.5²) и показано на итерациях 0, 5, 50, 400, 800, 1100, 1600 (от бледных тонких кривых к сплошным жирным). Поскольку у P есть масса там, где узкое Q почти равно нулю, первые шаги в основном раздувают σ (до 3.83 к итерации 50, тогда как μ лишь медленно сдвигается от −2 до −1.49); затем μ смещается к 3, а σ сжимается до 1. После 1600 шагов μ = 2.92, σ = 1.01. Нижняя панель: KL(P‖Q) в натах в логарифмическом масштабе. Расчёт: KL между гауссианами в замкнутом виде, обычный градиентный спуск по параметрам (μ, log σ) с шагом обучения 0.01.

При обычном градиентном спуске по (μ,log⁡σ)(\mu, \log\sigma), как на рисунке, траектория показывает приоритеты прямой KL (forward KL). Пока QQ узкое и находится далеко, большая часть массы PP лежит там, где q≈0q \approx 0, и log⁡p−log⁡q\log p - \log q там огромно. Дешевле всего расширить QQ: на первых шагах σ\sigma резко растёт, а μ\mu едва сдвигается. Когда QQ накрывает PP, μ\mu смещается к цели, а σ\sigma сжимается обратно до ширины PP. Порядок определяется величиной градиентов: из формулы в замкнутом виде ∂/∂log⁡σ=1−σP2+(μP−μ)2σ2\partial/\partial\log\sigma = 1 - \frac{\sigma_P^2 + (\mu_P-\mu)^2}{\sigma^2} растёт как (μP−μ)2/σ2(\mu_P-\mu)^2/\sigma^2, тогда как ∂/∂μ=μ−μPσ2\partial/\partial\mu = \frac{\mu-\mu_P}{\sigma^2} растёт лишь как ∣μP−μ∣/σ2\lvert\mu_P-\mu\rvert/\sigma^2. Adam, который нормирует шаг по каждой координате, сдвигает оба параметра примерно с одинаковой скоростью и приходит к тому же оптимуму другим путём.

Что предполагает KL#

Начнём с формулы для непрерывных распределений (Kullback and Leibler, 1951):

DKL(P ∥ Q)=∫p(x) log⁡p(x)q(x) dx.D_{\mathrm{KL}}(P\,\|\,Q) = \int p(x)\,\log\frac{p(x)}{q(x)}\,dx .

Чтобы она была осмысленным конечным числом, должны выполняться условия (a)–(c); (d) и (e) — это выбор, который нужно делать согласованно (Cover and Thomas, 2006, §8.5; Murphy, 2023, §5.1).

(a) Общий носитель#

Носитель (support) распределения — множество его возможных значений, supp⁡p={x:p(x)>0}\operatorname{supp} p = \lbrace x : p(x) > 0\rbrace. Если p(x)>0p(x) > 0, но q(x)=0q(x) = 0 на области, которой PP даёт положительную вероятность, то там log⁡p(x)q(x)=∞\log\frac{p(x)}{q(x)} = \infty и дивергенция бесконечна.

Формально DKL(P ∥ Q)D_{\mathrm{KL}}(P\,\|\,Q) конечна, только если PP абсолютно непрерывно относительно QQ, что записывается как P≪QP \ll Q: каждое множество, которому QQ даёт нулевую вероятность, имеет нулевую и PP-вероятность. Где у PP есть масса, она должна быть и у QQ. Это одна из причин, по которым модели, обучаемые методом максимального правдоподобия, используют всюду положительные плотности, например гауссианы: плотность без «дыр» избавляет от бесконечностей из-за несовпадения носителей: потеря на сэмпле −log⁡q(xi)-\log q(x_i) конечна в каждой наблюдённой точке. Конечности ожидаемой потери или KL положительность не гарантирует: в условии (b) ниже обе плотности всюду положительны, и всё же DKL=∞D_{\mathrm{KL}} = \infty. Сама по себе положительность не делает модель размытой. Но в сочетании с прямой KL, которая наказывает за любую пропущенную массу, модель, неспособная представить данные, размазывает вероятность между модами и вокруг них (см. раздел «Одна гауссиана, две моды»). Это одно из предлагаемых объяснений размытых сэмплов у моделей изображений, обученных по правдоподобию (Theis, van den Oord and Bethge, 2016).

Рисунок

Общий носитель: у Q не должно быть дыр там, где живёт P

Модель с дырами и размытая модельДва графика одной и той же красной плотности стандартного нормального распределения P. На первом Q — плоский прямоугольник между минус 1.5 и 1.5 и ноль вне его; хвосты P вне прямоугольника закрашены красным и подписаны «p больше 0, q равно 0», поэтому log p по q бесконечен и KL бесконечна. На втором Q — более широкая синяя гауссиана, всюду положительная, и KL конечна, около 0.128 ната.Q с дырамиKL(P‖Q) = ∞−1.51.5QPp > 0, q = 0⇒ log p/q = ∞q = 0«Размытая» гауссиана QKL(P‖Q) = 0.128 натаPq > 0всюду−202Модель с дырами и размытая модельДва графика одной и той же красной плотности стандартного нормального распределения P. На первом Q — плоский прямоугольник между минус 1.5 и 1.5 и ноль вне его; хвосты P вне прямоугольника закрашены красным и подписаны «p больше 0, q равно 0», поэтому log p по q бесконечен и KL бесконечна. На втором Q — более широкая синяя гауссиана, всюду положительная, и KL конечна, около 0.128 ната.Q с дырамиKL(P‖Q) = ∞−1.51.5QPp > 0, q = 0⇒ log p/q = ∞q = 0«Размытая» гауссиана QKL(P‖Q) = 0.128 натаPq > 0всюду−202
P = 𝒩(0, 1) — красным. Слева: Q равномерно на [−1.5, 1.5]. В закрашенных хвостах сосредоточено 13.4% массы P, и там p(x) > 0, а q(x) = 0, поэтому подынтегральное выражение p log(p/q) бесконечно и KL(P‖Q) = ∞. Справа: «размытая» гауссиана Q = 𝒩(0, 1.5²) положительна всюду, и KL(P‖Q) = 0.128 ната.

Условие одностороннее. Точки, где q(x)>0q(x) > 0, но p(x)=0p(x) = 0, вносят в DKL(P ∥ Q)D_{\mathrm{KL}}(P\,\|\,Q) вклад 0⋅log⁡0q(x)=00\cdot\log\frac{0}{q(x)} = 0; они важны только для обратного направления.

(b) Интегрируемость#

Интеграл должен сходиться. Совпадения носителей для этого недостаточно. Пусть, например, PP — стандартное распределение Коши, а Q=N(0,σ2)Q = \mathcal N(0, \sigma^2). Обе плотности всюду положительны, но log⁡pq\log\frac{p}{q} растёт как x22σ2\frac{x^2}{2\sigma^2}, а EP[x2]=∞\mathbb E_P[x^2] = \infty, поэтому DKL(P ∥ Q)=∞D_{\mathrm{KL}}(P\,\|\,Q) = \infty. Модель с лёгкими хвостами не может подогнать по KL данные с тяжёлыми хвостами.

(c) Нормированные плотности#

pp и qq должны быть плотностями вероятности (или функциями вероятности): неотрицательными и с интегралом (или суммой), равным 11. KL не определена для ненормированных значений, например логитов классификатора; их сначала нужно пропустить через softmax. Объект torch.distributions возвращает из log_prob нормированные логарифмы плотности.

(d) Направление#

KL не симметрична, DKL(P ∥ Q)≠DKL(Q ∥ P)D_{\mathrm{KL}}(P\,\|\,Q) \ne D_{\mathrm{KL}}(Q\,\|\,P), поэтому нужно решить, какое распределение играет роль истины, а какое — приближения:

  • DKL(P ∥ Q)D_{\mathrm{KL}}(P\,\|\,Q), прямая KL, усредняет по PP и наказывает за пропущенные моды: QQ должно покрывать всё, где живёт PP. Это направление максимального правдоподобия.
  • DKL(Q ∥ P)D_{\mathrm{KL}}(Q\,\|\,P), обратная KL, усредняет по QQ и наказывает за лишнюю массу: QQ не должно растекаться туда, где P≈0P \approx 0. Это направление используется в вариационном выводе (variational inference), в том числе в VAE.
Рисунок

Какое направление что наказывает: пропущенные моды и лишняя масса

Пропущенные моды и лишняя массаДва графика одной и той же красной бимодальной плотности P с пиками в минус 2.5 и 2.5. На первом узкая синяя Q сидит только на правом пике; левый пик закрашен и подписан как пропущенная мода, прямая дивергенция KL между P и Q — около 12 нат, а обратная — около 0.69. На втором широкая синяя гауссиана покрывает оба пика; область, где Q выше P, — в середине и на внешних хвостах — закрашена и подписана как лишняя масса, и теперь обратная дивергенция, около 1.54 ната, больше прямой, около 0.62.Q пропускает модуKL(P‖Q) = 12.06KL(Q‖P) = 0.69−2.502.5QPпропуск моды: p > 0, q ≈ 0за это наказывает KL(P‖Q)Q растекается туда, где P нетKL(P‖Q) = 0.62KL(Q‖P) = 1.54−2.502.5QPлишняя масса: q > 0, p ≈ 0за это наказывает KL(Q‖P)Пропущенные моды и лишняя массаДва графика одной и той же красной бимодальной плотности P с пиками в минус 2.5 и 2.5. На первом узкая синяя Q сидит только на правом пике; левый пик закрашен и подписан как пропущенная мода, прямая дивергенция KL между P и Q — около 12 нат, а обратная — около 0.69. На втором широкая синяя гауссиана покрывает оба пика; область, где Q выше P, — в середине и на внешних хвостах — закрашена и подписана как лишняя масса, и теперь обратная дивергенция, около 1.54 ната, больше прямой, около 0.62.Q пропускает модуKL(P‖Q) = 12.06KL(Q‖P) = 0.69−2.502.5QPпропуск моды: p > 0, q ≈ 0за это наказывает KL(P‖Q)Q растекается туда, где P нетKL(P‖Q) = 0.62KL(Q‖P) = 1.54−2.502.5QPлишняя масса: q > 0, p ≈ 0за это наказывает KL(Q‖P)
P (красная) — смесь с равными весами 𝒩(±2.5, 0.7²). Слева: Q сидит на одной моде. Пропущенная мода — это область, где живёт P, а Q почти равно нулю, поэтому прямая дивергенция KL(P‖Q) = 12.06 ната велика, тогда как обратная KL(Q‖P) = 0.69 ≈ ln 2. Справа: Q = 𝒩(0, 2.60²) покрывает обе моды (это лучшая одиночная гауссиана для KL(P‖Q)), но кладёт массу между ними и за ними, где P ≈ 0 (закрашено), поэтому теперь больше KL(Q‖P) = 1.54, а KL(P‖Q) = 0.62. Все значения вычислены численным интегрированием.

(e) Непрерывные и дискретные распределения#

Для дискретных распределений интеграл становится суммой, DKL(P ∥ Q)=∑xp(x)log⁡p(x)q(x)D_{\mathrm{KL}}(P\,\|\,Q) = \sum_{x} p(x)\log\frac{p(x)}{q(x)}. Смешение двух случаев даёт бесконечную дивергенцию. Если у PP есть атом в точке xx, то Q({x})=0Q(\lbrace x\rbrace) = 0 для любого распределения QQ с плотностью, поэтому PP не абсолютно непрерывно относительно QQ и DKL(P ∥ Q)=∞D_{\mathrm{KL}}(P\,\|\,Q) = \infty по условию (a). Вот почему для непрерывных данных максимальное правдоподобие понимают как выборочную оценку DKL(P ∥ Q)D_{\mathrm{KL}}(P\,\|\,Q) для лежащей в основе плотности pp, а не как KL эмпирического распределения сэмплов (ср. заметку об энтропии, где для дискретных исходов такое прочтение точно).

Допущения моделирования#

Когда KL используется как функция потерь при обучении, на веру принимается ещё несколько вещей:

  • Представимость. Семейство QθQ_\theta способно выразить нужную форму. Одна гауссиана может точно совпасть с целевым распределением из одной гауссианы, но не со смесью двух компонент; что происходит тогда, показывает последний раздел.
  • Дифференцируемость. log⁡qθ(x)\log q_\theta(x) должна быть дифференцируема по θ\theta, чтобы можно было применить градиентный спуск. Репараметризация σ=elog⁡σ\sigma = e^{\log\sigma} к тому же снимает ограничения с параметров, так что шаг градиента никогда не даст отрицательное σ\sigma.
  • Вычислимость. Прямой KL нужны сэмплы из PP и значения log⁡q\log q в них. Обратной KL нужны сэмплы из QQ (репараметризованные, чтобы получить градиенты) и значения log⁡q\log q и log⁡p\log p в них. Для реальных данных доступно только первое, поэтому максимальное правдоподобие использует прямое направление.

В коде. У каждого допущения есть конкретное место в коде. QQ — это Normal или MultivariateNormal, всюду положительное, поэтому (a) математически выполняется при любом целевом распределении. Численно оно всё же может нарушиться. Код вычисляет qx = Q.log_prob(x).exp(), а затем qx.log2(), и в 32-битной арифметике с плавающей точкой экспонента обращается в 00 (underflow), как только log⁡q(x)\log q(x) опускается ниже примерно −103-103: при σ≈1\sigma \approx 1 это около 1414 стандартных отклонений от μ\mu, а порог сдвигается вместе с log⁡σ\log\sigma. Из-за этого функция потерь становится бесконечной, когда QQ стартует далеко от PP. Работа напрямую с log_prob позволяет этого избежать. Та же осторожность нужна и для двухкомпонентных целевых распределений ниже. Их логарифм плотности log⁡(12p1(x)+12p2(x))\log\big(\tfrac12 p_1(x) + \tfrac12 p_2(x)\big) вычисляется из логарифмов плотности компонент a=log⁡p1(x)+log⁡12a = \log p_1(x) + \log\tfrac12 и b=log⁡p2(x)+log⁡12b = \log p_2(x) + \log\tfrac12 как logaddexp⁡(a,b)=max⁡(a,b)+log⁡(1+e−∣a−b∣)\operatorname{logaddexp}(a, b) = \max(a, b) + \log\big(1 + e^{-|a - b|}\big); экспонента большого отрицательного числа в этой формуле никогда не стоит отдельно, поэтому результат остаётся конечным вдали от обеих компонент. Ковариация LL⊤\mathbf L\mathbf L^\top с экспоненцированной диагональю сохраняет QQ корректной нормированной плотностью, как требует (c). Целевое распределение — известная гауссиана или смесь, поэтому px можно вычислить. Наконец, функция потерь усредняет по x ~ P, что фиксирует направление DKL(P ∥ Q)D_{\mathrm{KL}}(P\,\|\,Q).

Одна гауссиана, две моды#

Если целевое распределение — одна гауссиана, подгонка по KL просто восстанавливает его. Интересен случай, когда семейство моделей не может представить целевое распределение. В двумерном случае целевое распределение — смесь с равными весами N((−5,−5),I)\mathcal N\big((-5,-5), \mathbf I\big) и N((4,4),I)\mathcal N\big((4,4), \mathbf I\big). В одномерном оно равно

P=12 N(−3, 0.52)+12 N(−8, 0.52),P = \tfrac12\,\mathcal N(-3,\, 0.5^2) + \tfrac12\,\mathcal N(-8,\, 0.5^2),

а модель стартует с Q=N(0,1)Q = \mathcal N(0, 1). Сравниваются четыре функции потерь: прямая KL, обратная KL, JS и функция потерь наименьших квадратов на значениях плотности. Ни одна из них не удовлетворительна, и у каждой на то своя причина. Те же компромиссы снова возникают в разных генеративных моделях, поэтому эту игрушечную задачу стоит разобрать подробно (Huszár, 2015; Theis, van den Oord and Bethge, 2016).

Вдали от цели доминирует пропущенная мода#

Начальное Q=N(0,1)Q = \mathcal N(0, 1) едва достаёт до дальней моды в −8-8. Гауссиана никогда не равна нулю в точности, но в восьми стандартных отклонениях от среднего она практически равна нулю. Там log⁡p(x)q(x)\log\frac{p(x)}{q(x)} огромен, и дальняя мода доминирует во всей дивергенции. Если бы QQ было там в точности нулём, дивергенция была бы бесконечной, как говорит условие (a). Для гауссовского QQ прямая KL тем не менее остаётся конечной, и её градиент по μ\mu, (μ−EP[x])/σ2(\mu - \mathbb E_P[x])/\sigma^2, здесь велик. Перекрытие важно, во-первых, численно, потому что в 32-битной арифметике с плавающей точкой qq обращается в 00 (см. В коде выше), а во-вторых, для ограниченных функций потерь — JS и наименьших квадратов, — градиенты которых без перекрытия исчезают (см. таблицу ниже).

Рисунок

Когда Q не покрывает часть носителя P

Прямая KL огромна там, где Q почти равно нулю, а P — нетВерхняя панель: красная целевая плотность с модами в -8 и -3 и синяя плотность модели 𝒩(0, 1) с центром в 0. Серая полоса левее x = -5.1 отмечает область, где q меньше одной миллионной, а p всё ещё положительна. В точке x = -8 q примерно равна 5, умноженному на 10 в степени -15, а log p по q — около 32 нат. Нижняя панель: подынтегральное выражение p(x) log p(x)/q(x) имеет высокий пик около 12.8 на дальней моде и маленький пик в -3; его площадь, KL-дивергенция, равна 17.9 ната.q(x) < 10⁻⁶, но p(x) > 0−10−8−6−4−202PQ = 𝒩(0, 1)q(−8) ≈ 5·10⁻¹⁵Вклад в KL(P‖Q): p(x) log p(x)/q(x)04812−10−8−6−4−202здесь log p/q ≈ 32 натплощадь = KL(P‖Q) ≈ 17.9 натаесли q(x) = 0 при p(x) > 0:KL(P‖Q) = ∞Прямая KL огромна там, где Q почти равно нулю, а P — нетВерхняя панель: красная целевая плотность с модами в -8 и -3 и синяя плотность модели 𝒩(0, 1) с центром в 0. Серая полоса левее x = -5.1 отмечает область, где q меньше одной миллионной, а p всё ещё положительна. В точке x = -8 q примерно равна 5, умноженному на 10 в степени -15, а log p по q — около 32 нат. Нижняя панель: подынтегральное выражение p(x) log p(x)/q(x) имеет высокий пик около 12.8 на дальней моде и маленький пик в -3; его площадь, KL-дивергенция, равна 17.9 ната.q(x) < 10⁻⁶,но p(x) > 0q(−8) ≈ 5·10⁻¹⁵−10−8−6−4−202PQ = 𝒩(0, 1)Вклад в KL(P‖Q):p(x) log p(x)/q(x)04812−10−8−6−4−202здесь log p/q ≈ 32 натплощадь = KL(P‖Q) ≈ 17.9 натаесли q(x) = 0 при p(x) > 0:KL(P‖Q) = ∞
Сверху: бимодальное целевое распределение P из ноутбука и начальная модель Q = 𝒩(0, 1). Левее x ≈ −5.1 плотность модели меньше 10⁻⁶, но у P там всё ещё целая мода. Снизу: вклад каждой точки p(x) log p(x)/q(x) в KL(P‖Q); дальняя мода доминирует в сумме, равной 17.9 ната. Если бы q была в точности равна нулю там, где p > 0, логарифм отношения и дивергенция были бы бесконечными.

Прямая KL покрывает обе моды, обратная выбирает одну#

Минимизация DKL(P ∥ Q)D_{\mathrm{KL}}(P\,\|\,Q) заставляет одну гауссиану покрыть обе моды с большим разбросом. Функция потерь усредняет log⁡pq\log\frac{p}{q} по сэмплам PP, поэтому любая область, где у PP есть масса, а QQ мало, наказывается очень сильно. Для гауссовского QQ оптимум — точное сопоставление моментов (moment matching). Если записать прямую KL как

DKL(P ∥ Q)=−H(P)−EP[log⁡q(x)],D_{\mathrm{KL}}(P\,\|\,Q) = -H(P) - \mathbb E_P[\log q(x)],

то от QQ зависит только второе слагаемое, а для гауссианы log⁡q\log q зависит от xx только через xx и xx⊤xx^{\top}. Приравнивая нулю производные по μ\boldsymbol\mu и Σ\boldsymbol\Sigma, получаем

μ∗=EP[x],Σ∗=Cov⁡P[x]\boldsymbol\mu^\ast = \mathbb E_P[x],\qquad \boldsymbol\Sigma^\ast = \operatorname{Cov}_P[x]

(Bishop, 2006, §10.7). Для одномерной цели это даёт μ∗=−5.5\mu^\ast = -5.5 и σ∗2=0.25+2.52=6.5\sigma^{\ast2} = 0.25 + 2.5^2 = 6.5, так что σ∗≈2.55\sigma^\ast \approx 2.55: каждая компонента вносит собственную дисперсию 0.250.25, а разброс двух средних вокруг −5.5-5.5 добавляет 2.522.5^2. Для двумерной цели получаются среднее (−0.5,−0.5)(-0.5, -0.5) и ковариация (21.2520.2520.2521.25)\begin{pmatrix} 21.25 & 20.25 \\ 20.25 & 21.25\end{pmatrix}: одна вытянутая гауссиана вдоль диагонали, проходящей через обе моды, с самой плотной частью в пустом промежутке между ними. В этом оптимуме дивергенция равна 1.1701.170 ната (1.691.69 бита). Подгонка с Adam (шаг обучения 0.10.1, 2000 фиксированных сэмплов, старт с N(0,I)\mathcal N(\mathbf 0, \mathbf I)) приходит именно к этой картине с оценкой 1.6691.669 бита после 4800 шагов; разрыв в 0.0190.019 бита меньше стандартного отклонения оценки по 2000 сэмплам — около 0.0230.023 бита.

Обратная дивергенция DKL(Q ∥ P)D_{\mathrm{KL}}(Q\,\|\,P) усредняет по сэмплам QQ. Она наказывает QQ за массу там, где PP мало, и не обращает внимания на те части PP, которые QQ игнорирует, поэтому QQ захватывает одну моду (Bishop, 2006, §10.1.2, рисунок 10.3; Minka, 2005). Для двух равных, хорошо разделённых мод положение точно на одной из них стоит всего DKL(Q ∥ P)≈ln⁡2D_{\mathrm{KL}}(Q\,\|\,P) \approx \ln 2: на этой моде p≈q/2p \approx q/2, поэтому log⁡qp≈ln⁡2\log\frac{q}{p} \approx \ln 2 всюду, где у QQ есть масса.

Рисунок

Подгонка одной гауссианы к двум модам: прямая и обратная KL

Подгонка гауссианы к бимодальному целевому распределению по прямой и обратной KLДве панели с одним и тем же красным бимодальным целевым распределением, пики в x = -8 и x = -3. Верхняя панель: гауссиана, минимизирующая KL(P‖Q), со средним −5.50 и стандартным отклонением 2.55 — широкая синяя кривая, охватывающая обе моды, с пиком в пустом промежутке между ними; KL(P‖Q) = 0.94 ната. Нижняя панель: гауссиана, минимизирующая KL(Q‖P), со средним −3.00 и стандартным отклонением 0.50 — узкая синяя кривая только на правой моде, так что сплошная кривая игнорирует моду в -8; KL(Q‖P) = 0.69 ната, около ln 2. Пунктирная кривая на левой моде отмечает зеркальное решение, столь же хорошее.Прямая KL: минимум KL(P‖Q) по Q−10−8−6−4−2PОбратная KL: минимум KL(Q‖P) по Q−10−8−6−4−2покрывает обе моды, широкаяздесь P ≈ 0оптимум Q:μ = −5.50σ = 2.55KL(P‖Q) = 0.94захватываетодну модуμ = −3.00σ = 0.50KL(Q‖P) = 0.69≈ ln 2игнорируетсясплошной;пунктир:зеркальное,не хужеПодгонка гауссианы к бимодальному целевому распределению по прямой и обратной KLДве панели с одним и тем же красным бимодальным целевым распределением, пики в x = -8 и x = -3. Верхняя панель: гауссиана, минимизирующая KL(P‖Q), со средним −5.50 и стандартным отклонением 2.55 — широкая синяя кривая, охватывающая обе моды, с пиком в пустом промежутке между ними; KL(P‖Q) = 0.94 ната. Нижняя панель: гауссиана, минимизирующая KL(Q‖P), со средним −3.00 и стандартным отклонением 0.50 — узкая синяя кривая только на правой моде, так что сплошная кривая игнорирует моду в -8; KL(Q‖P) = 0.69 ната, около ln 2. Пунктирная кривая на левой моде отмечает зеркальное решение, столь же хорошее.Прямая KL: минимум KL(P‖Q) по Q−10−8−6−4−2PОбратная KL: минимум KL(Q‖P) по Q−10−8−6−4−2покрывает обе моды, широкаяздесь P ≈ 0лучшая гауссиана: μ = −5.50, σ = 2.55KL(P‖Q) = 0.94 натавыбираетодну модулучшая гауссиана: μ = −3.00, σ = 0.50KL(Q‖P) = 0.69 ната ≈ ln 2сплошная кривая игнорирует моду в −8;пунктир: зеркальное решение, не хуже
Целевое распределение — одномерная смесь из ноутбука P = ½𝒩(−3, 0.5²) + ½𝒩(−8, 0.5²). Лучшая одиночная гауссиана по KL(P‖Q) (найденная перебором по сетке) имеет μ = −5.50, σ = 2.55: она совпадает с P по среднему и дисперсии. Её самая плотная часть и около трети её массы лежат в промежутке, где P почти равно нулю. По KL(Q‖P) лучшая гауссиана сидит на одной моде (μ = −3.00, σ = 0.50); другая мода — столь же хорошее решение.

JS тоже не покрывает моды#

JS никогда не обращается в бесконечность, но проблему покрытия мод не решает. JS-подгонка двумерной смеси с Adam (шаг обучения 0.10.1, 5000 итераций), начатая с μ=(−2,−2)\boldsymbol\mu = (-2,-2), заканчивается на μ≈(−4.99,−5.06)\boldsymbol\mu \approx (-4.99, -5.06) с почти единичной ковариацией при значении функции потерь 0.2730.273 бита. Это гауссиана на моде в (−5,−5)(-5,-5); мода в (4,4)(4,4) отброшена. Функция потерь в этом запуске — взвешенный вариант, 0.7 DKL(P ∥ M)+0.3 DKL(Q ∥ M)0.7\,D_{\mathrm{KL}}(P\,\|\,M) + 0.3\,D_{\mathrm{KL}}(Q\,\|\,M) в битах. Для него точный захват одной моды даёт 0.2700.270 бита, что близко к достигнутому значению; для симметричной JS получилось бы 34log⁡243≈0.311\tfrac34\log_2\tfrac43 \approx 0.311 бита. С одномерной целью всё заканчивается так же. Обычный градиентный спуск (шаг обучения 0.10.1, 5000 новых сэмплов каждого распределения на каждом шаге) из N(0,1)\mathcal N(0, 1) после 1800 шагов находится в μ=−2.995\mu = -2.995, σ=0.495\sigma = 0.495, на ближней моде в −3-3, с тем же значением взвешенной функции потерь 0.2700.270 бита. Пиковая плотность QQ там, 0.810.81, вдвое больше, чем у цели, 0.400.40: вся масса QQ сосредоточена на моде, которая содержит половину массы PP. Симметричная JS ведёт себя так же: для одномерной цели её лучшая одиночная гауссиана тоже располагается на одной моде (см. таблицу ниже).

Оценка JS по сэмплам. Каждая половина JS — математическое ожидание по своему распределению,

DJS(P ∥ Q)=12 Ex∼P[log⁡p(x)m(x)]+12 Ey∼Q[log⁡q(y)m(y)],m=12(p+q),\begin{aligned} D_{\mathrm{JS}}(P\,\|\,Q) &= \tfrac12\,\mathbb E_{x\sim P}\Big[\log\frac{p(x)}{m(x)}\Big] + \tfrac12\,\mathbb E_{y\sim Q}\Big[\log\frac{q(y)}{m(y)}\Big], \\ m &= \tfrac12(p + q), \end{aligned}

поэтому для оценки нужны две выборки: x1,…,xN∼Px_1, \dots, x_N \sim P для первого слагаемого и y1,…,yN∼Qy_1, \dots, y_N \sim Q для второго, и каждое слагаемое усредняется так же, как в оценке KL выше. Плотность смеси вычисляется в логарифмической шкале, log⁡m=logaddexp⁡(log⁡p+log⁡12, log⁡q+log⁡12)\log m = \operatorname{logaddexp}\big(\log p + \log\tfrac12,\ \log q + \log\tfrac12\big), как и для двухкомпонентной цели. Второе слагаемое зависит от параметров QQ ещё и через сэмплы yjy_j. Чтобы его градиент был верным, сэмплы нужно брать с помощью трюка репараметризации (reparameterization trick), y=μ+σεy = \mu + \sigma\varepsilon с ε∼N(0,1)\varepsilon \sim \mathcal N(0, 1): тогда обратное распространение ошибки учитывает, как они смещаются при изменении μ\mu и σ\sigma. В приведённых выше запусках JS сэмплы yjy_j берутся без него, поэтому их градиенты эту зависимость не учитывают.

У ограниченности есть и вторая цена. Когда QQ и PP почти не перекрываются, JS уже близка к своему максимуму ln⁡2\ln 2 и почти плоская, поэтому её градиент слаб. Для одномерной цели при начальном N(0,1)\mathcal N(0,1) она равна 0.6450.645 ната — уже 93%93\% от ln⁡2\ln 2. То же насыщение — причина, по которой исходная минимаксная целевая функция GAN, равная 2 DJS−ln⁡42\,D_{\mathrm{JS}} - \ln 4 при оптимальном дискриминаторе, даёт затухающие градиенты генератора (Arjovsky and Bottou, 2017, теорема 2.4; см. заметку о GAN и GAN Вассерштейна).

Функция потерь наименьших квадратов на плотностях чувствительна к масштабу#

Наивная альтернатива — напрямую сравнивать значения плотности:

LLS=1N∑i=1N(q(xi)−p(xi))2,xi∼P.\mathcal L_{\mathrm{LS}} = \frac1N \sum_{i=1}^{N} \bigl(q(x_i) - p(x_i)\bigr)^2 , \qquad x_i \sim P .

Значения плотности зависят от масштаба данных. Если растянуть каждую координату в cc раз, все плотности в dd измерениях делятся на cdc^{d}. Тогда квадраты разностей, а с ними и функция потерь, уменьшаются в c2dc^{2d} раз, а градиенты — в сопоставимое число раз. При обычном SGD шаг обучения, подходящий для одного масштаба, не годится для другого. Адаптивные оптимизаторы вроде Adam компенсируют постоянный множитель, но не решают вторую проблему: когда QQ не перекрывается с PP, в точках данных q(xi)≈0q(x_i) \approx 0, и функция потерь остаётся около константы EP[p(x)2]\mathbb E_P[p(x)^2], что почти не даёт градиента. У KL нет ни одной из этих проблем. Отношение p/qp/q, а значит, и KL не меняются при изменении масштаба. А −log⁡q(xi)-\log q(x_i) вдали от μ\mu растёт как (xi−μ)2/2σ2(x_i-\mu)^2/2\sigma^2, так что при удалении QQ от PP градиент KL растёт, а не исчезает (∣∂/∂μ∣=5.5\lvert\partial/\partial\mu\rvert = 5.5 при начальном QQ в таблице ниже).

У функции потерь наименьших квадратов к тому же несколько минимумов. Для одномерной цели её глобальный минимум — широкая гауссиана из таблицы ниже (σ≈2.53\sigma \approx 2.53), но гауссиана на одной моде, N(−3,1.212)\mathcal N(-3, 1.21^2), — локальный минимум (значение 0.04950.0495 против 0.04700.0470). В двумерном случае гауссиана на одной моде, N((4,4),1.582 I)\mathcal N\big((4,4), 1.58^2\,\mathbf I\big), — локальный минимум со значением 0.001130.00113; наименьшее значение, которое находит численный поиск, равно 0.001020.00102, у гауссианы с центром в (−0.5,−0.5)(-0.5,-0.5), вытянутой вдоль диагонали (стандартное отклонение 6.56.5 вдоль неё и 0.430.43 поперёк). К какому минимуму придёт градиентный спуск, зависит от начальной точки. Подгонка с Adam (шаг обучения 0.0010.001, 5000 итераций, 1000 сэмплов), начатая с N((1,1),I)\mathcal N\big((1,1), \mathbf I\big), которое перекрывается только с модой в (4,4)(4,4), заканчивается гауссианой QQ с центром на этой моде, более широкой, чем сама мода; мода в (−5,−5)(-5,-5) игнорируется. Её сэмплы почти ничего не вносят в градиент, потому что там q≈0q \approx 0. QQ получается шире компоненты, потому что гауссиана, вся масса которой сосредоточена на моде с весом 12\tfrac12, была бы там вдвое плотнее PP, а расширение понижает её пик. Больший шаг обучения или вчетверо большее число итераций приводят к той же моде.

Сравнение четырёх функций потерь#

Одномерная цель выше, натуральные логарифмы. Функция потерь наименьших квадратов EP[(q−p)2]\mathbb E_P\big[(q-p)^2\big] измеряется не в натах: её единица — квадрат плотности, поэтому её значение зависит от масштаба данных.

Одна гауссиана QQDKL(P ∥ Q)D_{\mathrm{KL}}(P\,\Vert\,Q)DKL(Q ∥ P)D_{\mathrm{KL}}(Q\,\Vert\,P)DJSD_{\mathrm{JS}}LS
начальная N(0,1)\mathcal N(0, 1)17.8817.8819.5019.500.6450.6450.09010.0901
с сопоставленными моментами N(−5.5, 6.5)\mathcal N(-5.5,\, 6.5), σ≈2.55\sigma \approx 2.550.936\mathbf{0.936}3.7093.7090.2550.2550.0470\mathbf{0.0470}
одна мода N(−3, 0.52)\mathcal N(-3,\, 0.5^2)24.3124.310.693\mathbf{0.693}0.216\mathbf{0.216}0.09190.0919
∣∂/∂μ∣\lvert\partial/\partial\mu\rvert при начальном QQ5.55.512.012.00.0700.0700.00450.0045

Жирным для каждой функции потерь выделен лучший из трёх кандидатов. Для KL, обратной KL и JS выделенное значение — также глобальный оптимум функции потерь по всем (μ,σ)(\mu, \sigma), найденный перебором по сетке; оптимум наименьших квадратов находится при σ≈2.53\sigma \approx 2.53, то есть практически совпадает с гауссианой с сопоставленными моментами. Значения вычислены численным интегрированием. Прямая KL и наименьшие квадраты предпочитают широкую гауссиану, обратная KL и JS — одну моду. Последняя строка показывает, насколько сильно каждая функция потерь тянет начальное QQ к данным: KL даёт сильный сигнал, а JS и наименьшие квадраты почти плоские.

Подгонка по прямой KL с Adam (шаг обучения 0.010.01, 1000 фиксированных сэмплов) приходит к гауссиане с сопоставленными моментами: μ=−5.494\mu = -5.494, σ=2.566\sigma = 2.566, с оценкой 1.3001.300 бита. Точное значение в оптимуме — 0.9360.936 ната, или 1.3501.350 бита; разница в 0.050.05 бита меньше двух стандартных отклонений оценки по 1000 сэмплам (каждое около 0.030.03 бита).

Как ведут себя градиенты во время обучения#

Дополнительный материал: как меняются модули градиентов в двух запусках обучения, один из которых использует неполную оценку JS. Остальная часть заметки на него не опирается.

Последняя строка таблицы — снимок в начальной точке. На протяжении всей подгонки градиенты KL и JS ведут себя по-разному (одномерная цель, модули в битах на единицу μ\mu и на единицу log⁡σ\log\sigma):

  • Прямая KL на фиксированных сэмплах: большие и гладкие, в конце нулевые. При начальном N(0,1)\mathcal N(0, 1) градиенты равны 7.97.9 по μ\mu и 51.651.6 по log⁡σ\log\sigma (по формулам для градиентов выше это 5.55.5 и 35.7535.75 ната, делённые на ln⁡2\ln 2). Градиент по log⁡σ\log\sigma, намного больший, обваливается первым — как только QQ становится достаточно широким, чтобы накрыть обе моды. Градиент по μ\mu убывает медленнее и держится на уровне нескольких десятых бита, пока QQ перемещается к цели. Поскольку сэмплы фиксированы, функция потерь — детерминированная функция от (μ,log⁡σ)(\mu, \log\sigma), и по мере приближения к её минимуму оба градиента стремятся к нулю.
  • JS с новыми сэмплами: маленькие и шумные. Этот запуск — диагностика, а не измерение настоящего градиента JS: он сэмплирует yjy_j без приёма репараметризации, поэтому его градиенты не учитывают зависимость второго слагаемого от сэмплов. В описанном выше запуске обычного градиентного спуска (шаг обучения 0.10.1, 5000 новых сэмплов PP и QQ на каждом шаге) ни один градиент не превышает примерно 0.110.11 бита. Модули дважды достигают пика: около шага 40, пока QQ расширяется, и около шага 720, когда оно сжимается к моде в −3-3. После этого они не затухают, а колеблются между 00 и примерно 0.040.04 бита вплоть до последнего из 2000 шагов. На каждом шаге функция потерь оценивается по новым сэмплам, поэтому её градиент несёт шум оценки Монте-Карло, который не исчезает в оптимуме, и при постоянном шаге обучения параметры продолжают на него реагировать.

Здесь смешаны три эффекта, и их стоит разделять. Геометрия целевой функции: JS почти плоская вдали от цели, что показывает последняя строка таблицы по точным интегралам, а KL даёт там сильный сигнал и чистую остановку в оптимуме. Оценка: градиенты запуска с JS неполны, поэтому точная форма его траектории мало говорит о настоящем градиенте JS. Сэмплирование: при новых сэмплах на каждом шаге (resampling) любой оценённый градиент сохраняет шум Монте-Карло и в оптимуме, так что подгонка с постоянным шагом обучения никогда точно не останавливается.

Ноутбук#

Эксперименты следуют ноутбуку Distances between distributions (HSE-LAMBDA Deep Generative Models, закреплённый коммит; ячейки нумеруются с 1, считая все ячейки, включая текстовые). Результаты запусков, приведённые выше, взяты из его сохранённых выходов ячеек; точные значения дивергенций и градиентов, минимумы функции потерь наименьших квадратов и симуляция отрицательных оценок вычислены отдельно, как и запуски с функцией потерь наименьших квадратов с пересчитанным px и возобновлённая кривая градиентов KL. Ячейки 1–11 (вспомогательные функции, целевое распределение из одной гауссианы и начальное QQ) описаны в заметке о гауссианах.

  • Ячейки 12–15: выборочная оценка DKL(P ∥ Q)D_{\mathrm{KL}}(P\,\|\,Q) (kl_loss, в битах; её аргумент weights принимает веса значимости (importance weights) и по умолчанию состоит из единиц) и подгонка двумерной модели с Adam (шаг обучения 0.1, 5000 итераций) к одиночной цели N((−5,−5),I)\mathcal N((-5,-5), \mathbf I) на 1000 сэмплах x из ячейки 8. Последний график, на шаге 4800, озаглавлен KL = -0.0020.
  • Ячейки 16–19: двухкомпонентная двумерная смесь со средними (−5,−5)(-5,-5) и (4,4)(4,4) и та же подгонка по KL, применённая к ней, на 2000 фиксированных сэмплах. log_prob_mixture использует torch.logaddexp. sample_from_mixture берёт ровно половину сэмплов из каждой компоненты, то есть строит стратифицированную выборку (stratified sample); при независимых одинаково распределённых (i.i.d.) сэмплах из смеси их число в каждой компоненте распределялось бы по биномиальному закону. Последний график, на шаге 4800, показывает KL mixture = 1.6688.
  • Ячейки 20–23: JS-дивергенция и её оценка методом Монте-Карло (js_div: x = P.sample(...) для первого слагаемого, y = sample(Q, ...) для второго, torch.logaddexp для log⁡m\log m), а также JS-подгонка смеси, начатая с μ=(−2,−2)\boldsymbol\mu = (-2,-2), с 5000 сэмплами на каждом шаге. В последней распечатке, на шаге 4900, стоят JS loss = 0.2734 и mu = tensor([-4.9879, -5.0583]). При повторном запуске важны две детали реализации. js_div возвращает взвешенную комбинацию 0.7/0.30.7/0.3, а не симметричную JS с весами ½–½. Кроме того, сэмплы QQ она берёт через sample(), а не rsample(), поэтому градиент не учитывает, как эти сэмплы смещаются при изменении QQ.
  • Ячейки 24–26: LSE_loss — среднеквадратичная ошибка между q(xi)q(x_i) и p(xi)p(x_i) — и подгонка с Adam (шаг обучения 0.001, 5000 итераций), начатая с N((1,1),I)\mathcal N((1,1), \mathbf I). Для контекста ноутбук ссылается на статью о GAN с наименьшими квадратами (least-squares GAN; Mao et al., 2017), хотя в ней наименьшие квадраты применяются к выходам дискриминатора, а не к плотностям. Ячейка обучения берёт новые сэмплы x, но повторно использует px, оставшееся от ячейки с JS, — плотности цели в 1000 других точках, поэтому px нужно пересчитать, чтобы функция потерь сравнивала две плотности в одних и тех же точках. Последний график, на шаге 4800, показывает LSE = 0.0013, и QQ находится на моде в (4,4)(4,4). С пересчитанным px та же подгонка всё равно заканчивается на этой моде, со значением функции потерь около 0.00110.0011 в повторной реализации.
  • Ячейки 27–38: вспомогательные функции кода выше (get_parameters_1d и create_distr_1d в ячейке 29, target_1d в ячейках 30–31) и одномерная смесь 12N(−3,0.52)+12N(−8,0.52)\tfrac12\mathcal N(-3, 0.5^2) + \tfrac12\mathcal N(-8, 0.5^2), к которой гауссиана подгоняется по KL (Adam, шаг обучения 0.01, 2000 итераций, 1000 фиксированных сэмплов) и, начиная с N(0,1)\mathcal N(0, 1), по JS (SGD, шаг обучения 0.1, 2000 итераций); модули градиентов по μ\mu и log⁡σ\log\sigma построены на графиках по ходу обучения (ячейки 35 и 38). JS-подгонка использует ту же взвешенную js_div с 5000 новыми сэмплами на каждом шаге. Сохранённые графики показывают подгонку по KL на шаге 1500 (Loss (KL) = 1.3001, mu = -5.494, std = 2.566) и JS-подгонку на шаге 1800 (JS = 0.2698, mu = -2.995, std = 0.495). В легенде ячейки 35 написано |grad sigma|, но кривая — это градиент по log⁡σ\log\sigma, как и подписано в ячейке 38.
  • Сохранённая кривая градиентов KL начинается не с N(0,1)\mathcal N(0, 1). Ячейка 33 создаёт параметры, соответствующие N(0,1)\mathcal N(0, 1); ячейка 34 не создаёт их заново. Кривая ячейки 35 начинается с ∣∂/∂μ∣≈0.85\lvert\partial/\partial\mu\rvert \approx 0.85 и ∣∂/∂log⁡σ∣≈3.6\lvert\partial/\partial\log\sigma\rvert \approx 3.6 бита, тогда как старт с N(0,1)\mathcal N(0, 1) даёт 7.97.9 и 51.651.6. Таких значений новый запуск достигает примерно через 200 шагов, при μ≈−1.1\mu \approx -1.1, σ≈2.7\sigma \approx 2.7, а в номерах выполнения (execution count) между ячейками 33 и 34 пропущено одно число: сохранённый запуск продолжился с того места, где параметры оставил более ранний, прерванный запуск ячейки 34. Повторная реализация, которая возобновляет обучение с этой точки с новым оптимизатором, воспроизводит сохранённую кривую: ∣∂/∂log⁡σ∣\lvert\partial/\partial\log\sigma\rvert падает почти до 00 примерно за 100 шагов, ∣∂/∂μ∣\lvert\partial/\partial\mu\rvert держится около 0.250.25 примерно до шага 400 и достигает 00 к шагу 750 или около того, а к шагу 1500 подгонка находится в μ≈−5.50\mu \approx -5.50, σ≈2.56\sigma \approx 2.56. Новый запуск медленнее: к шагу 1500 он всё ещё в μ≈−4.1\mu \approx -4.1. Чтобы получить задуманный старт, ячейку 33 нужно выполнить заново перед ячейкой 34.

Дальше#

До сих пор у модели было пять параметров и плотность в замкнутом виде. Реальные генеративные модели заменяют эти пять параметров нейронной сетью, а многие отказываются и от плотности в замкнутом виде. Обучение таких сетей требует собственного инструментария. Следующая заметка собирает элементы, которые используются на протяжении всего курса: батч-нормализацию (batch normalization), то, как градиенты проходят через глубокие стеки слоёв, и размерности свёрток.

Литература#