Master's Thesis : Master's Degree in Statistics, Universidad Carlos III de Madrid (UC3M), 2024–2025
Author: Seyed Amirhossein Mosaddad
Supervisor: Eduardo García Portugués
This repository contains all the code, experiments, and animations accompanying the master's thesis "Generative Modeling Through Diffusions". The thesis provides a step-by-step introduction to score-based diffusion generative models, covering the theory and practical implementation of:
- Score functions and score matching (explicit and denoising)
- Langevin dynamics for sampling
- Neural networks (MLPs and U-Nets) for learning score functions
- Noise-conditional score networks (NCSN)
- Stochastic differential equations (SDEs) for generative modeling
- Real data generation from the Quick, Draw! dataset
Figure 1. Overview of the theoretical and methodological framework of the thesis.
├── Example 1 - Fisher div 1/ # Score matching for N(0, θ), analytical & empirical
├── Example 2 - Fisher div 2/ # Score matching for N(μ, σ²), 2D surface optimization
├── Example 3 - Langevin diffusion/ # Langevin dynamics on a 2D Gaussian mixture
├── Example 4 - Naive model/ # Naive score matching on an oval distribution (MLP)
├── Example 5 - NCSN/ # Denoising score matching with noise-conditional score network
├── Experiment - QuickDraw/ # U-Net + VE-SDE on Quick, Draw! images (tree, car, octopus)
├── slides/ # Thesis defense presentation slides
├── assets/ # Assets
└── README.md
Demonstrates that the Fisher divergence
Figure 2. Behavior of the objective functions and their sample-based estimates across different sample sizes.
Thesis reference: Example 1, Figure 2.1
Extends Example 1 to jointly estimate both the mean and variance of a normal distribution. 3D surface plots of
Figure 3. Sample-based estimator surfaces for joint estimation of the mean and variance across increasing sample sizes.
Thesis reference: Example 2, Figure 2.2
Visualizes how Langevin dynamics generates samples from a 2D mixture of three Gaussians using the exact score function. 500 uniformly initialized points converge to the mixture modes.
Figure 4. Langevin dynamics sampling from a mixture distribution.
Thesis reference: Example 3, Figure 2.3
Trains an MLP (6 hidden layers, 1024 units, softplus activation) to learn the score function of an oval-shaped distribution via explicit score matching. Demonstrates that score estimates are accurate in high-density regions but unreliable in low-density areas.
Figure 5. Error analysis of the learned score field: angular error (left) and magnitude error (right), with contours indicating the underlying data density.
Figure 6. Langevin Markov chain trajectories from different initializations over 200 steps, indicating stable dynamics in high-density areas and unstable behavior in low-density regions.
Thesis reference: Example 4, Figures 3.1–3.4
Uses denoising score matching with multiple noise levels to address the limitations of the naive approach. Trains the same MLP architecture with a geometric noise schedule (
Figure 7. Spatial error analysis of the NCSN model across different noise levels. The top row shows magnitude error between the true and learned score fields for high (left), medium (middle), and low (right) noise levels. The bottom row shows the corresponding angular error heatmaps.
Figure 8. Perturbation of the data density across noise levels. Higher noise smooths and spreads the density; structure re-emerges as noise decreases.
Figure 9. Sample distribution evolving during annealed Langevin denoising. Samples gradually recover the true data density as noise is removed.
Thesis reference: Example 5, Figures 3.5–3.9
Trains a U-Net on 28×28 grayscale sketches from the Quick, Draw! dataset (trees, cars, octopi). Uses a Variance-Exploding SDE for the forward process and generates new images by simulating the reverse SDE with Euler–Maruyama discretization.
| With stochastic noise | Without stochastic noise |
|---|---|
| Diverse, varied samples | Collapsed to modal shapes |
Figure 10. Denoising process across the tree, car, and octopus datasets. Left: sampling with added Gaussian noise; right: without. Each row progresses from pure noise to a clean sample over 1,000 iterations (rows are independent samples).
Figure 11. Real samples from each dataset. Left: tree, Middle: car, Right: octopus.
Thesis reference: Chapter 4, Figures 4.1–4.5
- Python 3.8+
- PyTorch
- NumPy, SciPy, Matplotlib
- Google Colab (recommended for the QuickDraw experiment, trained on A100 GPU)
git clone https://github.com/soroush-msd/Generative-modeling-through-diffusions.git
cd Generative-modeling-through-diffusions
pip install torch numpy scipy matplotlibNOTE : It is best to use Conda to create an isolated environment for installing dependencies.
Examples 1-5 are Python scripts. Run them directly from the project root:
python "Example 1 - Fisher div 1/fisher_div_1.py"
python "Example 2 - Fisher div 2/fisher_div_2.py"
python "Example 3 - Langevin diffusion/LD.py"
python "Example 4 - Naive model/naive.py"
python "Example 5 - NCSN/ncsn.py"The QuickDraw experiment is a Jupyter Notebook and is recommended to run in Google Colab with GPU acceleration enabled (trained on an A100 GPU).
Each dataset has a saved model checkpoint (a plain state_dict) so you can generate samples without retraining:
| Dataset | Checkpoint |
|---|---|
| Tree | Experiment - QuickDraw/tree/ckpt_quickdraw_tree.pth |
| Car | Experiment - QuickDraw/car/ckpt_quickdraw_car.pth |
| Octopus | Experiment - QuickDraw/octopus/ckpt_quickdraw_octopus_new.pth |
The model is wrapped in torch.nn.DataParallel during training, so rebuild it the same way before loading the weights:
score_model = torch.nn.DataParallel(ScoreNet(marginal_prob_std=marginal_prob_std_fn)).to(device)
ckpt = torch.load('ckpt_quickdraw_tree.pth', map_location=device)
score_model.load_state_dict(ckpt)
score_model.eval() # ready for samplingThen run the Euler–Maruyama sampler to generate new sketches. Per-dataset training loss curves (training_loss_*.pdf) are included as well.
- Full thesis: Generative Modeling Through Diffusions - UC3M e-Archivo (open access)
- Defense slides:
slides.pdf
If you find this work useful, please consider citing:
@mastersthesis{mosaddad2025diffusions,
title = {Generative Modeling Through Diffusions},
author = {Mosaddad, Seyed Amirhossein},
school = {Universidad Carlos III de Madrid},
year = {2025},
month = {September},
type = {Master's Thesis},
note = {Master's Degree in Statistics for Data Science},
url = {https://hdl.handle.net/10016/48727}
}- Hyvärinen, A. (2005). Estimation of non-normalized statistical models by score matching. JMLR.
- Song, Y. & Ermon, S. (2019). Generative modeling by estimating gradients of the data distribution. NeurIPS.
- Song, Y. et al. (2020). Score-based generative modeling through stochastic differential equations. arXiv.
- Vincent, P. (2011). A connection between score matching and denoising autoencoders. Neural Computation.
- Song, Y. (2021). Generative modeling by estimating gradients of the data distribution (blog post).
This work is licensed under Creative Commons Attribution–NonCommercial–NoDerivatives 4.0.























































