Menu iconMenu iconGenerative Deep Learning Updated Edition
Generative Deep Learning Updated Edition

Chapter 9: Exploring Diffusion Models

9.5 Practical Exercises - Chapter 9: Exploring Diffusion Models

This section provides practical exercises to reinforce your understanding of diffusion models and their evaluation. Each exercise includes a problem statement and a solution with code examples where applicable.

Exercise 1: Implement the Forward Diffusion Process

Problem Statement:Implement the forward diffusion process to add Gaussian noise to an input dataset over a series of time steps. Visualize the transformation of the data at each step.

Solution:

import numpy as np
import matplotlib.pyplot as plt

def forward_diffusion(data, num_steps, noise_scale=0.1):
    """
    Applies forward diffusion process to the data.

    Parameters:
    - data: The original data (e.g., an image represented as a NumPy array).
    - num_steps: The number of diffusion steps.
    - noise_scale: The scale of the Gaussian noise to be added at each step.

    Returns:
    - A list of noisy data at each diffusion step.
    """
    noisy_data = [data]
    for step in range(num_steps):
        noise = np.random.normal(scale=noise_scale, size=data.shape)
        noisy_data.append(noisy_data[-1] + noise)
    return noisy_data

# Generate a simple 1D signal
data = np.sin(np.linspace(0, 2 * np.pi, 100))
noisy_data = forward_diffusion(data, num_steps=10, noise_scale=0.1)

# Plot the noisy data
plt.figure(figsize=(10, 6))
for i, noisy in enumerate(noisy_data):
    plt.plot(noisy, label=f"Step {i}")
plt.legend()
plt.title("Forward Diffusion Process")
plt.show()

Exercise 2: Build and Train a Simple Denoising Model

Problem Statement: Build a simple denoising model using a neural network and train it to remove noise from the noisy data generated in Exercise 1.

Solution:

import tensorflow as tf
from tensorflow.keras.layers import Input, Dense, Flatten, Reshape
from tensorflow.keras.models import Model

def build_denoising_network(input_shape):
    """
    Builds a simple denoising network.

    Parameters:
    - input_shape: Shape of the input data.

    Returns:
    - A Keras model for denoising.
    """
    inputs = Input(shape=input_shape)
    x = Flatten()(inputs)
    x = Dense(128, activation='relu')(x)
    x = Dense(np.prod(input_shape), activation='linear')(x)
    outputs = Reshape(input_shape)(x)
    return Model(inputs, outputs)

# Example usage with 1D data
input_shape = (100,)
denoising_network = build_denoising_network(input_shape)
denoising_network.compile(optimizer='adam', loss='mse')

# Generate synthetic training data
num_samples = 1000
data_length = 100
training_data = generate_synthetic_data(num_samples, data_length)

# Apply forward diffusion to the training data
num_steps = 10
noise_scale = 0.1
noisy_training_data = [forward_diffusion(data, num_steps, noise_scale) for data in training_data]

# Prepare data for training
X_train = np.array([noisy[-1] for noisy in noisy_training_data])  # Final noisy state
y_train = np.array([data for data in training_data])  # Original data

# Train the denoising model
history = denoising_network.fit(X_train, y_train, epochs=20, batch_size=32, validation_split=0.2)

