前の話
Tensorflow 2.0.0rc0 + Tensorflow Probability 0.8.0rc0 -> RealNVP(1)
Tensorflow 2.0.0rc0 + Tensorflow Probability 0.8.0rc0 -> RealNVP(2)
今回する話
Glow x MNIST
RealNVP を Glow にしてみます。
tl;dr
Glow x MNIST notebook
repository
Invertible 1x1 conv
理論的な話は Glow: Better Reversible Generative Modelsメモ を見て下さい。
RealNVP では Coupling Layer で Coupling の組み合わせの偏りを減らすために、Channel 軸方向に見て要素を反転していました。
ここをGlowでは Invertible 1x1 conv という学習可能な Bijector に代替しました。やっていることは簡単に言うと入力 $x$ Tensor $[h, w, c]$ に対して、行列 $W$ $[c, c]$ をかけ合わせます。
$f(x)$ の式を簡単に示します。
\begin{eqnarray*}
y &=& f(x) \\
&=& Wx
\end{eqnarray*}
逆関数 $f^{-1}(x)$ は次のようになります。
\begin{eqnarray*}
x &=& f^{-1}(x) \\
&=& W^{-1} x
\end{eqnarray*}
よって $W$ の条件は、逆行列が存在することになります。このため Glow では W に回転行列を用いています。
また $W$ の逆行列の計算は、直接的に行うとかなりコストがかかります。これを効率的に行うために、Glowでは LU 分解を用いています。私の実装でもこの例にもれずLU分解を使って逆行列を計算しています。
Actnorm
理論的な話は Glow: Better Reversible Generative Modelsメモ を見て下さい。
これは初期バッチに対して、Channel軸方向に正則化を行います。そしてその正則化のパラメータを初期重みとして学習を行います。
実装 & 訓練
Tensorflow 2.0.0rc0 + Tensorflow Probability 0.8.0rc0 -> RealNVP(2)
と対して変わらないので割愛。notebook を見て下さい。
推論
右上は無視して大丈夫です。
上側は元のテストデータ(入力)
下側は入って正規分布になって戻ってきたデータ $f^{−1}(f(x))$
右下は2つのデータを正規分布上で混ぜたもの、となっています。