-
Notifications
You must be signed in to change notification settings - Fork 761
/
automated-transformations.tex
217 lines (171 loc) · 8.9 KB
/
automated-transformations.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
\title{Automated Transformations}
\subsection{Automated Transformations}
Automated transformations provide convenient handling of constrained
continuous variables during inference by transforming them to an
unconstrained space. Automated transformations are crucial for
expanding the scope of algorithm classes such as gradient-based Monte
Carlo and variational inference with reparameterization gradients.
A Jupyter notebook version of this tutorial is available
\href{http://nbviewer.jupyter.org/github/blei-lab/edward/blob/master/notebooks/automated_transformations.ipynb}{here}.
\subsubsection{The Transform Primitive}
Automated transformations in Edward are enabled through the key
primitive
\href{/api/ed/transform}{\texttt{ed.transform}}.
It takes as input a (possibly constrained) continuous random variable
$\mathbf{x}$, defaults to a choice of transformation $T$, and returns a
\href{/api/ed/models/TransformedDistribution}
{\texttt{TransformedDistribution}}
$\mathbf{y}=T(\mathbf{x})$ with unconstrained support.
An optional argument allows you to manually specify the transformation.
The returned random variable $\mathbf{y}$'s density is the original
random variable $\mathbf{x}$'s density adjusted by the determinant of
the Jacobian of the inverse transformation \citep{casella2002statistical},
$$p(\mathbf{y}) = p(\mathbf{x})~|\mathrm{det}~J_{T^{-1}}(\mathbf{y}) |.$$
Intuitively, the Jacobian describes how a transformation warps unit
volumes across spaces. This matters for transformations of random
variables, since probability density functions must always integrate
to one.
\subsubsection{Automated Transformations in Inference}
To use automated transformations during inference, set the flag
argument \texttt{auto_transform=True} in \texttt{inference.initialize}
(or the all-encompassing method \texttt{inference.run}):
\begin{lstlisting}[language=Python]
inference.initialize(auto_transform=True)
\end{lstlisting}
By default, the flag is already set to \texttt{True}.
With this flag, any key-value pair passed into inference's
\texttt{latent_vars} with unequal support is transformed to the
unconstrained space; no transformation is applied if already
unconstrained. The algorithm is then run under
\texttt{inference.latent_vars}, which explicitly stores the
transformed latent variables and forgets the constrained ones.
We illustrate automated transformations in a few inference examples.
Imagine that the target distribution is a Gamma distribution.
\begin{lstlisting}[language=Python]
from edward.models import Gamma
x = Gamma(1.0, 2.0)
\end{lstlisting}
This example is only used for illustration, but note this context of
inference with latent variables of non-negative support occur
frequently: for example, this appears when applying topic models with a deep exponential
family where we might use a normal variational
approximation to implicitly approximate latent variables with Gamma
priors (in
\href{https://github.com/blei-lab/edward/blob/master/examples/deep_exponential_family.py}
{\texttt{examples/deep_exponential_family.py}},
we explicitly define a non-negative variational approximation).
\textbf{Variational inference.}
Consider a Normal variational approximation
and use the algorithm \href{/api/ed/KLqp}{\texttt{ed.KLqp}}.
\begin{lstlisting}[language=Python]
from edward.models import Normal
qx = Normal(loc=tf.Variable(tf.random_normal([])),
scale=tf.nn.softplus(tf.Variable(tf.random_normal([]))))
inference = ed.KLqp({x: qx})
inference.run()
\end{lstlisting}
The Gamma and Normal distribution have unequal support, so inference
transforms both to the unconstrained space; normal is already
unconstrained so only Gamma is transformed. \texttt{ed.KLqp} then
optimizes with
\href{/api/klqp}{reparameterization gradients}.
This means the Normal distribution's parameters are optimized to match
the transformed (unconstrained) Gamma distribution.
Oftentimes we'd like the approximation on the original (constrained)
space. This was never needed for inference, so we must explicitly
build it by first obtaining the target distribution's transformation
and then inverting the transformation:
\begin{lstlisting}[language=Python]
from tensorflow.contrib.distributions import bijectors
x_unconstrained = inference.transformations[x] # transformed prior
x_transform = x_unconstrained.bijector # transformed prior's transformation
qx_constrained = ed.transform(qx, bijectors.Invert(x_transform))
\end{lstlisting}
The set of transformations is given by
\texttt{inference.transformations}, which is a dictionary with keys
given by any constrained latent variables and values given by their
transformed distribution. We use the
\href{https://www.tensorflow.org/versions/master/api_docs/python/tf/distributions/bijectors}{\texttt{bijectors}}
module in \texttt{tf.distributions} in order to handle invertible
transformations.
\texttt{qx_unconstrained} is a random variable distributed
according to a inverse-transformed (constrained) normal distribution.
For example, if the automated transformation from non-negative to
reals is $\log$, then the constrained approximation is a LogNormal
distribution; here, the default transformation is the inverse of
$\textrm{softplus}$.
We can visualize the densities of the distributions.
The figure below shows that the inverse-transformed normal
distribution has lighter tails than the Gamma but is overall a
good fit.
\begin{lstlisting}[language=Python]
sns.distplot(x.sample(50000).eval(), hist=False, label='x')
sns.distplot(qx_constrained.sample(100000).eval(), hist=False, label='qx')
\end{lstlisting}
\includegraphics[width=600px]{/images/automated-transformations-0.png}
\textbf{Gradient-based Monte Carlo.}
Consider an Empirical approximation with 1000 samples
and use the algorithm \href{/api/ed/HMC}{\texttt{ed.HMC}}.
\begin{lstlisting}[language=Python]
from edward.models import Normal
qx = Empirical(params=tf.Variable(tf.random_normal([1000])))
inference = ed.HMC({x: qx})
inference.run(step_size=0.8)
\end{lstlisting}
Gamma and Empirical have unequal support so Gamma is transformed to
the unconstrained space; by implementation, discrete delta
distributions such as Empirical and PointMass are not transformed.
\texttt{ed.HMC} then simulates Hamiltonian
dynamics and writes the unconstrained samples to the empirical
distribution.
In order to obtain the approximation on the original (constrained)
support, we again take the inverse of the target distribution's
transformation.
\begin{lstlisting}[language=Python]
from tensorflow.contrib.distributions import bijectors
x_unconstrained = inference.transformations[x] # transformed prior
x_transform = x_unconstrained.bijector # transformed prior's transformation
qx_constrained = Empirical(params=x_transform.inverse(qx.params))
\end{lstlisting}
Unlike variational inference, we don't use \texttt{ed.transform} to
obtain the constrained approximation, as it only applies to continuous
distributions. Instead, we define a new Empirical distribution whose
parameters (samples) are given by transforming all samples stored in
the unconstrained approximation.
We can visualize the densities of the distributions.
The figure below indicates that the samples accurately fit the Gamma
distribution up to simulation error.
\begin{lstlisting}[language=Python]
sns.distplot(x.sample(50000).eval(), hist=False, label='x')
sns.distplot(qx_constrained.sample(100000).eval(), hist=False, label='qx')
\end{lstlisting}
\includegraphics[width=600px]{/images/automated-transformations-1.png}
\subsubsection{Acknowledgements \& Remarks}
Automated transformations have largely been popularized by Stan
for Hamiltonian Monte Carlo \citep{carpenter2016stan}.
This design is inspired by Stan's. However, a key distinction is that Edward
provides users the ability to wield transformations and more flexibly
manipulate results in both the original (constrained) and inferred
(unconstrained) space.
Automated transformations are also core to the algorithm automatic
differentiation variational inference \citep{kucukelbir2017automatic},
which allows it to select a default variational family of normal
distributions. However, note the automated transformation from
non-negative to reals in Edward is not $\log$, which is used in Stan;
rather, Edward uses $\textrm{softplus}$ which is more numerically
stable (see also \citet[Fig.~9]{kucukelbir2017automatic}).
Finally, note that not all inference algorithms use or even need
automated transformations.
\href{/api/ed/Gibbs}{\texttt{ed.Gibbs}}, moment
matching with EP using Edward's conjugacy, and
\href{/api/ed/KLqp}{\texttt{ed.KLqp}}
with
score function gradients all perform inference on the original latent
variable space.
Point estimation such as \href{/api/ed/MAP}{\texttt{ed.MAP}} also
use the original latent variable space and only requires a
constrained transformation on unconstrained free parameters.
Model parameter estimation such as
\href{/api/ed/GANInference}{\texttt{ed.GANInference}} do not even
perform inference over latent variables.
\subsubsection{References}\label{references}