Является ли код правильным способом понимания Vae против стандартного автоэнкодера? - PullRequest
0 голосов
/ 15 февраля 2019

Я создал две мини-сети кодирования для стандартного автоэнкодера и VAE и нанес на график каждую.Хотелось бы знать, правильно ли мое понимание этого мини-чехла.Обратите внимание, что это только одна эпоха, и она заканчивается кодированием.

import numpy as np
from matplotlib import pyplot as plt

np.random.seed(0)

fig, (ax,ax2) = plt.subplots(2,1)

def relu(x):
    c = np.where(x>0,x,0)
    return c


#Standard autoencoder
x = np.random.randint(0,2,[100,5])
w_autoencoder = np.random.normal(0,1,[5,2])


bottle_neck = relu(x.dot(w_autoencoder))

ax.scatter(bottle_neck[:,0],bottle_neck[:,1])

#VAE autoencoder

w_vae1 = np.random.normal(0,1,[5,2])
w_vae2 = np.random.normal(0,1,[5,2])

mu = relu(x.dot(w_vae1))
sigma = relu(x.dot(w_vae2))

epsilon_sample = np.random.normal(0,1,[100,2])

latent_space = mu+np.log2(sigma)*epsilon_sample

ax2.scatter(latent_space[:,0], latent_space[:,1],c='red')

w_vae1 = np.random.normal(0,1,[5,2])
w_vae2 = np.random.normal(0,1,[5,2])

mu = relu(x.dot(w_vae1))
sigma = relu(x.dot(w_vae2))

epsilon_sample = np.random.normal(0,1,[100,2])

latent_space = mu+np.log2(sigma)*epsilon_sample

ax2.scatter(latent_space[:,0], latent_space[:,1],c='red')

1 Ответ

0 голосов
/ 22 февраля 2019

Поскольку ваш мотив - «понимание», я должен сказать, что вы находитесь в правильном направлении, и работа над такого рода реализацией определенно поможет вам в понимании.Но я твердо верю, что «понимание» должно быть достигнуто сначала в книгах / бумагах и только потом через реализацию / код.

На первый взгляд ваш стандартный автоэнкодер выглядит хорошо.В вашей реализации вы предполагаете, что ваш скрытый код будет находиться в диапазоне (0, бесконечность), используя relu(x).

Однако, выполняя реализацию VAE, выневозможно получить скрытый код с функцией relu(x).Это где ваше «теоретическое» понимание отсутствует.В стандартном VAE мы предполагаем, что скрытый код является выборкой из гауссовского распределения и, таким образом, мы аппроксимируем параметры этого гауссовского распределения, то есть среднее значение и ковариацию.Кроме того, мы также делаем другое предположение, что это гауссово распределение является факториальным, что означает, что ковариационная матрица диагональ .В вашей реализации вы аппроксимируете среднее значение и диагональную ковариацию следующим образом:

mu = relu(x.dot(w_vae1))
sigma = relu(x.dot(w_vae2))

, что кажется нормальным, но при получении образца ( трюк репараметризации ), вы не знаете, почему вы ввели np.log2().Поскольку вы используете ReLU() активацию, вы можете получить 0 в вашей сигма-переменной, а когда вы выполните np.log2(0), вы получите inf.Я полагаю, что вы были мотивированы некоторым доступным кодом, где они делают:

mu = relu(x.dot(w_vae1)) #same as yours
logOfSigma = x.dot(w_vae2) #you are forcing your network to learn log(sigma)

Теперь, так как вы аппроксимируете лог сигма, вы можете позволить своему выводу быть отрицательным, потому что для получения сигмы вы должны сделать что-то вродеnp.exp(logOfSigma) и это гарантирует, что вы всегда получите положительные значения в вашей диагональной ковариационной матрице.Теперь, чтобы сделать выборку, вы можете просто сделать:

latent_code = mu + np.exp(logOfSigma)*epsilon_sample

Надеюсь, это поможет!

...