# Chapter 6: Project: Handwritten Digit Generation with VAEs

## 6.4 Generating New Handwritten Digits

Now that our Variational Autoencoder (VAE) is trained, we can use it to generate new, artificial handwritten digits. The process of generating new data with a VAE involves two main steps:

- Sampling points from the latent space.
- Decoding these points back into the original data space.

**6.4.1 Sampling Points from the Latent Space**

The first step in the generation process is to sample points from the latent space. As we recall, the latent space of a VAE is a compressed, abstract representation of our data, and it's where the VAE learns to encode the most important features and structures of our data.

In our case, we've structured our VAE so that the latent space follows a standard normal distribution. This means we can generate new points simply by sampling from this distribution.

Here's a Python function that samples a given number of points from the latent space:

`import numpy as np`

def sample_latent_points(latent_dim, n_samples):

# Generate points in the latent space

x_input = np.random.randn(latent_dim * n_samples)

# Reshape into a batch of inputs for the network

x_input = x_input.reshape(n_samples, latent_dim)

return x_input

This function takes the dimensionality of the latent space and the number of samples we want to generate as arguments, and returns a batch of points sampled from the standard normal distribution.

**6.4.2 Decoding Points from the Latent Space**

The second step in the generation process is to decode the points we've sampled from the latent space back into the original data space. This is done by passing the points through the decoder part of our VAE.

Here's a Python function that uses our VAE's decoder to generate new handwritten digits from points in the latent space:

`def generate_digits(decoder, latent_dim, n_samples):`

# Sample points in the latent space

x_input = sample_latent_points(latent_dim, n_samples)

# Predict outputs given the points in the latent space

images = decoder.predict(x_input)

return images

In this function, we first sample a batch of points from the latent space using the

function we defined earlier. We then pass these points through the decoder part of our VAE to generate new handwritten digits.**sample_latent_points**

With these functions, we can generate any number of new, artificial handwritten digits that resemble the real digits our VAE was trained on. Note that since the generation process involves random sampling from the latent space, the generated digits will be different each time we run the function.

## 6.4 Generating New Handwritten Digits

Now that our Variational Autoencoder (VAE) is trained, we can use it to generate new, artificial handwritten digits. The process of generating new data with a VAE involves two main steps:

- Sampling points from the latent space.
- Decoding these points back into the original data space.

**6.4.1 Sampling Points from the Latent Space**

The first step in the generation process is to sample points from the latent space. As we recall, the latent space of a VAE is a compressed, abstract representation of our data, and it's where the VAE learns to encode the most important features and structures of our data.

In our case, we've structured our VAE so that the latent space follows a standard normal distribution. This means we can generate new points simply by sampling from this distribution.

Here's a Python function that samples a given number of points from the latent space:

`import numpy as np`

def sample_latent_points(latent_dim, n_samples):

# Generate points in the latent space

x_input = np.random.randn(latent_dim * n_samples)

# Reshape into a batch of inputs for the network

x_input = x_input.reshape(n_samples, latent_dim)

return x_input

This function takes the dimensionality of the latent space and the number of samples we want to generate as arguments, and returns a batch of points sampled from the standard normal distribution.

**6.4.2 Decoding Points from the Latent Space**

The second step in the generation process is to decode the points we've sampled from the latent space back into the original data space. This is done by passing the points through the decoder part of our VAE.

Here's a Python function that uses our VAE's decoder to generate new handwritten digits from points in the latent space:

`def generate_digits(decoder, latent_dim, n_samples):`

# Sample points in the latent space

x_input = sample_latent_points(latent_dim, n_samples)

# Predict outputs given the points in the latent space

images = decoder.predict(x_input)

return images

In this function, we first sample a batch of points from the latent space using the

function we defined earlier. We then pass these points through the decoder part of our VAE to generate new handwritten digits.**sample_latent_points**

With these functions, we can generate any number of new, artificial handwritten digits that resemble the real digits our VAE was trained on. Note that since the generation process involves random sampling from the latent space, the generated digits will be different each time we run the function.

## 6.4 Generating New Handwritten Digits

Now that our Variational Autoencoder (VAE) is trained, we can use it to generate new, artificial handwritten digits. The process of generating new data with a VAE involves two main steps:

- Sampling points from the latent space.
- Decoding these points back into the original data space.

**6.4.1 Sampling Points from the Latent Space**

The first step in the generation process is to sample points from the latent space. As we recall, the latent space of a VAE is a compressed, abstract representation of our data, and it's where the VAE learns to encode the most important features and structures of our data.

In our case, we've structured our VAE so that the latent space follows a standard normal distribution. This means we can generate new points simply by sampling from this distribution.

Here's a Python function that samples a given number of points from the latent space:

`import numpy as np`

def sample_latent_points(latent_dim, n_samples):

# Generate points in the latent space

x_input = np.random.randn(latent_dim * n_samples)

# Reshape into a batch of inputs for the network

x_input = x_input.reshape(n_samples, latent_dim)

return x_input

This function takes the dimensionality of the latent space and the number of samples we want to generate as arguments, and returns a batch of points sampled from the standard normal distribution.

**6.4.2 Decoding Points from the Latent Space**

The second step in the generation process is to decode the points we've sampled from the latent space back into the original data space. This is done by passing the points through the decoder part of our VAE.

Here's a Python function that uses our VAE's decoder to generate new handwritten digits from points in the latent space:

`def generate_digits(decoder, latent_dim, n_samples):`

# Sample points in the latent space

x_input = sample_latent_points(latent_dim, n_samples)

# Predict outputs given the points in the latent space

images = decoder.predict(x_input)

return images

In this function, we first sample a batch of points from the latent space using the

function we defined earlier. We then pass these points through the decoder part of our VAE to generate new handwritten digits.**sample_latent_points**

With these functions, we can generate any number of new, artificial handwritten digits that resemble the real digits our VAE was trained on. Note that since the generation process involves random sampling from the latent space, the generated digits will be different each time we run the function.

## 6.4 Generating New Handwritten Digits

- Sampling points from the latent space.
- Decoding these points back into the original data space.

**6.4.1 Sampling Points from the Latent Space**

Here's a Python function that samples a given number of points from the latent space:

`import numpy as np`

def sample_latent_points(latent_dim, n_samples):

# Generate points in the latent space

x_input = np.random.randn(latent_dim * n_samples)

# Reshape into a batch of inputs for the network

x_input = x_input.reshape(n_samples, latent_dim)

return x_input

**6.4.2 Decoding Points from the Latent Space**

`def generate_digits(decoder, latent_dim, n_samples):`

# Sample points in the latent space

x_input = sample_latent_points(latent_dim, n_samples)

# Predict outputs given the points in the latent space

images = decoder.predict(x_input)

return images

function we defined earlier. We then pass these points through the decoder part of our VAE to generate new handwritten digits.**sample_latent_points**