Skip to content
AI360Xpert
Beta

StyleGAN

StyleGAN separates what to draw from how to render it, so coarse layers pick the pose while fine layers pick freckles, each steerable on its own.

A mapping network turns noise into a style code that steers coarse layers for pose and fine layers for texture independently
A mapping network turns noise into a style code that steers coarse layers for pose and fine layers for texture independently

Why Does This Exist?

ProGAN drew sharp megapixel faces but offered no steering wheel. Its latent vector entangled everything: nudging one number changed age, pose, and lighting together, and mixing two faces produced unpredictable blends. Artists could generate but not direct.

StyleGAN restructured the generator around control. A mapping network first converts noise zz into an intermediate code ww, and that code enters every layer separately through adaptive instance normalisation. Coarse layers read ww as pose and shape, fine layers read it as colour and microstructure. Style mixing, feeding one face's code to coarse layers and another's to fine layers, then works exactly as hoped. Editing real photos through this machinery is covered in GAN inversion.

Think of It Like This

A film director with separate departments

A director tells the set department "a rainy street", the costume department "wool coats", and the lighting crew "cold blue". Each department interprets the same script at its own scale, and the director can reshoot costumes without moving buildings.

The ww code is the script and each resolution layer is a department. Traditional generators hand every department an identical photocopy of one note; StyleGAN lets the director brief each department at its own level. The shoot fails when departments stop matching, mixed styles that clash, which is why mixing range choice matters.

How It Actually Works

The mapping network ff, eight fully connected layers, converts zz into ww. Each synthesis layer ii transforms ww into scale and bias (ys,i,yb,i)(y_{s,i}, y_{b,i}) and applies them to normalised feature maps xix_i:

AdaIN(xi,w)=ys,i(w) xi−μ(xi)σ(xi)+yb,i(w)\mathrm{AdaIN}(x_i, w) = y_{s,i}(w) \, \frac{x_i - \mu(x_i)}{\sigma(x_i)} + y_{b,i}(w)

μ\mu and σ\sigma are per-channel statistics, so each layer's content is standardised before the style is imposed. Resolution decides meaning: layers 00–77 (up to 64×6464 \times 64) set pose, face shape, and hairstyle; layers 88–1717 set colours, skin texture, and background detail. Independent per-pixel Gaussian noise injected after each convolution supplies stochastic detail like freckle placement and hair strands.

Worked example

Style-mix face A (pose donor) with face B (texture donor) at 10241024 pixels and 1818 layer pairs. Feed A's code to layers 00–77 and B's to layers 88–1717. The output keeps A's head angle and jawline but wears B's skin tone, lighting, and freckles. Move the boundary to layer 44 and A's identity leaks into mid-level features; move it to 1212 and B's pose starts intruding. The boundary position is the creative control.

Code

AdaIN in five lines, the operation that imposes style on standardised features.

def adain(x: list[list[float]], scale: float, bias: float) -> list[list[float]]:    """Impose style (scale, bias) on a single-channel feature map."""    flat = [v for row in x for v in row]    mu = sum(flat) / len(flat)  # content statistics first    sigma = (sum((v - mu) ** 2 for v in flat) / len(flat)) ** 0.5 + 1e-6    return [[round(scale * (v - mu) / sigma + bias, 2) for v in row] for row in x]

print(adain([[0.2, 0.8], [0.4, 0.6]], 1.5, 0.1))  # -> [[-1.91, 2.11], [-0.57, 0.77]]

Watch Out For

Blob artefacts from AdaIN normalisation

StyleGAN 1 occasionally renders odd round blobs, most visibly in skies and walls. The cause is the AdaIN step itself: normalising each channel lets the generator hide signal magnitude information that the next layer needs, and it compensates with localised magnitude spikes.

StyleGAN 2 redesigned normalisation into weight demodulation, removing the blobs. If you see them, you are running version 1; upgrade rather than tuning around the artefact.

Assuming every layer boundary mixes cleanly

Mixing at arbitrary boundaries can splice incompatible features, a child's jawline with an elder's skin texture, producing uncanny outputs that users blame on the model. Boundaries inside coarse layers change identity; inside fine layers change rendering.

Mix within the 00–77 versus 88–1717 split first and move the boundary deliberately. Log which ranges produced each result.

The Quick Version

  • StyleGAN maps noise zz through an 88-layer network into style code ww.
  • AdaIN imposes per-layer scale and bias on standardised features at every resolution.
  • Layers 00–77 control pose and shape; layers 88–1717 control colour and microstructure.
  • Style mixing feeds different codes to coarse and fine layers for hybrid faces.
  • Version 1 blobs come from AdaIN itself; version 2 demodulation removes them.