<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://gregoryljohnson.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://gregoryljohnson.github.io/" rel="alternate" type="text/html" /><updated>2026-08-13T19:14:30+00:00</updated><id>https://gregoryljohnson.github.io/feed.xml</id><title type="html">Gregory Johnon’s Stuff</title><subtitle>Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description.</subtitle><author><name>Gregory Johnson</name></author><entry><title type="html">Basic Normalizing Flows</title><link href="https://gregoryljohnson.github.io/blog/NM1/" rel="alternate" type="text/html" title="Basic Normalizing Flows" /><published>2025-04-10T00:00:00+00:00</published><updated>2025-04-10T00:00:00+00:00</updated><id>https://gregoryljohnson.github.io/blog/NM1</id><content type="html" xml:base="https://gregoryljohnson.github.io/blog/NM1/"><![CDATA[<h1 id="basic-normalizing-flows">Basic Normalizing Flows</h1>

<p>In this post, we are going to explore a very basic implementation of normalizing flows, the goal of which is to extend to more intersting scneario’s with more advanced architectures. Ultimately, we’d like to reproduce the results of <a href="https://arxiv.org/abs/2203.01243">Pawlowski, J., Urban, J. (2022)</a>.</p>

<h2 id="density-estimation">Density estimation</h2>

<p>In this section, we follow <a href="https://arxiv.org/abs/1908.09257">Shen et al. (2019)</a>. Suppose you have some data, $\mathcal{D} = { y^{(i)} }_{i=1}^N$ with $y^{(i)} \in \mathbb{R}^d$, whose underlying density, $p_y you’d like to know. The core idea is to find a transformation (neccesarily a bijection), $y=g(z)$, which maps a simple distribution, $p_z$, to the target distribution $p_y$. The term normalizing flows seems to stem from the flow reducing the target distrbution to a normal distribution.</p>

<p>Let us derive a relation between $p_z$ and $p_z$ using $f=g^{-1}$:
\(\begin{aligned}
p_y(y) dy &amp;= p_z(z) dz\\
&amp;= p_z( f(y)) | \text{det} \, Dg\,(f(y))|^{-1} dy \\
&amp;= p_z(f(y))| \text{det} \, Df(y)| dy
\end{aligned}\)
where $Df= \frac{\partial f}{\partial x}$ is the Jacobian. We take the magnitude of the jacobian so as to ensure the pdfs remain positive. In the last line, we used the relation of Jacobians of inverse functions.</p>

<p>If we have a set of bijections which are easily inverted, we can simply compose together functions of this set to produce a more expressive transformation.</p>

<p>\(\begin{aligned}
g &amp;= g_N \circ g_{N-1} \circ ... \circ g_1 \\
f &amp;= f_1 \circ f_{2} \circ ... \circ f_N \\
\end{aligned}\)
and so for the Jacobians (using y=g(z))
\(\begin{aligned}
Df(y) &amp;= \prod_{i=1}^N D f_i(x_i) \\
\det Df(y) &amp;= \prod_{i=1}^N \det D f_i(x_i)
\end{aligned}\)
where $x_1 = z$, $x_N=y$, and
\(\begin{aligned}
x_N &amp;= y  \\
x_{N-1} &amp;= f_N(y) \\
x_i &amp;= f_{i+1} \circ ... \circ f_N(y) \\
x_i &amp;= g_i \circ ... \circ g_1(z) \\
x_1 &amp;= g_1(z) 
\end{aligned}\)</p>

<p>Or for the other direction:
\(\begin{aligned}
\det Dg(z) &amp;= \prod_{i=1}^N \det D g_i(x_i) \\
x_1 &amp;= z \\
x_2 &amp;= g_1(z) \\
x_i &amp;= g_{i-1} \circ g_{i-2} \circ ... \circ g_1(z)
\end{aligned}\)</p>

<p>To the transform, we seek to maximize the log-likelihood of the data given the transform parameters $\theta$ (we fix the base/latent distribution):</p>

