【问题标题】:Generating new data using VAE in keras在 keras 中使用 VAE 生成新数据
【发布时间】:2023-01-22 21:34:56
【问题描述】:

我构建了以下函数,它将一些数据作为输入并在其上运行 VAE:

def VAE(data, original_dim, latent_dim, test_size, epochs):
    
    x_train, x_test = train_test_split(data, test_size=test_size, random_state=42)
    
    # Define the VAE architecture
    #Encoder
    encoder_inputs = tf.keras.Input(shape=(original_dim,))
    x = layers.Dense(64, activation='relu')(encoder_inputs)
    x = layers.Dense(32, activation='relu')(x)
    x = layers.Dense(8, activation='relu')(x)

    #--- Custom Latent Space Layer
    z_mean = layers.Dense(units=latent_dim, name='Z-Mean', activation='linear')(x)
    z_log_sigma = layers.Dense(units=latent_dim, name='Z-Log-Sigma', activation='linear')(x)
    z = layers.Lambda(sampling, name='Z-Sampling-Layer')([z_mean, z_log_sigma, latent_dim]) # Z sampling layer

    # Instantiate the encoder
    encoder = tf.keras.Model(encoder_inputs, [z_mean, z_log_sigma, z], name='encoder')

    #Decoder
    latent_inputs = tf.keras.Input(shape=(latent_dim,))
    x = layers.Dense(8, activation='relu')(latent_inputs)
    x = layers.Dense(32, activation='relu')(x)
    x = layers.Dense(64, activation='relu')(x)
    decoder_outputs = layers.Dense(1, activation='relu')(x)

    # Instantiate the decoder
    decoder = tf.keras.Model(latent_inputs, decoder_outputs, name='decoder')

    # Define outputs from a VAE model by specifying how the encoder-decoder models are linked
    # Instantiate a VAE model
    vae = tf.keras.Model(inputs=encoder_inputs, outputs=decoder(encoder(encoder_inputs)[2]), name='vae')
    
    # Reconstruction loss compares inputs and outputs and tries to minimise the difference
    r_loss = original_dim * tf.keras.losses.mse(encoder_inputs, decoder(encoder(encoder_inputs)[2]))  # use MSE

    # KL divergence loss compares the encoded latent distribution Z with standard Normal distribution and penalizes if it's too different
    kl_loss = -0.5 * K.mean(1 + z_log_sigma - K.square(z_mean) - K.exp(z_log_sigma), axis=-1)

    #VAE total loss
    vae_loss = K.mean(r_loss + kl_loss)

    # Add loss to the model and compile it
    vae.add_loss(vae_loss)
    vae.compile(optimizer='adam')
    
    # train the model
    vae.fit(x_train, x_train, epochs=epochs, validation_data=(x_test, x_test))

在哪里

def sampling(args):
    
    z_mean, z_log_sigma, latent_dim = args
    epsilon = K.random_normal(shape=(K.shape(z_mean)[0], latent_dim), mean=0., stddev=1., seed=42)
    return z_mean + K.exp(z_log_sigma) * epsilon

我的问题是,如果我想生成新数据,使用上面的 VAE 如何实现?

如果我想采样 100 个新数据,我应该使用这个吗

   latent_mean = tf.math.reduce_mean(encoder(x_train)[2], axis=0) 
   latent_std = tf.math.reduce_std(encoder(x_train)[2], axis=0)
   latent_sample = tf.random.normal(shape=(100, latent_dim), mean=latent_mean, 
                                    stddev=latent_std)
   generated_data = decoder(latent_sample)

或者

   latent_mean = tf.math.reduce_mean(encoder(x_train)[0], axis=0) 
   latent_std = tf.math.reduce_mean(tf.math.exp(encoder(x_train))[1], axis=0)
   latent_sample = tf.random.normal(shape=(100, latent_dim), mean=latent_mean, 
                                    stddev=latent_std)
   generated_data = decoder(latent_sample)

基本上我应该从z推断出z_meanz_log_sigma还是应该直接使用z_meanz_log_sigma?有什么区别 ?

最终目标是 generated_data 的分布尽可能接近原始 data 的分布。

【问题讨论】:

    标签: python machine-learning keras deep-learning autoencoder


    【解决方案1】:

    我想你会想直接使用 z_mean 和 z_log_sigma。网络的输出不应该需要进一步减少。你会想从中取样: normal(encoder(x)[0], encoder(x)[1]) 而不是取均值和标准差的均值。

    我想您已经在使用this example,但您会注意到采样层直接连接到网络的均值和标准输出。

    https://keras.io/examples/generative/vae/

    【讨论】:

      猜你喜欢
      • 2021-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-05
      • 1970-01-01
      相关资源
      最近更新 更多