t-SNEは多次元のデータを2,3次元上にマッピングして可視化できるようにする手法の一つで、 Stochastic Neighbor Embedding(SNE, 確率的近傍埋め込み)という手法をベースに、t分布を用いるなどして改良したもの。
SNE
まず入力データ間の類似度をユークリッド距離を用いた次の条件付き確率p_{j|i}で表す。 これはx_iを中心とした正規分布上で、確率密度に基づいて隣り合うデータを選ぶ場合x_jが選ばれる確率となる。
同様に出力データでも次の条件付き確率q_{j|i}を計算する。σ=1/sqrt(2)
とする。
この分布間のKL情報量を勾配降下法で最小化していくことで出力を最適化するのがSME。
自己情報量、エントロピー、KL情報量、交差エントロピーと尤度関数 - sambaiz-net
ロジスティック回帰の尤度と交差エントロピーと勾配降下法 - sambaiz-net
t-SNE
t-SNEでは条件付き確率ではなく同時確率を用いる。また、qを自由度1のt分布で表す。
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
同じ数字や似ている数字の潜在変数が近いところに配置されていて、潜在空間をうまく可視化できているように見える。