Skip to main content

ParticleGAN

GANs with a learnable particle prior, for PyTorch.

Tests

A GAN usually draws its latent code from a fixed Gaussian and leaves all of the work of covering the data to the generator; when it cannot, modes go missing. ParticleGAN replaces that noise with a table of learnable latent vectors (particles) that are optimized together with the generator, so the prior itself can move toward the data's modes. The package ships one training configuration: a relativistic-pairing (RpGAN) logistic loss, a critic gradient penalty that hands over from R1 to capped gradients plus an EMA-critic anchor as the learning rate anneals, and the optimizer settings and schedules that go with them (how it works). You write an ordinary PyTorch GAN loop; the recipe builds the pieces.

100 Gaussians: default GAN recipe converging with live weights

The package default, GANTrainer(get_recipe("gan"), G, D) with no overrides, live weights, seed 1234: 100/100 modes, 98.9% within 3σ after 7,000 updates, with all 100 modes first covered at update 1,430. Reproduce this animation.

Install

Requires Python 3.10+ and PyTorch.

python -m pip install particlegan           # the library (0.8.0)

For the examples, experiments and tests, install from source:

git clone https://github.com/255BITS/ParticleGAN.git
cd ParticleGAN
python -m pip install -e '.[experiments,dev]'  # plus examples, experiments and tests

Train a GAN

Everything comes from role-named factories on a recipe; the loop is yours.

import copy
import torch
from torch import nn
from particlegan import get_recipe, scale_learning_rates

def real_batch(n):  # replace with your DataLoader: 8 Gaussians on a ring
    angle = torch.randint(8, (n, 1)) * torch.pi / 4
    return torch.cat([angle.cos(), angle.sin()], 1) + 0.05 * torch.randn(n, 2)

recipe = get_recipe(total_steps=2000)
G = nn.Sequential(nn.Linear(recipe.z_dim, 128), nn.LeakyReLU(0.2), nn.Linear(128, 2))
D = nn.Sequential(nn.Linear(2, 128), nn.LeakyReLU(0.2), nn.Linear(128, 1))
prior = recipe.make_prior()                      # the learnable particle table
opt_g, opt_d = recipe.make_optimizers(G, D, prior, ema_critic=copy.deepcopy(D))
penalty, gan = recipe.make_critic_penalty(opt_d), recipe.make_loss()
base_lrs = [[group["lr"] for group in opt.param_groups] for opt in (opt_g, opt_d)]

for step in range(recipe.total_steps):
    scale_learning_rates(step, recipe, (opt_g, opt_d), base_lrs, prior)
    real = real_batch(recipe.batch_size)
    z, _ = prior.sample(recipe.batch_size)
    fake = G(z)

    d_loss = gan.d_loss(D(real), D(fake.detach())) + penalty(D, real, fake.detach())
    opt_d.zero_grad(); d_loss.backward(); opt_d.step()

    g_loss = gan.g_loss(D(fake), D(real))
    opt_g.zero_grad(); g_loss.backward(); opt_g.step()

opt_g and opt_d are Adam optimizers whose step() also does the formulation's step-time work, and their state_dict() holds all of its state, so checkpoint them as usual. examples/pytorch_loop.py adds the remaining pieces of the default update (critic input noise, generator output noise, EMA weights).

Or let GANTrainer run exactly that default update:

from particlegan import GANTrainer

trainer = GANTrainer(get_recipe(), G, D)
for _ in range(trainer.recipe.total_steps):
    trainer.step(real_batch(trainer.recipe.batch_size))
samples = trainer.sample(1024)

Model families

get_recipe(name) selects the model; every family trains the same way.

Name Model
gan (default) GAN with a learnable particle prior
mog GAN with a mixture-of-Gaussians particle prior
ddgan Denoising-diffusion GAN with a UCD (class-conditional) critic
ddgan_mog ddgan with a mixture-of-Gaussians prior
ae_gan Autoencoder GAN: an encoder routes data to particles
vae_gan Variational variant of ae_gan
ae_ddgan Autoencoder denoising-diffusion GAN

Any field can be overridden: get_recipe("mog", total_steps=20_000).

Learn more

Citation

@software{particlegan2025,
  author = {Martyn Garcia},
  title = {ParticleGAN: Learnable Priors for Stable GANs},
  year = {2025},
  url = {https://github.com/255BITS/ParticleGAN}
}

License

MIT

Release files for particlegan 0.8.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for particlegan 0.8.0
File Size Uploaded
particlegan-0.8.0.tar.gz 223.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for particlegan 0.8.0
File Interpreter ABI Platform
particlegan-0.8.0-py3-none-any.whl Python 3 none any Details

Total release size: 269.9 kB

Release files / particlegan-0.8.0.tar.gz

Download URL particlegan-0.8.0.tar.gz
Size 223.8 kB
Tags Source
SHA-256 checksum
How to use checksums
08e10a6320a5195619147091588ac7b17f1f40e7cbea251faaaa0e9ab4bbeb2f
BLAKE2b-256 checksum
How to use checksums
c5557f81cd8e307d136965065d6474b1afe7fae2eb5e8e270067c8af355cb05e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release files / particlegan-0.8.0-py3-none-any.whl

Download URL particlegan-0.8.0-py3-none-any.whl
Size 46.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fd4ddd6c03158e1751cad78b77acf1b0c5915fd7a0d2250b70919f97ddfc5dbe
BLAKE2b-256 checksum
How to use checksums
23ac3b89d6aff913e7de0419ce2df82b2f1285a13c92050c3096da6004e1e067
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.8.0 This release

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page