Keras 中的变分自动编码器:如何在训练和预测时实现 Keras Layer 的不同输出?

Variational Autoencoder in Keras: How to achieve different output of a Keras Layer at the time of training and prediction?

我们正在 TF 2.0 中实现一篇名为“Variational Autoencoders for Collaborative Filtering”的论文。 以上论文在TF 1.0中的示例实现给出here.

本文提出了一种用于协同过滤的变分自动编码器的实现。作为编码器的输出,它在训练网络时使用重新参数化技巧对潜在向量Z进行采样。

重新参数化技巧 对 ε ∼ N (0, IK) 进行采样并将潜在向量 Z 重新参数化为: Zu = µϕ(xu ) + ϵ ⊙ σϕ(xu) 其中µϕ和σϕ是根据编码器的输出计算的。

但是,在预测的时候,论文提出只使用µϕ进行采样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中有其他方法,请推荐。

你可以这样做:

# 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 模型进行预测。