Getting Started#
pyautoencoder is a PyTorch library for building and training state-of-the-art autoencoders. It is designed to host a growing collection of autoencoder variants, with structured outputs and modular loss functions to make experimentation easy.
Installation#
Install pyautoencoder via pip:
pip install pyautoencoder
Or install from source:
git clone https://github.com/andrea-pollastro/pyautoencoders.git
cd pyautoencoders
pip install -e .
Quick Start#
Vanilla Autoencoder (AE)#
Train a simple autoencoder on MNIST:
import torch
import torch.nn as nn
from pyautoencoder.vanilla import AE
# Define encoder and decoder
encoder = nn.Sequential(
nn.Flatten(),
nn.Linear(784, 256),
nn.ReLU(),
nn.Linear(256, 64),
)
decoder = nn.Sequential(
nn.Linear(64, 256),
nn.ReLU(),
nn.Linear(256, 784),
)
# Create and build the model
model = AE(encoder=encoder, decoder=decoder)
model.build(torch.randn(1, 1, 28, 28))
# Training loop
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
x_batch = torch.randn(32, 1, 28, 28)
output = model(x_batch)
loss_results = model.compute_loss(x_batch, output, likelihood='bernoulli')
optimizer.zero_grad()
loss_results.objective.backward()
optimizer.step()
# encode/decode run under inference_mode automatically
z = model.encode(x_batch).z # AEEncodeOutput → latent tensor
x_hat = model.decode(z).x_hat # AEDecodeOutput → reconstruction tensor
Variational Autoencoder (VAE)#
Train a VAE with the reparameterization trick:
import torch
import torch.nn as nn
from pyautoencoder.variational import VAE
# Define encoder and decoder
encoder = nn.Sequential(
nn.Flatten(),
nn.Linear(784, 256),
nn.ReLU(),
nn.Linear(256, 128),
)
decoder = nn.Sequential(
nn.Linear(64, 256),
nn.ReLU(),
nn.Linear(256, 784),
)
# Create and build the model
model = VAE(encoder=encoder, decoder=decoder, latent_dim=64)
model.build(torch.randn(1, 1, 28, 28))
# Training loop
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
x_batch = torch.randn(32, 1, 28, 28)
output = model(x_batch, S=1) # S=1: single Monte Carlo sample
loss_results = model.compute_loss(x_batch, output, beta=1, likelihood='bernoulli')
optimizer.zero_grad()
loss_results.objective.backward()
optimizer.step()
Core Concepts#
ModelOutput#
All forward passes return structured output dataclasses that are easy to inspect:
output = model(x)
print(output)
# AEOutput(x_hat=Tensor(shape=(32, 1, 28, 28), dtype=torch.float32),
# z=Tensor(shape=(32, 64), dtype=torch.float32))
Loss Result#
Loss functions return structured results with optimization targets and diagnostics:
loss_results = loss_fn(x, model_output)
loss_results.objective.backward() # Optimize this
print(loss_results.diagnostics) # Log these for additional diagnostics