A Variational Autoencoder (VAE) helps us learn how to create new data similar to what we have, like making new pictures that look like real ones.
Variational Autoencoder in Computer Vision
class VAE(tf.keras.Model): def __init__(self, latent_dim): super(VAE, self).__init__() self.encoder = ... # define encoder model self.decoder = ... # define decoder model self.latent_dim = latent_dim def sample(self, eps=None): if eps is None: eps = tf.random.normal(shape=(100, self.latent_dim)) return self.decode(eps, apply_sigmoid=True) def encode(self, x): mean, logvar = self.encoder(x) return mean, logvar def reparameterize(self, mean, logvar): eps = tf.random.normal(shape=tf.shape(mean)) return eps * tf.exp(logvar * 0.5) + mean def decode(self, z, apply_sigmoid=False): logits = self.decoder(z) if apply_sigmoid: probs = tf.sigmoid(logits) return probs return logits
The encoder learns to represent input data as two values: mean and log variance.
The reparameterization trick allows backpropagation through random sampling.
mean, logvar = vae.encode(input_image)
z = vae.reparameterize(mean, logvar)
reconstructed = vae.decode(z, apply_sigmoid=True)loss = reconstruction_loss + kl_divergence_loss optimizer.minimize(loss, vae.trainable_variables)
This program trains a simple VAE on MNIST digits for 3 epochs, then shows the sum of pixel values of an original and its reconstruction to see how close they are.
import tensorflow as tf from tensorflow.keras import layers class Sampling(layers.Layer): def call(self, inputs): mean, logvar = inputs eps = tf.random.normal(shape=tf.shape(mean)) return eps * tf.exp(logvar * 0.5) + mean latent_dim = 2 # Encoder encoder_inputs = tf.keras.Input(shape=(28, 28, 1)) x = layers.Flatten()(encoder_inputs) x = layers.Dense(128, activation='relu')(x) mean = layers.Dense(latent_dim)(x) logvar = layers.Dense(latent_dim)(x) z = Sampling()([mean, logvar]) encoder = tf.keras.Model(encoder_inputs, [mean, logvar, z], name='encoder') # Decoder latent_inputs = tf.keras.Input(shape=(latent_dim,)) x = layers.Dense(128, activation='relu')(latent_inputs) x = layers.Dense(28 * 28, activation='sigmoid')(x) decoder_outputs = layers.Reshape((28, 28, 1))(x) decoder = tf.keras.Model(latent_inputs, decoder_outputs, name='decoder') # VAE Model class VAE(tf.keras.Model): def __init__(self, encoder, decoder): super(VAE, self).__init__() self.encoder = encoder self.decoder = decoder def call(self, x): mean, logvar, z = self.encoder(x) reconstructed = self.decoder(z) kl_loss = -0.5 * tf.reduce_mean(1 + logvar - tf.square(mean) - tf.exp(logvar)) self.add_loss(kl_loss) return reconstructed # Load data (x_train, _), (x_test, _) = tf.keras.datasets.mnist.load_data() x_train = x_train.astype('float32') / 255. x_train = x_train[..., tf.newaxis] x_test = x_test.astype('float32') / 255. x_test = x_test[..., tf.newaxis] vae = VAE(encoder, decoder) vae.compile(optimizer='adam', loss=tf.keras.losses.MeanSquaredError()) # Train vae.fit(x_train, x_train, epochs=3, batch_size=64) # Test reconstruction import numpy as np sample = x_test[:1] reconstructed = vae(sample) print('Original pixel sum:', np.sum(sample.numpy())) print('Reconstructed pixel sum:', np.sum(reconstructed.numpy()))
The KL divergence loss helps the model learn a smooth latent space.
Using a small latent dimension (like 2) helps visualize the latent space.
Training longer usually improves reconstruction quality.
Variational Autoencoders learn to compress and generate data by encoding inputs into a latent space with randomness.
The reparameterization trick allows training with random sampling.
They are useful for generating new data and understanding data features.
Practice
Solution
Step 1: Understand VAE's role in data compression
VAEs encode input data into a smaller latent space that captures important features.Step 2: Recognize VAE's generative ability
VAEs can generate new data by sampling from the latent space, unlike simple compression methods.Final Answer:
To compress data into a smaller, meaningful representation and generate new data samples -> Option AQuick Check:
VAE purpose = compress + generate [OK]
- Confusing VAE with classifiers
- Thinking VAE only compresses without generation
- Mixing VAE with image enhancement methods
Solution
Step 1: Identify where randomness is needed
Randomness is introduced to sample from the latent space during training.Step 2: Recognize the reparameterization trick's role
This trick allows gradients to flow through random sampling by expressing sampling as a deterministic function plus noise.Final Answer:
The reparameterization trick -> Option BQuick Check:
Randomness in VAE = reparameterization trick [OK]
- Thinking encoder output is random by itself
- Confusing decoder input with randomness source
- Assuming loss function adds randomness
z if mu and log_var have shape (batch_size, latent_dim)?
std = torch.exp(0.5 * log_var) eps = torch.randn_like(std) z = mu + eps * std
Solution
Step 1: Analyze shapes of mu and log_var
Both have shape (batch_size, latent_dim), so std and eps will match this shape.Step 2: Calculate z shape from element-wise operations
Since z = mu + eps * std is element-wise, z keeps the same shape as mu and std.Final Answer:
(batch_size, latent_dim) -> Option DQuick Check:
z shape = mu shape = (batch_size, latent_dim) [OK]
- Swapping batch_size and latent_dim dimensions
- Assuming z is a vector, not a batch
- Confusing shape of eps with mu
Solution
Step 1: Understand cause of blurry images
Blurriness often means the latent space is too small to capture enough detail.Step 2: Choose the fix that increases detail capacity
Increasing latent dimension allows encoding more features, improving sharpness.Final Answer:
Increase the latent space dimension to capture more details -> Option CQuick Check:
More latent dims = better detail [OK]
- Removing KL divergence breaks training stability
- Changing batch size rarely fixes blurriness
- Simplifying decoder reduces model power
Solution
Step 1: Understand VAE latent space distribution
The latent space is modeled as a standard normal distribution after training.Step 2: Generate images by sampling and decoding
Sampling random points from this distribution and decoding them produces new images similar to training data.Final Answer:
Sample random points from a standard normal distribution, then pass them through the decoder -> Option AQuick Check:
Generate = sample latent + decode [OK]
- Feeding noise into encoder instead of decoder
- Using encoder outputs as images directly
- Retraining VAE unnecessarily for generation
Ready to prove it?
Pass the test and this pattern moves unknown
