tf.contrib.distributions.bijectors.Bijector
Интерфейс для преобразований Distribution выборки.
@abc.abstractmethod
tf.contrib.distributions.bijectors.Bijector(
graph_parents=None, is_constant_jacobian=False, validate_args=False, dtype=None,
forward_min_event_ndims=None, inverse_min_event_ndims=None, name=None
)
Бижекторы могут использоваться для представления любой дифференцируемой и инъективной (один к одному) функции, определенной на открытом подмножестве R^n. Некоторые неинъективные преобразования также поддерживаются (см. «Неинъективные преобразования» ниже).
Математические подробности
Биджектор реализует гладкое накрывающее отображение, т.е. локальный диффеоморфизм, такой, что каждая точка в области имеет окрестность, равномерно покрытую отображением (см. также). Биджектор используется TransformedDistribution но может быть в целом использован для преобразования Distribution сгенерированной Tensor. Биджектор характеризуется тремя операциями:
-
Прямое преобразование
Полезно для превращения одного случайного результата в другой случайный результат из другого распределения.
-
Обратное преобразование
Полезно для «обращения» преобразования для вычисления одной вероятности в терминах другой.
-
log_det_jacobian(x)«Логарифм абсолютного значения определителя матрицы всех частных производных первого порядка обратной функции».
Полезно для обращения преобразования для вычисления одной вероятности в терминах другой. Геометрически определитель Якобиана — это объем преобразования, который используется для масштабирования вероятности.
Мы берем абсолютное значение определителя до логарифмирования, чтобы избежать значений NaN. Геометрически отрицательный определитель соответствует преобразованию, меняющему ориентацию. Для нас приемлемо отбрасывать знак определителя, поскольку мы интегрируем только везде неотрицательные функции (плотности вероятностей), и правильная ориентация всегда та, которая дает неотрицаемый интеграл.
По соглашению, преобразования случайных величин называются в терминах прямого преобразования. Прямое преобразование создает выборки, обратное полезно для вычисления вероятностей.
Примеры использования
- Основные свойства:
x = ... # A tensor. # Evaluate forward transformation. fwd_x = my_bijector.forward(x) x == my_bijector.inverse(fwd_x) x != my_bijector.forward(fwd_x) # Not equal because x != g(g(x)).
- Вычисление логарифмической правдоподобия:
def transformed_log_prob(bijector, log_prob, x):
return (bijector.inverse_log_det_jacobian(x, event_ndims=0) +
log_prob(bijector.inverse(x)))
- Преобразование случайного результата:
def transformed_sample(bijector, x): return bijector.forward(x)
Примеры биджекторов
- «Экспоненциальный»
Y = g(X) = exp(X) X ~ Normal(0, 1) # Univariate.
Подразумевает:
g^{-1}(Y) = log(Y)
|Jacobian(g^{-1})(y)| = 1 / y
Y ~ LogNormal(0, 1), i.e.,
prob(Y=y) = |Jacobian(g^{-1})(y)| * prob(X=g^{-1}(y))
= (1 / y) Normal(log(y); 0, 1)
Вот пример того, как можно реализовать биджектор Exp:
class Exp(Bijector):
def __init__(self, validate_args=False, name="exp"):
super(Exp, self).__init__(
validate_args=validate_args,
forward_min_event_ndims=0,
name=name)
def _forward(self, x):
return math_ops.exp(x)
def _inverse(self, y):
return math_ops.log(y)
def _inverse_log_det_jacobian(self, y):
return -self._forward_log_det_jacobian(self._inverse(y))
def _forward_log_det_jacobian(self, x):
# Notice that we needn't do any reducing, even when`event_ndims > 0`.
# The base Bijector class will handle reducing for us; it knows how
# to do so because we called `super` `__init__` with
# `forward_min_event_ndims = 0`.
return x
- «Аффинный»
Y = g(X) = sqrtSigma * X + mu X ~ MultivariateNormal(0, I_d)
Подразумевает:
g^{-1}(Y) = inv(sqrtSigma) * (Y - mu)
|Jacobian(g^{-1})(y)| = det(inv(sqrtSigma))
Y ~ MultivariateNormal(mu, sqrtSigma) , i.e.,
prob(Y=y) = |Jacobian(g^{-1})(y)| * prob(X=g^{-1}(y))
= det(sqrtSigma)^(-d) *
MultivariateNormal(inv(sqrtSigma) * (y - mu); 0, I_d)
Min_event_ndims и именование
Бижекторы именуются по размерности данных, на которых они действуют (т. е. без трансляции). Мы можем рассматривать бижекторы как имеющие внутреннюю min_event_ndims , которая является минимальным числом измерений для биджекторского действия. Например, для преобразования Холецкого требуется матрица, и поэтому min_event_ndims=2.
Примеры:
AffineScalar: min_event_ndims=0 Affine: min_event_ndims=1 Cholesky: min_event_ndims=2 Exp: min_event_ndims=0 Sigmoid: min_event_ndims=0 SoftmaxCentered: min_event_ndims=1
Обратите внимание на разницу между Affine и AffineScalar. AffineScalar действует на скалярные события, тогда как Affine действует на векторные события.
В более общем случае существует forward_min_event_ndims и inverse_min_event_ndims. В большинстве случаев они будут одинаковыми. Однако для некоторых биджекторов, изменяющих форму, они будут отличаться (например, биджектор, добавляющий дополнительное измерение в конце, может иметь forward_min_event_ndims=0 и inverse_min_event_ndims=1).
Определитель Якобиана
Определитель Якобиана — это уменьшение по event_ndims - min_event_ndims (forward_min_event_ndims для forward_log_det_jacobian и inverse_min_event_ndims для inverse_log_det_jacobian). Для этого рассмотрим Exp Bijector примененное к Tensor, имеющему семантику формы выборки, пакетной выборки и события (S, B, E). Предположим, что разбиение формы биджектора — (S=[4], B=[2], E=[3, 3]). Форма Tensor , возвращаемая forward и inverse , не изменяется, т. е. [4, 2, 3, 3]. Однако форма, возвращаемая inverse_log_det_jacobian , составляет [4, 2] , поскольку определитель Якобиана — это уменьшение по размерности события.
Еще один пример — Affine Bijector. Поскольку min_event_ndims = 1, уменьшение определителя Якобиана происходит по event_ndims - 1.
Иногда полезно реализовать обратный определитель Якобиана как отрицательный прямой определитель Якобиана. Например,
def _inverse_log_det_jacobian(self, y): return -self._forward_log_det_jac(self._inverse(y)) # Note negation.
Правильность этого подхода можно увидеть из следующего утверждения.
-
Утверждение:
Предположим, что
Y = g(X)— это биекция, производная которой существует и не равна нулю для ее области определения, т. е.dY/dX = d/dX g(X) != 0. Тогда:
(log o det o jacobian o g^{-1})(Y) = -(log o det o jacobian o g)(X)
-
Доказательство:
Из биективности, ненулевой дифференцируемости
gтеорема обратной функции теорема обратной функции подразумевает, чтоg^{-1}дифференцируема в области значенийg. Применяя правило цепи кy = g(x) = g(g^{-1}(y)), получаемI = g'(g^{-1}(y))*g^{-1}'(y). Та же теорема также подразумевает, чтоg^{-1}'невырождена, поэтому:inv[ g'(g^{-1}(y)) ] = g^{-1}'(y). Утверждение следует из свойств определителя.
В целом предпочтительнее напрямую реализовывать обратный определитель Якобиана. Это должно обеспечить лучшую числовую устойчивость и часто будет совмещать подграфы с реализацией _inverse.
Is_constant_jacobian
У некоторых биджекторов будут постоянные матрицы Якобиана. Например, биджектор Affine кодирует умножение на матрицу плюс сдвиг, с матрицей Якобиана, той же самой упомянутой матрицей.
is_constant_jacobian кодирует тот факт, что матрица Якобиана постоянна. Семантика этого аргумента следующая:
- Повторные вызовы функций «log_det_jacobian» с тем же
event_ndims(но не обязательно с тем же входом) будут возвращать вычисленный в первый раз якобиан (поскольку матрица постоянна и, следовательно, не зависит от ввода). -
Реализации
log_det_jacobianпросто транслируются к истинномуlog_det_jacobian(поскольку, опять же, матрица якобиана не зависит от ввода). Конкретно,log_det_jacobianреализуется как логарифмический определитель якобиана для одного входного значения.
class Identity(Bijector):
def __init__(self, validate_args=False, name="identity"):
super(Identity, self).__init__(
is_constant_jacobian=True,
validate_args=validate_args,
forward_min_event_ndims=0,
name=name)
def _forward(self, x):
return x
def _inverse(self, y):
return y
def _inverse_log_det_jacobian(self, y):
return -self._forward_log_det_jacobian(self._inverse(y))
def _forward_log_det_jacobian(self, x):
# The full log jacobian determinant would be array_ops.zero_like(x).
# However, we circumvent materializing that, since the jacobian
# calculation is input independent, and we specify it for one input.
return constant_op.constant(0., x.dtype.base_dtype)
Требования к подклассу
-
Подклассы обычно реализуют:
-
_forward, -
_inverse, -
_inverse_log_det_jacobian, -
_forward_log_det_jacobian(необязательно).
_forward_log_det_jacobianвызывается при инвертировании биджектора с помощью биджектораInvert. Если не определено, используется несколько менее эффективный расчет-1 * _inverse_log_det_jacobian.Если биджектор изменяет форму входных данных, вы также должны реализовать:
- _forward_event_shape_tensor,
- _forward_event_shape (необязательно),
- _inverse_event_shape_tensor,
- _inverse_event_shape (необязательно).
По умолчанию предполагается, что форма события не изменяется от входных данных.
-
-
Если использование
BijectorограниченоTransformedDistribution(или родственными объектами, такими какQuantizedDistribution), то в зависимости от вашего использования вам может не понадобиться реализовывать все функции_forwardи_inverse.Примеры:
- Выборка (например,
sample) требует только_forward. - Функции вероятностей (например,
prob,cdf,survival) требуют только_inverse(и связанные с ним). - Вызов функций вероятностей только на выходе
sampleозначает, что_inverseможет быть реализован как кеширование.
См. «Примеры использования» [выше], в котором показано, как эти функции используются для преобразования распределения. (Примечание:
_forwardтеоретически мог бы быть реализован как кеширование, но для этого потребовалось бы управление механизмом генерации выборки.) - Выборка (например,
Неинъективные преобразования
Неинъективные отображения g поддерживаются при условии, что их область определения D может быть разделена на k непересекающихся подмножеств, Union{D1, ..., Dk}, такие, что, игнорируя множества нулевой меры, ограничение g на каждое подмножество является дифференцируемой биекцией на g(D). В частности, это означает, что для y in g(D) множество образов, т. е. g^{-1}(y) = {x in D : g(x) = y} , всегда содержит ровно k различных точек.
Свойство _is_injective установлено в False для указания того, что биджектор неинъективен, но удовлетворяет вышеуказанному условию.
Обычный API биджекторов модифицируется в случае _is_injective is False (см. строку документации метода для получения подробностей). Здесь мы покажем на примере биджектор AbsoluteValue . В этом случае область определения D = (-inf, inf) может быть разделена на D1 = (-inf, 0), D2 = {0} и D3 = (0, inf) . Пусть gi — ограничение g на Di, тогда и g1 и g3 являются биекциями на (0, inf), с g1^{-1}(y) = -y и g3^{-1}(y) = y . Мы будем использовать g1 и g3 для определения методов биджектора над D1 и D3 . D2 = {0} — исключение, в котором g2 — это взаимно однозначное соответствие, а производная не определена корректно. К счастью, при рассмотрении преобразований плотностей вероятностей (например, в TransformedDistribution ) множества нулевой меры теоретически не влияют и оказывают лишь небольшое влияние в 32- или 64-битной точности. По этой причине мы определим inverse(0) и inverse_log_det_jacobian(0) как [0, 0] , что удобно и приводит к левополунепрерывной плотности вероятностей.
abs = tfp.distributions.bijectors.AbsoluteValue() abs.forward(-1.) ==> 1. abs.forward(1.) ==> 1. abs.inverse(1.) ==> (-1., 1.) # The |dX/dY| is constant, == 1. So Log|dX/dY| == 0. abs.inverse_log_det_jacobian(1., event_ndims=0) ==> (0., 0.) # Special case handling of 0. abs.inverse(0.) ==> (0., 0.) abs.inverse_log_det_jacobian(0., event_ndims=0) ==> (0., 0.)
| Аргументы | |
|---|---|
graph_parents | Список Python с предшественниками графа данного Bijector. |
is_constant_jacobian | Python bool, указывающий, что матрица Якоби не является функцией от входных данных. |
validate_args | Python bool, по умолчанию False. Проводить ли проверку входных данных с помощью assert. Если validate_args имеет значение False, и входные данные некорректны, гарантии корректного поведения нет. |
dtype | tf.dtype поддерживаемый данным Bijector. None означает, что тип данных не навязывается. |
forward_min_event_ndims | Python integer, указывающий минимальное число измерений, на которых работает forward. |
inverse_min_event_ndims | Python integer указывающий минимальное число измерений, на которых работает inverse. Будет установлено значение forward_min_event_ndims по умолчанию, если значение не указано. |
name | Имя для Ops, созданных инициализатором. |
| Исключения | |
|---|---|
ValueError | Если ни forward_min_event_ndims, ни inverse_min_event_ndims не указаны, или если хотя бы одно из них отрицательно. |
ValueError | Если член graph_parents не является Tensor. |
| Атрибуты | |
|---|---|
dtype | Тип данных Tensor преобразуемых этим распределением. |
forward_min_event_ndims | Возвращает минимальное число измерений, на которых bijector.forward работает. |
graph_parents | Возвращает graph_parents данного Bijector в виде списка Python. |
inverse_min_event_ndims | Возвращает минимальное число измерений, на которых bijector.inverse работает. |
is_constant_jacobian | Возвращает true, если матрица Якоби не является функцией от x. Примечание: Матрица Якоби либо постоянна для forward и inverse, либо для ни одного из них. |
name | Возвращает строковое имя данного Bijector. |
validate_args | Возвращает True, если аргументы Tensor будут проверены. |
Методы
forward
forward(
x, name='forward'
)
Возвращает результат вычисления "forward", т.е. X = g(Y).
| Аргументы | |
|---|---|
x | Tensor. Вход для вычисления "forward". |
name | Имя для данного op. |
| Возвращаемое значение | |
|---|---|
Tensor. |
| Исключения | |
|---|---|
TypeError | если self.dtype указано, и x.dtype не является self.dtype. |
NotImplementedError | если _forward не реализовано. |
forward_event_shape
forward_event_shape(
input_shape
)
Форма единичного образца из единичной партии в виде TensorShape.
То же, что и forward_event_shape_tensor. Может быть только частично определена.
| Аргументы | |
|---|---|
input_shape | TensorShape указывающий форму части события, переданной в функцию forward. |
| Возвращаемое значение | |
|---|---|
forward_event_shape_tensor | TensorShape указывающий форму части события после применения forward. Возможно неизвестна. |
forward_event_shape_tensor
forward_event_shape_tensor(
input_shape, name='forward_event_shape_tensor'
)
Форма единичного образца из единичной партии в виде тензора 1D int32.
| Аргументы | |
|---|---|
input_shape | Tensor, int32 вектор указывающий форму части события, переданной в функцию forward. |
name | имя для op. |
| Возвращаемое значение | |
|---|---|
forward_event_shape_tensor | Tensor, int32 вектор указывающий форму части события после применения forward. |
forward_log_det_jacobian
forward_log_det_jacobian(
x, event_ndims, name='forward_log_det_jacobian'
)
Возвращает как прямую, так и логарифм определителя якобиана.
| Аргументы | |
|---|---|
x | Tensor. Вход для вычисления определителя якобиана "прямого" отображения. |
event_ndims | Количество измерений в преобразуемых вероятностных событиях. Должно быть больше или равно self.forward_min_event_ndims. Результат суммируется по последним измерениям, чтобы получить скалярный определитель якобиана для каждого события, т. е. он имеет размерность x.shape.ndims - event_ndims . |
name | Имя, которое нужно дать этому оператору. |
| Возвращаемое значение | |
|---|---|
Tensor, если этот биектор является инъективным. Если не инъективен, это не реализовано. |
| Исключения | |
|---|---|
TypeError | если self.dtype указано, и y.dtype не self.dtype. |
NotImplementedError | если ни _forward_log_det_jacobian ни {_inverse, _inverse_log_det_jacobian} не реализованы, или это биектор, не являющийся инъективным. |
inverse
inverse(
y, name='inverse'
)
Возвращает обратное вычисление Bijector, т. е., X = g^{-1}(Y).
| Аргументы | |
|---|---|
y | Tensor. Вход для вычисления "обратного" отображения. |
name | Имя, которое нужно дать этому оператору. |
| Возвращаемое значение | |
|---|---|
Tensor, если этот биектор является инъективным. Если не инъективен, возвращает k-кортеж, содержащий уникальные k точки (x1, ..., xk) такие, что g(xi) = y. |
| Исключения | |
|---|---|
TypeError | если self.dtype указано, и y.dtype не self.dtype. |
NotImplementedError | если _inverse не реализовано. |
inverse_event_shape
inverse_event_shape(
output_shape
)
Форма одного образца из одной партии как TensorShape.
То же самое, что и inverse_event_shape_tensor. Может быть определена лишь частично.
| Аргументы | |
|---|---|
output_shape | TensorShape , указывающая форму части события, переданную в функцию inverse . |
| Возвращаемое значение | |
|---|---|
inverse_event_shape_tensor | TensorShape , указывающая форму части события после применения inverse. Возможно, неизвестно. |
inverse_event_shape_tensor
inverse_event_shape_tensor(
output_shape, name='inverse_event_shape_tensor'
)
Форма одного образца из одной партии как одномерный int32 массив Tensor.
| Аргументы | |
|---|---|
output_shape | Tensor, int32 вектор, указывающий форму части события, переданной в функцию inverse. |
name | имя, которое нужно присвоить операции |
| Возвращает | |
|---|---|
inverse_event_shape_tensor | Tensor, int32 вектор, указывающий форму части события после применения inverse. |
inverse_log_det_jacobian
inverse_log_det_jacobian(
y, event_ndims, name='inverse_log_det_jacobian'
)
Возвращает (лог o det o якобиан o обратный)(y).
Математически возвращает: log(det(dX/dY))(Y). (Напомним, что: X=g^{-1}(Y).)
Обратите внимание, что forward_log_det_jacobian является отрицанием этой функции, вычисленной в точке g^{-1}(y).
| Аргументы | |
|---|---|
y | Tensor. Вход для вычисления определителя обратного якобиана. |
event_ndims | Количество измерений в преобразуемых вероятностных событиях. Должно быть больше или равно self.inverse_min_event_ndims. Результат суммируется по последним измерениям для получения скалярного определителя якобиана для каждого события, т.е. он имеет форму y.shape.ndims - event_ndims измерений. |
name | Имя, которое нужно присвоить этой операции. |
| Возвращает | |
|---|---|
Tensor, если этот биектор инъективен. Если не инъективен, возвращает кортеж локальных логарифмов определителей якобианов, log(det(Dg_i^{-1}(y))), где g_i - ограничение g на ith разбиение Di. |
| Исключения | |
|---|---|
TypeError | если self.dtype указано, а y.dtype не self.dtype. |
NotImplementedError | если _inverse_log_det_jacobian не реализовано. |
© 2020 The TensorFlow Authors. All rights reserved.
Licensed under the Creative Commons Attribution License 3.0.
Code samples licensed under the Apache 2.0 License.
https://www.tensorflow.org/versions/r1.15/api_docs/python/tf/contrib/distributions/bijectors/Bijector