# Plot the training and validation loss
plt.plot(history.history['loss'], label='Training Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.title('Training and Validation Loss')
plt.show()

Exercise 3: Evaluate the Model Using MSE

Problem Statement: Evaluate the trained denoising model using the Mean Squared Error (MSE) metric on a separate test dataset.

Solution:

import numpy as np
from sklearn.metrics import mean_squared_error

# Generate synthetic test data
test_data = generate_synthetic_data(100, data_length)
noisy_test_data = [forward_diffusion(data, num_steps, noise_scale) for data in test_data]
X_test = np.array([noisy[-1] for noisy in noisy_test_data])
y_test = np.array([data for data in test_data])

# Predict denoised data
denoised_data = denoising_network.predict(X_test)

# Calculate MSE
mse = mean_squared_error(y_test.flatten(), denoised_data.flatten())
print(f"MSE: {mse}")

Exercise 4: Calculate the Fréchet Inception Distance (FID)

Problem Statement: Calculate the Fréchet Inception Distance (FID) to evaluate the quality and diversity of the denoised data generated by the model.

Solution:

from scipy.linalg import sqrtm
from numpy import cov, trace, iscomplexobj

def calculate_fid(real_images, generated_images):
    # Calculate the mean and covariance of real and generated images
    mu1, sigma1 = real_images.mean(axis=0), cov(real_images, rowvar=False)
    mu2, sigma2 = generated_images.mean(axis=0), cov(generated_images, rowvar=False)

    # Calculate the sum of squared differences between means
    ssdiff = np.sum((mu1 - mu2) ** 2.0)

    # Calculate the square root of the product of covariances
    covmean = sqrtm(sigma1.dot(sigma2))
    if iscomplexobj(covmean):
        covmean = covmean.real

    # Calculate the FID score
    fid = ssdiff + trace(sigma1 + sigma2 - 2.0 * covmean)
    return fid

# Assume denoised_data and y_test are the denoised and original data, respectively
fid_score = calculate_fid(y_test.reshape(100, -1), denoised_data.reshape(100, -1))
print(f"FID Score: {fid_score}")

Exercise 5: Visual Inspection of Denoised Data

Problem Statement: Visually inspect the denoised data generated by the model to assess its quality and coherence compared to the original and noisy data.

Solution:

import matplotlib.pyplot as plt

# Generate a sample for visual inspection
sample_idx = 0
plt.figure(figsize=(12, 4))
plt.subplot(1, 3, 1)
plt.plot(y_test[sample_idx], label='Original Data')
plt.title('Original Data')
plt.subplot(1, 3, 2)
plt.plot(X_test[sample_idx], label='Noisy Data')
plt.title('Noisy Data')
plt.subplot(1, 3, 3)
plt.plot(denoised_data[sample_idx], label='Denoised Data')
plt.title('Denoised Data')
plt.show()

These practical exercises provide hands-on experience with diffusion models and their evaluation. By implementing the forward diffusion process, building and training a denoising model, and evaluating the model using quantitative and qualitative methods, you can deepen your understanding of how diffusion models work and how to assess their performance.

Each exercise is designed to reinforce key concepts and techniques, helping you effectively apply diffusion models to various generative tasks.

9.5 Practical Exercises - Chapter 9: Exploring Diffusion Models

This section provides practical exercises to reinforce your understanding of diffusion models and their evaluation. Each exercise includes a problem statement and a solution with code examples where applicable.

Exercise 1: Implement the Forward Diffusion Process

Problem Statement:Implement the forward diffusion process to add Gaussian noise to an input dataset over a series of time steps. Visualize the transformation of the data at each step.

Solution:

import numpy as np
import matplotlib.pyplot as plt

def forward_diffusion(data, num_steps, noise_scale=0.1):
    """
    Applies forward diffusion process to the data.

    Parameters:
    - data: The original data (e.g., an image represented as a NumPy array).
    - num_steps: The number of diffusion steps.
    - noise_scale: The scale of the Gaussian noise to be added at each step.

    Returns:
    - A list of noisy data at each diffusion step.
    """
    noisy_data = [data]
    for step in range(num_steps):
        noise = np.random.normal(scale=noise_scale, size=data.shape)
        noisy_data.append(noisy_data[-1] + noise)
    return noisy_data

# Generate a simple 1D signal
data = np.sin(np.linspace(0, 2 * np.pi, 100))
noisy_data = forward_diffusion(data, num_steps=10, noise_scale=0.1)

# Plot the noisy data
plt.figure(figsize=(10, 6))
for i, noisy in enumerate(noisy_data):
    plt.plot(noisy, label=f"Step {i}")
plt.legend()
plt.title("Forward Diffusion Process")
plt.show()

Exercise 2: Build and Train a Simple Denoising Model

Problem Statement: Build a simple denoising model using a neural network and train it to remove noise from the noisy data generated in Exercise 1.

Solution:

import tensorflow as tf
from tensorflow.keras.layers import Input, Dense, Flatten, Reshape
from tensorflow.keras.models import Model

def build_denoising_network(input_shape):
    """
    Builds a simple denoising network.

    Parameters:
    - input_shape: Shape of the input data.

    Returns:
    - A Keras model for denoising.
    """
    inputs = Input(shape=input_shape)
    x = Flatten()(inputs)
    x = Dense(128, activation='relu')(x)
    x = Dense(np.prod(input_shape), activation='linear')(x)
    outputs = Reshape(input_shape)(x)
    return Model(inputs, outputs)

# Example usage with 1D data
input_shape = (100,)
denoising_network = build_denoising_network(input_shape)
denoising_network.compile(optimizer='adam', loss='mse')

# Generate synthetic training data
num_samples = 1000
data_length = 100
training_data = generate_synthetic_data(num_samples, data_length)

# Apply forward diffusion to the training data
num_steps = 10
noise_scale = 0.1
noisy_training_data = [forward_diffusion(data, num_steps, noise_scale) for data in training_data]

# Prepare data for training
X_train = np.array([noisy[-1] for noisy in noisy_training_data])  # Final noisy state
y_train = np.array([data for data in training_data])  # Original data

# Train the denoising model
history = denoising_network.fit(X_train, y_train, epochs=20, batch_size=32, validation_split=0.2)

# Plot the training and validation loss
plt.plot(history.history['loss'], label='Training Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.title('Training and Validation Loss')
plt.show()

Exercise 3: Evaluate the Model Using MSE

Problem Statement: Evaluate the trained denoising model using the Mean Squared Error (MSE) metric on a separate test dataset.

Solution:

import numpy as np
from sklearn.metrics import mean_squared_error

# Generate synthetic test data
test_data = generate_synthetic_data(100, data_length)
noisy_test_data = [forward_diffusion(data, num_steps, noise_scale) for data in test_data]
X_test = np.array([noisy[-1] for noisy in noisy_test_data])
y_test = np.array([data for data in test_data])

# Predict denoised data
denoised_data = denoising_network.predict(X_test)

# Calculate MSE
mse = mean_squared_error(y_test.flatten(), denoised_data.flatten())
print(f"MSE: {mse}")

Exercise 4: Calculate the Fréchet Inception Distance (FID)

Problem Statement: Calculate the Fréchet Inception Distance (FID) to evaluate the quality and diversity of the denoised data generated by the model.

Solution:

from scipy.linalg import sqrtm
from numpy import cov, trace, iscomplexobj

def calculate_fid(real_images, generated_images):
    # Calculate the mean and covariance of real and generated images
    mu1, sigma1 = real_images.mean(axis=0), cov(real_images, rowvar=False)
    mu2, sigma2 = generated_images.mean(axis=0), cov(generated_images, rowvar=False)

    # Calculate the sum of squared differences between means
    ssdiff = np.sum((mu1 - mu2) ** 2.0)

    # Calculate the square root of the product of covariances
    covmean = sqrtm(sigma1.dot(sigma2))
    if iscomplexobj(covmean):
        covmean = covmean.real

    # Calculate the FID score
    fid = ssdiff + trace(sigma1 + sigma2 - 2.0 * covmean)
    return fid

# Assume denoised_data and y_test are the denoised and original data, respectively
fid_score = calculate_fid(y_test.reshape(100, -1), denoised_data.reshape(100, -1))
print(f"FID Score: {fid_score}")

Exercise 5: Visual Inspection of Denoised Data

Problem Statement: Visually inspect the denoised data generated by the model to assess its quality and coherence compared to the original and noisy data.

Solution:

import matplotlib.pyplot as plt

# Generate a sample for visual inspection
sample_idx = 0
plt.figure(figsize=(12, 4))
plt.subplot(1, 3, 1)
plt.plot(y_test[sample_idx], label='Original Data')
plt.title('Original Data')
plt.subplot(1, 3, 2)
plt.plot(X_test[sample_idx], label='Noisy Data')
plt.title('Noisy Data')
plt.subplot(1, 3, 3)
plt.plot(denoised_data[sample_idx], label='Denoised Data')
plt.title('Denoised Data')
plt.show()

These practical exercises provide hands-on experience with diffusion models and their evaluation. By implementing the forward diffusion process, building and training a denoising model, and evaluating the model using quantitative and qualitative methods, you can deepen your understanding of how diffusion models work and how to assess their performance.

Each exercise is designed to reinforce key concepts and techniques, helping you effectively apply diffusion models to various generative tasks.

9.5 Practical Exercises - Chapter 9: Exploring Diffusion Models

This section provides practical exercises to reinforce your understanding of diffusion models and their evaluation. Each exercise includes a problem statement and a solution with code examples where applicable.

Exercise 1: Implement the Forward Diffusion Process

Problem Statement:Implement the forward diffusion process to add Gaussian noise to an input dataset over a series of time steps. Visualize the transformation of the data at each step.

Solution:

import numpy as np
import matplotlib.pyplot as plt

def forward_diffusion(data, num_steps, noise_scale=0.1):
    """
    Applies forward diffusion process to the data.

    Parameters:
    - data: The original data (e.g., an image represented as a NumPy array).
    - num_steps: The number of diffusion steps.
    - noise_scale: The scale of the Gaussian noise to be added at each step.

    Returns:
    - A list of noisy data at each diffusion step.
    """
    noisy_data = [data]
    for step in range(num_steps):
        noise = np.random.normal(scale=noise_scale, size=data.shape)
        noisy_data.append(noisy_data[-1] + noise)
    return noisy_data

# Generate a simple 1D signal
data = np.sin(np.linspace(0, 2 * np.pi, 100))
noisy_data = forward_diffusion(data, num_steps=10, noise_scale=0.1)

# Plot the noisy data
plt.figure(figsize=(10, 6))
for i, noisy in enumerate(noisy_data):
    plt.plot(noisy, label=f"Step {i}")
plt.legend()
plt.title("Forward Diffusion Process")
plt.show()

Exercise 2: Build and Train a Simple Denoising Model

Problem Statement: Build a simple denoising model using a neural network and train it to remove noise from the noisy data generated in Exercise 1.

Solution:

import tensorflow as tf
from tensorflow.keras.layers import Input, Dense, Flatten, Reshape
from tensorflow.keras.models import Model

def build_denoising_network(input_shape):
    """
    Builds a simple denoising network.

    Parameters:
    - input_shape: Shape of the input data.

    Returns:
    - A Keras model for denoising.
    """
    inputs = Input(shape=input_shape)
    x = Flatten()(inputs)
    x = Dense(128, activation='relu')(x)
    x = Dense(np.prod(input_shape), activation='linear')(x)
    outputs = Reshape(input_shape)(x)
    return Model(inputs, outputs)

# Example usage with 1D data
input_shape = (100,)
denoising_network = build_denoising_network(input_shape)
denoising_network.compile(optimizer='adam', loss='mse')

# Generate synthetic training data
num_samples = 1000
data_length = 100
training_data = generate_synthetic_data(num_samples, data_length)

# Apply forward diffusion to the training data
num_steps = 10
noise_scale = 0.1
noisy_training_data = [forward_diffusion(data, num_steps, noise_scale) for data in training_data]

# Prepare data for training
X_train = np.array([noisy[-1] for noisy in noisy_training_data])  # Final noisy state
y_train = np.array([data for data in training_data])  # Original data

# Train the denoising model
history = denoising_network.fit(X_train, y_train, epochs=20, batch_size=32, validation_split=0.2)

# Plot the training and validation loss
plt.plot(history.history['loss'], label='Training Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.title('Training and Validation Loss')
plt.show()

Exercise 3: Evaluate the Model Using MSE

Problem Statement: Evaluate the trained denoising model using the Mean Squared Error (MSE) metric on a separate test dataset.

Solution:

import numpy as np
from sklearn.metrics import mean_squared_error

# Generate synthetic test data
test_data = generate_synthetic_data(100, data_length)
noisy_test_data = [forward_diffusion(data, num_steps, noise_scale) for data in test_data]
X_test = np.array([noisy[-1] for noisy in noisy_test_data])
y_test = np.array([data for data in test_data])

# Predict denoised data
denoised_data = denoising_network.predict(X_test)

# Calculate MSE
mse = mean_squared_error(y_test.flatten(), denoised_data.flatten())
print(f"MSE: {mse}")

Exercise 4: Calculate the Fréchet Inception Distance (FID)

Problem Statement: Calculate the Fréchet Inception Distance (FID) to evaluate the quality and diversity of the denoised data generated by the model.

Solution:

from scipy.linalg import sqrtm
from numpy import cov, trace, iscomplexobj

def calculate_fid(real_images, generated_images):
    # Calculate the mean and covariance of real and generated images
    mu1, sigma1 = real_images.mean(axis=0), cov(real_images, rowvar=False)
    mu2, sigma2 = generated_images.mean(axis=0), cov(generated_images, rowvar=False)

    # Calculate the sum of squared differences between means
    ssdiff = np.sum((mu1 - mu2) ** 2.0)

    # Calculate the square root of the product of covariances
    covmean = sqrtm(sigma1.dot(sigma2))
    if iscomplexobj(covmean):
        covmean = covmean.real

    # Calculate the FID score
    fid = ssdiff + trace(sigma1 + sigma2 - 2.0 * covmean)
    return fid

# Assume denoised_data and y_test are the denoised and original data, respectively
fid_score = calculate_fid(y_test.reshape(100, -1), denoised_data.reshape(100, -1))
print(f"FID Score: {fid_score}")

Exercise 5: Visual Inspection of Denoised Data

Problem Statement: Visually inspect the denoised data generated by the model to assess its quality and coherence compared to the original and noisy data.

Solution:

import matplotlib.pyplot as plt

# Generate a sample for visual inspection
sample_idx = 0
plt.figure(figsize=(12, 4))
plt.subplot(1, 3, 1)
plt.plot(y_test[sample_idx], label='Original Data')
plt.title('Original Data')
plt.subplot(1, 3, 2)
plt.plot(X_test[sample_idx], label='Noisy Data')
plt.title('Noisy Data')
plt.subplot(1, 3, 3)
plt.plot(denoised_data[sample_idx], label='Denoised Data')
plt.title('Denoised Data')
plt.show()

These practical exercises provide hands-on experience with diffusion models and their evaluation. By implementing the forward diffusion process, building and training a denoising model, and evaluating the model using quantitative and qualitative methods, you can deepen your understanding of how diffusion models work and how to assess their performance.

Each exercise is designed to reinforce key concepts and techniques, helping you effectively apply diffusion models to various generative tasks.

9.5 Practical Exercises - Chapter 9: Exploring Diffusion Models

This section provides practical exercises to reinforce your understanding of diffusion models and their evaluation. Each exercise includes a problem statement and a solution with code examples where applicable.

Exercise 1: Implement the Forward Diffusion Process

Problem Statement:Implement the forward diffusion process to add Gaussian noise to an input dataset over a series of time steps. Visualize the transformation of the data at each step.

Solution:

import numpy as np
import matplotlib.pyplot as plt

def forward_diffusion(data, num_steps, noise_scale=0.1):
    """
    Applies forward diffusion process to the data.

    Parameters:
    - data: The original data (e.g., an image represented as a NumPy array).
    - num_steps: The number of diffusion steps.
    - noise_scale: The scale of the Gaussian noise to be added at each step.

    Returns:
    - A list of noisy data at each diffusion step.
    """
    noisy_data = [data]
    for step in range(num_steps):
        noise = np.random.normal(scale=noise_scale, size=data.shape)
        noisy_data.append(noisy_data[-1] + noise)
    return noisy_data

# Generate a simple 1D signal
data = np.sin(np.linspace(0, 2 * np.pi, 100))
noisy_data = forward_diffusion(data, num_steps=10, noise_scale=0.1)

# Plot the noisy data
plt.figure(figsize=(10, 6))
for i, noisy in enumerate(noisy_data):
    plt.plot(noisy, label=f"Step {i}")
plt.legend()
plt.title("Forward Diffusion Process")
plt.show()

Exercise 2: Build and Train a Simple Denoising Model

Problem Statement: Build a simple denoising model using a neural network and train it to remove noise from the noisy data generated in Exercise 1.

Solution:

import tensorflow as tf
from tensorflow.keras.layers import Input, Dense, Flatten, Reshape
from tensorflow.keras.models import Model

def build_denoising_network(input_shape):
    """
    Builds a simple denoising network.

    Parameters:
    - input_shape: Shape of the input data.

    Returns:
    - A Keras model for denoising.
    """
    inputs = Input(shape=input_shape)
    x = Flatten()(inputs)
    x = Dense(128, activation='relu')(x)
    x = Dense(np.prod(input_shape), activation='linear')(x)
    outputs = Reshape(input_shape)(x)
    return Model(inputs, outputs)

# Example usage with 1D data
input_shape = (100,)
denoising_network = build_denoising_network(input_shape)
denoising_network.compile(optimizer='adam', loss='mse')

# Generate synthetic training data
num_samples = 1000
data_length = 100
training_data = generate_synthetic_data(num_samples, data_length)

# Apply forward diffusion to the training data
num_steps = 10
noise_scale = 0.1
noisy_training_data = [forward_diffusion(data, num_steps, noise_scale) for data in training_data]

# Prepare data for training
X_train = np.array([noisy[-1] for noisy in noisy_training_data])  # Final noisy state
y_train = np.array([data for data in training_data])  # Original data

# Train the denoising model
history = denoising_network.fit(X_train, y_train, epochs=20, batch_size=32, validation_split=0.2)

# Plot the training and validation loss
plt.plot(history.history['loss'], label='Training Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.title('Training and Validation Loss')
plt.show()

Exercise 3: Evaluate the Model Using MSE

Problem Statement: Evaluate the trained denoising model using the Mean Squared Error (MSE) metric on a separate test dataset.

Solution:

import numpy as np
from sklearn.metrics import mean_squared_error

# Generate synthetic test data
test_data = generate_synthetic_data(100, data_length)
noisy_test_data = [forward_diffusion(data, num_steps, noise_scale) for data in test_data]
X_test = np.array([noisy[-1] for noisy in noisy_test_data])
y_test = np.array([data for data in test_data])

# Predict denoised data
denoised_data = denoising_network.predict(X_test)

# Calculate MSE
mse = mean_squared_error(y_test.flatten(), denoised_data.flatten())
print(f"MSE: {mse}")

Exercise 4: Calculate the Fréchet Inception Distance (FID)

Problem Statement: Calculate the Fréchet Inception Distance (FID) to evaluate the quality and diversity of the denoised data generated by the model.

Solution:

from scipy.linalg import sqrtm
from numpy import cov, trace, iscomplexobj

def calculate_fid(real_images, generated_images):
    # Calculate the mean and covariance of real and generated images
    mu1, sigma1 = real_images.mean(axis=0), cov(real_images, rowvar=False)
    mu2, sigma2 = generated_images.mean(axis=0), cov(generated_images, rowvar=False)

    # Calculate the sum of squared differences between means
    ssdiff = np.sum((mu1 - mu2) ** 2.0)

    # Calculate the square root of the product of covariances
    covmean = sqrtm(sigma1.dot(sigma2))
    if iscomplexobj(covmean):
        covmean = covmean.real

    # Calculate the FID score
    fid = ssdiff + trace(sigma1 + sigma2 - 2.0 * covmean)
    return fid

# Assume denoised_data and y_test are the denoised and original data, respectively
fid_score = calculate_fid(y_test.reshape(100, -1), denoised_data.reshape(100, -1))
print(f"FID Score: {fid_score}")

Exercise 5: Visual Inspection of Denoised Data

Problem Statement: Visually inspect the denoised data generated by the model to assess its quality and coherence compared to the original and noisy data.

Solution:

import matplotlib.pyplot as plt

# Generate a sample for visual inspection
sample_idx = 0
plt.figure(figsize=(12, 4))
plt.subplot(1, 3, 1)
plt.plot(y_test[sample_idx], label='Original Data')
plt.title('Original Data')
plt.subplot(1, 3, 2)
plt.plot(X_test[sample_idx], label='Noisy Data')
plt.title('Noisy Data')
plt.subplot(1, 3, 3)
plt.plot(denoised_data[sample_idx], label='Denoised Data')
plt.title('Denoised Data')
plt.show()

These practical exercises provide hands-on experience with diffusion models and their evaluation. By implementing the forward diffusion process, building and training a denoising model, and evaluating the model using quantitative and qualitative methods, you can deepen your understanding of how diffusion models work and how to assess their performance.

Each exercise is designed to reinforce key concepts and techniques, helping you effectively apply diffusion models to various generative tasks.