ProGAN
ProGAN grows the generator and critic from thumbnails to megapixels, mastering each resolution before the next layer of detail is even added.
Why Does This Exist?
Jumping straight to generation fails reliably. The critic instantly spots high-frequency flaws, gradients turn chaotic, and training collapses before the generator learns even coarse face layout. Resolution is the enemy of stability.
ProGAN sidesteps the fight by scheduling it. Both networks start at , where the game is easy and layout is everything. Once thumbnails stabilise, a new layer fades in on each side and resolution doubles. By the time pixels arrive, the generator already draws correct faces and only refines pores and hair. The style-based successor that builds on this schedule is StyleGAN, and the scale-driven cousin is BigGAN.
Think of It Like This
An art student who earns bigger canvases
A teacher starts a student on postage stamps: composition only, no detail possible. When stamps look right, the student graduates to postcards, then to posters, then to murals. Each new size arrives with the previous skills intact, so the mural has correct composition from day one and the student only practices fine brushwork.
Direct-to-mural students drown in detail before learning composition. The fade-in below is the graduation ceremony: the new canvas blends in gradually so skills transfer instead of resetting.
How It Actually Works
Training proceeds in stages , nine doublings. When a stage begins, the new high-resolution layers join through a fade-in: output is , with sliding over thousands of images. At the network behaves exactly as the previous stage; at the new layers fully own the resolution.
Three stabilisers ride along. Minibatch standard deviation appends the batch's feature variation as a channel, so the critic notices collapsed batches directly. Equalised learning rate scales weights at runtime by , keeping update sizes uniform across layers. Pixelwise feature normalisation caps runaway magnitudes in the generator.
Worked example
Midway through the fade with , a pixel's value is half the upsampled output and half the new layers. If the old path says and the new layers say , the output is . Early on the trusted old path dominates; late in the fade the new detail takes over without any sudden shock to the critic.
Code
Fade-in blending, the three lines that make growing painless.
def fade_in(old: float, new: float, alpha: float) -> float: """Blend upsampled previous stage with fresh high-res layers.""" return (1 - alpha) * old + alpha * new
print(fade_in(0.4, 0.8, 0.0)) # -> 0.4 previous stage onlyprint(round(fade_in(0.4, 0.8, 0.5), 2)) # -> 0.6 halfway through the fadeprint(fade_in(0.4, 0.8, 1.0)) # -> 0.8 new layers fully own itWatch Out For
Rushing the fade schedule
Double resolution every few thousand images and the new layers never integrate: hits while the fresh convolutions still output noise, and the critic, suddenly facing garbage detail, destabilises the whole stack.
Hold each resolution until samples look clean at that size, typically hundreds of thousands of images per stage. The schedule is the method; hurrying it reverts to direct high-res training.
Forgetting minibatch statistics at sample time
Minibatch standard deviation needs a real batch to compute variation. Generate a single image and the statistic is degenerate, subtly shifting quality versus batch sampling.
Sample in batches even for demos, or accept the small single-sample shift. Never compare single-sample and batch-sample quality as if conditions matched.
The Quick Version
- ProGAN grows both networks from to in nine doublings.
- New layers fade in with sliding , blending old upsampled output with new detail.
- At with paths and , the output is exactly .
- Minibatch standard deviation, equalised learning rate, and pixel normalisation stabilise training.
- Rushed schedules and single-sample generation are the two classic mistakes.