\[\begin{aligned}
\log \, p(D|\theta) &amp;= \sum_{i=1}^N \, \log \,p_y(y^{(i)}|\theta) \\
&amp;= \sum_{i=1}^N \,\log \, p_z( f(y|\theta)) + \log \,| \text{det} \, D(f(y|\theta))| \\
&amp;= \sum_{i=1}^N \,\log \, p_z( f(y|\theta)) - \log \,| \text{det} \, Dg_\theta\,(f(y|\theta))| \\
\end{aligned}\]

<p>Implementing the $g$’s a layers in a neural network, we’d have something like this to compute the total log_prob:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">log_prob</span><span class="p">(</span><span class="n">flow</span><span class="p">,</span> <span class="n">target_data</span><span class="p">)</span>
  <span class="n">y</span> <span class="o">=</span> <span class="n">target_data</span><span class="p">.</span><span class="n">sample</span><span class="p">((</span><span class="mi">512</span><span class="p">,))</span>
  <span class="n">z</span> <span class="o">=</span> <span class="n">flow</span><span class="p">.</span><span class="n">inverse</span><span class="p">(</span><span class="n">y</span><span class="p">)</span> <span class="c1"># f(y)
</span>  <span class="n">p_z</span> <span class="o">=</span> <span class="n">flow</span><span class="p">.</span><span class="n">base_dist</span>
  <span class="n">log_pz</span> <span class="o">=</span> <span class="n">p_z</span><span class="p">.</span><span class="n">log_prob</span><span class="p">(</span><span class="n">f_y</span><span class="p">)</span>

  <span class="n">logdetJ</span> <span class="o">=</span> <span class="p">[]</span>
  <span class="k">for</span> <span class="n">layer</span> <span class="ow">in</span> <span class="n">model</span><span class="p">.</span><span class="n">layers</span><span class="p">:</span>
    <span class="n">logdetJ</span> <span class="o">+=</span> <span class="n">layer</span><span class="p">.</span><span class="n">log_abs_det_j</span><span class="p">(</span><span class="n">z</span><span class="p">)</span>
    <span class="n">z</span> <span class="o">=</span> <span class="n">layer</span><span class="p">(</span><span class="n">z</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">log_pz</span> <span class="o">-</span> <span class="n">logdetJ</span>
</code></pre></div></div>

<h3 id="references">References</h3>

<ul>
  <li>Rezende, D. J., Mohamed, S. (2015). <a href="https://arxiv.org/abs/1410.8516">Variational Inference with Normalizing Flows</a>. <em>arXiv preprint arXiv:1410.8516</em>.</li>
  <li>Shen, X., et al. (2019). <a href="https://arxiv.org/abs/1908.09257">Normalizing Flows for Probabilistic Modeling and Inference</a>. <em>arXiv:1908.09257</em>.</li>
  <li>Pawlowski, J., Urban, J. (2022). <a href="https://arxiv.org/abs/2203.01243">Flow-based density of states for complex actions</a>. <em>arXiv:2203.01243</em>.</li>
</ul>]]></content><author><name>Gregory Johnson</name></author><category term="Blog" /><category term="announcements" /><summary type="html"><![CDATA[Basic Normalizing Flows In this post, we are going to explore a very basic implementation of normalizing flows, the goal of which is to extend to more intersting scneario’s with more advanced architectures. Ultimately, we’d like to reproduce the results of Pawlowski, J., Urban, J. (2022). Density estimation In this section, we follow Shen et al. (2019). Suppose you have some data, $\mathcal{D} = { y^{(i)} }_{i=1}^N$ with $y^{(i)} \in \mathbb{R}^d$, whose underlying density, $p_y you’d like to know. The core idea is to find a transformation (neccesarily a bijection), $y=g(z)$, which maps a simple distribution, $p_z$, to the target distribution $p_y$. The term normalizing flows seems to stem from the flow reducing the target distrbution to a normal distribution. Let us derive a relation between $p_z$ and $p_z$ using $f=g^{-1}$: \(\begin{aligned} p_y(y) dy &amp;= p_z(z) dz\\ &amp;= p_z( f(y)) | \text{det} \, Dg\,(f(y))|^{-1} dy \\ &amp;= p_z(f(y))| \text{det} \, Df(y)| dy \end{aligned}\) where $Df= \frac{\partial f}{\partial x}$ is the Jacobian. We take the magnitude of the jacobian so as to ensure the pdfs remain positive. In the last line, we used the relation of Jacobians of inverse functions. If we have a set of bijections which are easily inverted, we can simply compose together functions of this set to produce a more expressive transformation. \(\begin{aligned} g &amp;= g_N \circ g_{N-1} \circ ... \circ g_1 \\ f &amp;= f_1 \circ f_{2} \circ ... \circ f_N \\ \end{aligned}\) and so for the Jacobians (using y=g(z)) \(\begin{aligned} Df(y) &amp;= \prod_{i=1}^N D f_i(x_i) \\ \det Df(y) &amp;= \prod_{i=1}^N \det D f_i(x_i) \end{aligned}\) where $x_1 = z$, $x_N=y$, and \(\begin{aligned} x_N &amp;= y \\ x_{N-1} &amp;= f_N(y) \\ x_i &amp;= f_{i+1} \circ ... \circ f_N(y) \\ x_i &amp;= g_i \circ ... \circ g_1(z) \\ x_1 &amp;= g_1(z) \end{aligned}\) Or for the other direction: \(\begin{aligned} \det Dg(z) &amp;= \prod_{i=1}^N \det D g_i(x_i) \\ x_1 &amp;= z \\ x_2 &amp;= g_1(z) \\ x_i &amp;= g_{i-1} \circ g_{i-2} \circ ... \circ g_1(z) \end{aligned}\) To the transform, we seek to maximize the log-likelihood of the data given the transform parameters $\theta$ (we fix the base/latent distribution): \[\begin{aligned} \log \, p(D|\theta) &amp;= \sum_{i=1}^N \, \log \,p_y(y^{(i)}|\theta) \\ &amp;= \sum_{i=1}^N \,\log \, p_z( f(y|\theta)) + \log \,| \text{det} \, D(f(y|\theta))| \\ &amp;= \sum_{i=1}^N \,\log \, p_z( f(y|\theta)) - \log \,| \text{det} \, Dg_\theta\,(f(y|\theta))| \\ \end{aligned}\] Implementing the $g$’s a layers in a neural network, we’d have something like this to compute the total log_prob: def log_prob(flow, target_data) y = target_data.sample((512,)) z = flow.inverse(y) # f(y) p_z = flow.base_dist log_pz = p_z.log_prob(f_y) logdetJ = [] for layer in model.layers: logdetJ += layer.log_abs_det_j(z) z = layer(z) return log_pz - logdetJ References Rezende, D. J., Mohamed, S. (2015). Variational Inference with Normalizing Flows. arXiv preprint arXiv:1410.8516. Shen, X., et al. (2019). Normalizing Flows for Probabilistic Modeling and Inference. arXiv:1908.09257. Pawlowski, J., Urban, J. (2022). Flow-based density of states for complex actions. arXiv:2203.01243.]]></summary></entry><entry><title type="html">Howdy</title><link href="https://gregoryljohnson.github.io/blog/howdy/" rel="alternate" type="text/html" title="Howdy" /><published>2025-04-04T00:00:00+00:00</published><updated>2025-04-04T00:00:00+00:00</updated><id>https://gregoryljohnson.github.io/blog/howdy</id><content type="html" xml:base="https://gregoryljohnson.github.io/blog/howdy/"><![CDATA[<h1 id="welcome-to-my-experiment">Welcome to my experiment</h1>
<p>I am starting a blog to experiment with documenting my scattered explorations.</p>

<p>Topics you might see here:</p>
<ul>
  <li>Statistical physics, field theory, critical phenomenon, renormalization</li>
  <li>Computational physics</li>
  <li>Statistics, machine learning</li>
  <li>Random math (differential geometry, logic, Hilbert spaces, …)</li>
  <li>Music and music theory</li>
  <li>History about any of these topics</li>
</ul>]]></content><author><name>Gregory Johnson</name></author><category term="Blog" /><category term="announcements" /><summary type="html"><![CDATA[Welcome to my experiment I am starting a blog to experiment with documenting my scattered explorations. Topics you might see here: Statistical physics, field theory, critical phenomenon, renormalization Computational physics Statistics, machine learning Random math (differential geometry, logic, Hilbert spaces, …) Music and music theory History about any of these topics]]></summary></entry></feed>