Вариационный автоэнкодер в Keras: Как добиться разной производительности слоя Keras во время обучения и прогнозирования? - PullRequest
1 голос
/ 24 марта 2020

Мы реализуем документ под названием - " Вариационные автокодеры для совместной фильтрации " в TF 2.0. Пример реализации вышеупомянутой статьи в TF 1.0 приведен здесь .

В статье предлагается реализация вариационного автоэнкодера для совместной фильтрации. В качестве выходного сигнала кодировщика он использует трюк репараметризации для выборки скрытого вектора Z во время обучения сети.

Трюк репараметризации выборки ϵ ∼ N (0, IK) и репараметризацию скрытого вектора Z как: Zu = µϕ (xu) + ϵ ⊙ σϕ (xu) , где µϕ и σϕ вычисляются из выходных данных encoder.

Но во время прогнозирования документ предлагает использовать только µϕ для выборки Z .

В нашей реализации мы использовал пользовательский tf.keras.layers.Layer для выборки скрытого вектора Z . Ниже приведен код архитектуры:

class Reparameterize(tf.keras.layers.Layer):
  """
  Custom layer.

  Reparameterization trick, sample random latent vectors Z from 
  the latent Gaussian distribution.

  The sampled vector Z is given by
  sampled_z = mean + std * epsilon
  """
  def call(self, inputs):
    Z_mu, Z_logvar = inputs

    Z_sigma = tf.math.exp(0.5 * Z_logvar)
    epsilon = tf.random.normal(tf.shape(Z_sigma))
    return Z_mu + Z_sigma * epsilon


class VAE:
  def __init__(self, input_dim, latent_dim=200):

    # encoder
    encoder_input = Input(shape=input_dim)
    X = tf.math.l2_normalize(encoder_input, 1)
    X = Dropout(0.5)(X)
    X = Dense(600, activation='tanh')(X)

    Z_mu = Dense(latent_dim)(X)
    Z_logvar = Dense(latent_dim)(X)

    sampled_Z = Reparameterize()([Z_mu, Z_logvar])

    # decoder
    decoder_input = Input(shape=latent_dim)
    X = Dense(600, activation='tanh')(decoder_input)
    logits = Dense(input_dim)(X)

    # define losses
    """
    custom loss function
    def loss(X_true, X_pred)
    """

    # create models
    self.encoder = Model(encoder_input, [Z_logvar, Z_mu, sampled_Z], name='encoder')
    self.decoder = Model(decoder_input, logits, name='decoder')

    self.vae = Model(encoder_input, self.decoder(sampled_Z), name='vae')
    self.vae.add_loss(kl_divergence(Z_logvar, Z_mu))

    # compile the model
    self.vae.compile(optimizer='adam', loss=loss, metrics=[loss])

Теперь, я ищу способ изменить реализацию пользовательского Перепараметризировать слой во время прогнозирования для использования только µϕ (Z_mu) для выборки Z , чтобы достичь того, что предлагается в упомянутой выше статье.

Или, если есть другой способ сделать это в Tf 2.0, любезно рекомендую.

1 Ответ

1 голос
/ 24 марта 2020

Вы можете сделать:

# create your VAE model
my_vae = VAE(input_dim = my_input_dim)
# Train it as you wish
# .....

Когда обучение закончено, вы можете использовать его следующим образом:

inp = Input(shape = my_input_dim)
_, Z_mu,_ = my_vae.encoder(inp) # my_vae is your trained model, get its outputs
decoder_output = my_vae.decoder(Z_mu) # use the Z_mu as input to decoder
vae_predictor = Model(inp, decoder_output) # create your prediction time model

Вы можете использовать модель vae_predictor сейчас для прогнозов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...