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 模型进行预测。
我们正在 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 模型进行预测。