CLI tool
timbmg/VAE-CVAE-MNIST avatar
timbmg/VAE-CVAE-MNIST

timbmg/VAE-CVAE-MNIST: A Two-Model Reference Implementation for Latent Variable Models

Variational Autoencoder and Conditional Variational Autoencoder on MNIST in PyTorch

663 stars111 forksPythonLicense varies

At a glance

What is it?
This repository implements a variational autoencoder and a conditional variational autoencoder on MNIST in PyTorch, with the conditional variant gated behind a single command line flag. It is a compact teaching artifact, not a library, and its README is thin enough that you should read the source before trusting it.
Who is it for?
Adopt this repository if you want a small, readable PyTorch script that demonstrates the difference between q(z|x) and q(z|x,c) on MNIST, and you are willing to read the source because the README does not document the interface. Do not adopt it if you need a maintained library, a licence you can rely on, or anything beyond MNIST.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 60 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The Problem It Solves: Comparing a VAE and a CVAE in One Codebase

Most introductory autoencoder repositories implement one model. This one implements two, and the second is a strict extension of the first. A standard variational autoencoder learns a latent distribution q(z|x) and a decoder p(x|z). A conditional variational autoencoder adds the label to both sides, learning q(z|x,c) and p(x|z,c), so that generation can be steered by a class label rather than left to whatever the prior produces. The README cites the two source papers directly: Auto-Encoding Variational Bayes for the VAE and Semi-supervised Learning with Deep Generative Models for the CVAE. Anyone who has read the first paper and wants to see how conditioning changes the objective has a concrete place to look. The audience is narrow on purpose. This is for someone learning latent variable models in PyTorch, or someone who needs a baseline on MNIST before moving to a harder dataset. It is not aimed at production use, and nothing in the material suggests it is maintained as a library.

How the Conditional Switch Works

The mechanism is a single command line flag. According to the README, running the conditional variational autoencoder requires adding --conditional to the command. The other options, described as hyperparameter settings such as learning rate, batch size, and encoder and decoder layer depth and size, are said to live in the code rather than in the README. That design choice tells you something about the intended use. A shared training path with a boolean switch keeps the two models close enough that differences in behaviour are attributable to the conditioning itself, not to divergent training code. The cost is that the interface is undiscoverable from the documentation. You cannot tell from the README whether the flag is a store_true argument, whether it changes the loss function, or whether it alters the encoder input dimension. You have to read the argument parser and the model definition. That is a reasonable trade for a teaching repository and an unreasonable one for anything you intend to hand to a colleague who has not read the source.

What the Plots Actually Show

The README includes four result images, all produced after 10 epochs of training with default settings, which the README states were not tuned. Two show the modeled latent distribution, described as z ~ q(z|x) for the VAE and q(z|x,c) for the CVAE, drawn from 100 samples per digit. The other two show reconstructions from randomly sampled z under p(x|z) and p(x|z,c), with the note that for the CVAE each class c was given as input once. The paired layout is the useful part, because it lets you compare how the latent space organizes with and without the label. Treat the images as illustrations of the intended behaviour, not as evidence of quality. Ten epochs on MNIST with untuned defaults is a demonstration, and the README says as much. There are no reported metrics, no log-likelihood numbers, and no comparison against other implementations. If you need to know how well the model fits, you will have to measure it yourself.

Getting It Running, and What the README Does Not Tell You

The documented entry point is short: run the training script, and add --conditional to switch to the conditional model. That is the entire setup instruction in the supplied material. There is no installation section, no requirements file mentioned, no pinned PyTorch version, and no statement of which Python version is expected. The repository is Python and the description names PyTorch, so you will need a working PyTorch install, but the README does not say which one. The hyperparameters are in the code, per the README, so the practical first step is to open the argument parser and read the defaults before launching a run. Because the README does not enumerate the flags, I cannot list them here with confidence, and I will not guess at names. The honest summary is that this repository assumes you will read the source. If that assumption does not fit how you work, the setup experience will be rougher than the two-command description suggests.

Where This Repository Falls Short

The licence is the first problem. The supplied material lists the licence as unknown, and there is no LICENSE statement in the README. Without a declared licence, default copyright applies in most jurisdictions, which means you do not have clear permission to redistribute or reuse the code. For a personal study exercise that may not matter. For anything shipped, it does. Verify the licence before you build on it, and if none is present, treat reuse as unresolved rather than assume permissiveness. The second limitation is scope. MNIST is 28x28 grayscale digits. Nothing in the material suggests the code handles other datasets, and there are no configuration hooks documented for swapping data. The third is maintenance. The repository is not archived and the last push is recent, but there are no releases, so there is no versioned artifact to pin and no changelog to read. You are tracking a branch. That combination, unknown licence plus no releases plus a README that defers to the code, makes this a poor dependency and a fine reference.

The Alternative: A Framework Instead of a Script

If you want a variational autoencoder you can configure rather than read, the alternative is a probabilistic programming framework such as Pyro or a model zoo with documented APIs. The difference in approach is real. Here, the model, the training loop, and the argument handling all live in one repository, and the README treats the code as the documentation. A framework inverts that: the model is expressed in a few lines of a probabilistic DSL, inference is handled by the library, and the documentation covers the interface rather than the implementation. You get configurability, versioned releases, and a licence you can read. You give up the ability to see the whole thing in one sitting. For learning what conditioning does to a latent space, the single-file version is easier to hold in your head. For building something you will maintain, the framework wins on every axis except transparency.

Maintenance and Upgrade Cost

The cost profile here is low and mostly borne at the start. There is no package to upgrade, no dependency tree to reconcile, and no release cadence to track. You clone it, install PyTorch, and run it. The ongoing cost is the opposite of a library's: instead of periodic version bumps, you pay once in reading time, because the README does not describe the interface and the code does. The absence of releases means there is no upgrade path to plan, and also no signal about which PyTorch versions have been exercised. If you fork it, you inherit the licence question. Without a declared licence, you cannot confidently relicense your fork or publish it under terms of your choosing. That is the single item most likely to block adoption in an organisation, and it is not something the README addresses.

Editorial conclusion

Adopt this repository if you want a small, readable PyTorch script that demonstrates the difference between q(z|x) and q(z|x,c) on MNIST, and you are willing to read the source because the README does not document the interface. Do not adopt it if you need a maintained library, a licence you can rely on, or anything beyond MNIST. Before using it, open the code and confirm the command line options for learning rate, batch size, and encoder and decoder depth, since the README only points at them rather than listing them.

Official sources

  1. Issues
  2. README
  3. timbmg/VAE-CVAE-MNIST on GitHub
Community notes

Community notes