← Back to list

Building a Modern Masked Autoencoder (MAE) from Scratch in PyTorch

Deep learning has a data problem. While supervised learning has given us incredible breakthroughs in computer vision, annotating millions…

Asheer Adnan · 2026-05-02 10:45 · 0 claps · 3.6 min read
#aem #image-reconstruction
Open on Medium ↗
Wiki topics: MM · Multimodal & Generative Media ML · Machine Learning EDU · Education & Learning

Building a Modern Masked Autoencoder (MAE) from Scratch in PyTorch

Deep learning has a data problem. While supervised learning has given us incredible breakthroughs in computer vision, annotating millions of images by hand is expensive, slow, and non-scalable. Enter Self-Supervised Learning (SSL) a paradigm that allows models to learn rich, structural representations from raw data without needing a single label.

Recently, I decided to build one of the most elegant SSL architectures from scratch: the Masked Autoencoder (MAE), originally introduced by Kaiming He et al. in 2022. But rather than just recreating the original paper, I decided to modernize it with recent architectural upgrades like Flash Attention, RMSNorm, and SwiGLU.

Here is a deep dive into how I built, optimized, and deployed this self-supervised vision learner.

What is a Masked Autoencoder (MAE)?

The core idea behind MAE is brilliantly simple: hide a massive portion of an image and force the model to predict the missing pieces.

Unlike standard autoencoders that compress and decompress entire images, an MAE operates on patches.

  1. Patchify: The image is divided into a grid of 16x16 patches.
  2. Mask: We randomly drop 75% of those patches. The model only gets to see 25% of the original image.
  3. Reconstruct: We pass the visible patches through an encoder, append learnable “mask tokens,” and use a decoder to reconstruct the original pixels.

By predicting the missing 75% of the image, the model is forced to learn a deep understanding of object structure, lighting, and semantic context. It cannot just memorize pixels; it has to understand what makes a dog look like a dog, or a car look like a car.

Architecture: Asymmetric Vision Transformers

My implementation utilizes an asymmetric architecture, meaning the Encoder is much heavier than the Decoder. This makes the model highly efficient to train because the massive Encoder only processes the 25% visible patches.

  • The Encoder (ViT-Base/16): A heavy lifting, 12-layer Vision Transformer with 768 hidden dimensions and 12 attention heads. It weighs in at roughly 86M parameters.
  • The Decoder (ViT-Small/16): A lighter, 12-layer Transformer with 384 hidden dimensions and 6 attention heads. It takes the encoded latent representations, adds mask tokens for the missing patches, and projects them back into pixel space. It sits at around 22M parameters.

Modernizing the Stack (2026 Updates)

To push the performance and stability of this model, I integrated several modern optimizations into the base PyTorch layers:

  • RMSNorm: Replaced standard LayerNorm for better gradient flow and computational efficiency.
  • SwiGLU Feed-Forward Networks: Swapped out the traditional GELU MLPs for SwiGLU, which provides a much better inductive bias for modern Transformers.
  • Flash Attention: Leveraged PyTorch’s native Scaled Dot-Product Attention (SDPA) for memory-efficient, lightning-fast self-attention.
  • LayerScale: Introduced per-layer scaling to stabilize the training of deeper networks.

The Training Pipeline

I trained the model on TinyImageNet (upsampled to 224x224) using a highly optimized PyTorch training loop.

Because Vision Transformers can be notoriously difficult to train, I utilized a heavily regularized setup:

  • Optimizer: AdamW with decoupled weight decay (explicitly ignoring biases and normalization layers to prevent feature collapse).
  • Scheduling: A cosine learning rate schedule with a 10-epoch linear warmup.
  • Loss Function: Beyond the standard Mean Squared Error (MSE) calculated strictly on the masked patches, I implemented per-patch normalization (a crucial trick from the original paper) and a frequency-domain auxiliary loss (FFT L1) to preserve high-frequency texture details.
  • Hardware Utilization: Accelerated the 50-epoch run using mixed-precision training (AMP), Distributed DataParallel across multiple GPUs, and torch.compile for JIT execution speeds. I also maintained an Exponential Moving Average (EMA) of the weights for a smoother, more robust final checkpoint.

Deployment: Bringing it to the Web

Training a model is only half the battle; people need to interact with it.

Using Streamlit, I built a front-end interface that allows users to upload their own images, adjust the masking ratio via a slider (e.g., dialing it from 50% up to a highly challenging 85%), and watch the MAE reconstruct the missing patches in real-time using the saved .pth weights.

Conclusion

Building an MAE from the ground up is an incredible exercise in understanding both the mechanics of Vision Transformers and the nuances of distributed model training. By stripping away labels and forcing the network to understand the raw structure of visual data, self-supervised learning continues to prove itself as the future of computer vision.

If you want to dive into the code, check out the full implementation (including the custom PyTorch modules and Streamlit app) on my GitHub!

**[Link to GitHub Repository]**

[Link to Hugging Face Model]


메타데이터
post_id
417e5e353f63
slug
building-a-modern-masked-autoencoder-mae-from-scratch-in-pytorch-417e5e353f63
url
https://medium.com/@asheeradnan/building-a-modern-masked-autoencoder-mae-from-scratch-in-pytorch-417e5e353f63
canonical_url
https://medium.com/@asheeradnan/building-a-modern-masked-autoencoder-mae-from-scratch-in-pytorch-417e5e353f63
author_url
https://medium.com/@asheeradnan
status
ok
fetched_at
2026-07-31 00:41:58