VAEでエンコードしたMNISTの潜在空間をt-SNEで可視化する

(2019-03-10)

t-SNEは多次元のデータを2,3次元上にマッピングして可視化できるようにする手法の一つで、 Stochastic Neighbor Embedding(SNE, 確率的近傍埋め込み)という手法をベースに、t分布を用いるなどして改良したもの。

Visualizing Data using t-SNE

SNE

まず入力データ間の類似度をユークリッド距離を用いた次の条件付き確率p_{j|i}で表す。 これはx_iを中心とした正規分布上で、確率密度に基づいて隣り合うデータを選ぶ場合x_jが選ばれる確率となる。

入力データ間の類似度p_{j|i}

同様に出力データでも次の条件付き確率q_{j|i}を計算する。σ=1/sqrt(2)とする。

出力データ間の類似度q_{j|i}

この分布間のKL情報量を勾配降下法で最小化していくことで出力を最適化するのがSME。

コスト

自己情報量、エントロピー、KL情報量、交差エントロピーと尤度関数 - sambaiz-net

ロジスティック回帰の尤度と交差エントロピーと勾配降下法 - sambaiz-net

t-SNE

t-SNEでは条件付き確率ではなく同時確率を用いる。また、qを自由度1のt分布で表す。

p_ij

q_ij

コスト

MNISTの潜在空間をt-SNEで可視化した結果

以前作ったVAEのMNISTモデルの潜在空間を scikit-learnのTSNEで可視化する。

PyTorchでVAEのモデルを実装してMNISTの画像を生成する - sambaiz-net

%matplotlib inline
import matplotlib.pyplot as plt
from sklearn.manifold import TSNE
from random import random

colors = ["red", "green", "blue", "orange", "purple", "brown", "fuchsia", "grey", "olive", "lightblue"]
def visualize_zs(zs, labels):
  plt.figure(figsize=(10,10))
  points = TSNE(n_components=2, random_state=0).fit_transform(zs)
  for p, l in zip(points, labels):
    plt.scatter(p[0], p[1], marker="${}$".format(l), c=colors[l])
  plt.show()

model.eval()
zs = []
for x, t in dataloader_valid:
    x = x.to(device)
    t = t.to(device)
    # generate from x
    y, z = model(x)
    z = z.cpu()
    t = t.cpu()
    visualize_zs(z.detach().numpy(), t.cpu().detach().numpy())
    break

同じ数字や似ている数字の潜在変数が近いところに配置されていて、潜在空間をうまく可視化できているように見える。

MNISTの潜在空間をt-SNEで次元削減したもの