Course contents 10 / 33

10 / 33 · GANs

Wasserstein GANs and Lipschitz constraints

Why the Wasserstein-1 distance gives the generator a useful gradient where JS saturates, the WGAN critic and generator losses, and the two standard ways to keep the critic 1-Lipschitz, the gradient penalty (WGAN-GP) and spectral normalization (SN-GAN).

On this page 8

The GAN note ended with a problem. With an optimal discriminator the generator minimizes 2 DJS(P ∥ Q)−2ln⁡22\,D_{\mathrm{JS}}(P\,\|\,Q) - 2\ln 2, and when the real distribution PP and the generator’s distribution QQ have disjoint supports, DJS=ln⁡2D_{\mathrm{JS}} = \ln 2 wherever QQ sits. A (near-)optimal discriminator is then constant around the generated samples, so the minimax generator loss gets no gradient and the non-saturating one gets unstable updates (Arjovsky and Bottou, 2017, Theorems 2.1–2.2, 2.4 and 2.6; see the GAN note). The Wasserstein GAN (Arjovsky, Chintala and Bottou, 2017) replaces JS with the Wasserstein-1 distance, which keeps decreasing as QQ moves towards PP even when they do not overlap. The price is a constraint on the discriminator: it must be 1-Lipschitz. The rest of the note is about the losses and the two standard ways to meet that constraint.

Notation. PP is the real data distribution, QQ the generator’s distribution (x=G(z)x = G(z) with noise z∼pzz \sim p_z, as in the GAN note), and ff the critic: the WGAN name for the discriminator, a network with a real-valued output and no sigmoid. Its loss keeps the discriminator’s name, LD\mathcal L_D. Real samples are xr∼Px_r \sim P and fake ones xf=G(z)x_f = G(z). ∥⋅∥2\|\cdot\|_2 is the Euclidean norm.

Wasserstein-1 distance#

Think of PP and QQ as two piles of earth of equal mass. A transport plan γ(x,y)\gamma(x, y) says how much mass moves from xx to yy; its marginals must be PP and QQ, and Π(P,Q)\Pi(P, Q) is the set of all such plans (Peyré and Cuturi, 2019, Chapter 2). Moving mass mm over a distance ∥x−y∥\|x - y\| costs m ∥x−y∥m\,\|x - y\|, and W1W_1, also called the earth mover’s distance, is the cheapest total cost:

W1(P,Q)=inf⁡γ∈Π(P,Q)E(x,y)∼γ ∥x−y∥.W_1(P, Q) = \inf_{\gamma \in \Pi(P, Q)} \mathbb{E}_{(x, y)\sim\gamma}\,\|x - y\| .

A network cannot optimize directly over all transport plans. For distributions on Rd\mathbb R^d with finite first moments, E∥x∥<∞\mathbb E\|x\| < \infty under both, W1W_1 is finite and the Kantorovich–Rubinstein duality (Villani, 2009, Remark 6.5) rewrites the infimum as a supremum over functions:

W1(P,Q)=sup⁡∥f∥L≤1  [ Ex∼P f(x)−Ex∼Q f(x)],\begin{aligned} W_1(P, Q) = \sup_{\|f\|_L \le 1}\; \Big[\, &\mathbb{E}_{x\sim P}\,f(x)\\ &- \mathbb{E}_{x\sim Q}\,f(x) \Big], \end{aligned}

where ∥f∥L≤1\|f\|_L \le 1 (ff is 1-Lipschitz) means ∣f(x)−f(y)∣≤∥x−y∥|f(x) - f(y)| \le \|x - y\| for all x,yx, y. This is where the critic and its constraint come from: the critic ff plays the role of the function inside the supremum. It scores real samples high and fake ones low, but it may not change faster than distance. Without the constraint, and with P≠QP \ne Q, the supremum would be +∞+\infty, since any separating ff could be scaled up.

Why this helps. Take two point masses, P=δ0P = \delta_0 (the data) and Qθ=δθQ_\theta = \delta_\theta (the model). For every θ≠0\theta \ne 0 the supports are disjoint. The mixture M=12(P+Qθ)M = \tfrac12(P + Q_\theta) puts mass 12\tfrac12 on each atom, so each KL term in DJSD_{\mathrm{JS}} compares mass 11 with mass 12\tfrac12 on a single atom:

DJS(P ∥ Qθ)=12DKL(P ∥ M)+12DKL(Qθ ∥ M)=12ln⁡11/2+12ln⁡11/2=ln⁡2≈0.693,DKL(P ∥ Qθ)=∞,W1(P,Qθ)=∣θ∣.\begin{aligned} D_{\mathrm{JS}}(P\,\|\,Q_\theta) &= \tfrac12 D_{\mathrm{KL}}(P\,\|\,M)\\ &\quad + \tfrac12 D_{\mathrm{KL}}(Q_\theta\,\|\,M)\\ &= \tfrac12\ln\frac{1}{1/2} + \tfrac12\ln\frac{1}{1/2}\\ &= \ln 2 \approx 0.693,\\ D_{\mathrm{KL}}(P\,\|\,Q_\theta) &= \infty,\\ W_1(P, Q_\theta) &= |\theta| . \end{aligned}

The only plan moves all the mass a distance ∣θ∣|\theta|. DJSD_{\mathrm{JS}} is constant in θ\theta, so its derivative is 00; W1W_1 has slope ±1\pm 1 and always points the model towards the data. This is a point-mass version of the parallel-lines example of the WGAN paper (Arjovsky, Chintala and Bottou, 2017, Example 1). More generally, write QθQ_\theta for the distribution of Gθ(z)G_\theta(z). If the data live in a compact set, as the paper assumes throughout, and GθG_\theta is continuous in θ\theta, so is W1(P,Qθ)W_1(P, Q_\theta). On an unbounded space continuity of GθG_\theta alone is not enough, and an integrability condition is needed as well. If GθG_\theta is a feedforward network and the prior has E∥z∥<∞\mathbb E\|z\| < \infty, which supplies such a condition, W1(P,Qθ)W_1(P, Q_\theta) is continuous and also differentiable almost everywhere in θ\theta. Neither statement holds for DJSD_{\mathrm{JS}} or KL, which can jump (Arjovsky, Chintala and Bottou, 2017, Theorem 1 and Corollary 1).

Figure

D_JS is flat for disjoint supports; W₁ keeps a slope

Jensen–Shannon divergence and Wasserstein-1 distance between two point massesTop: a red point mass P at zero and a blue point mass Q theta at theta equals 0.7, with a double arrow of length theta between them. Bottom: a plot against theta from minus 1.2 to 1.2. The Jensen–Shannon divergence is a flat red line at ln 2, about 0.693, with a hole at theta equals zero where it drops to a single point at zero; it is labelled flat, no gradient. The Wasserstein-1 distance is a green V shape equal to the absolute value of theta, labelled slope plus or minus 1, useful gradient.P = δ₀ (real)Qθ = δθ (model)θ0θ00.51value−1−0.50.51θW₁ = |θ|DJS = ln 2DJS is flat:no gradient for Gslope ±1:useful gradientDJS = 0 only at θ = 0Jensen–Shannon divergence and Wasserstein-1 distance between two point massesTop: a red point mass P at zero and a blue point mass Q theta at theta equals 0.7, with a double arrow of length theta between them. Bottom: a plot against theta from minus 1.2 to 1.2. The Jensen–Shannon divergence is a flat red line at ln 2, about 0.693, with a hole at theta equals zero where it drops to a single point at zero; it is labelled flat, no gradient. The Wasserstein-1 distance is a green V shape equal to the absolute value of theta, labelled slope plus or minus 1, useful gradient.P = δ₀(real)Qθ = δθ(model)θ0θ00.51value−1−0.50.51θDJS = ln 2: flat,no gradient for GW₁ = |θ|: slope ±1,useful gradientDJS = 0 only at θ = 0
P = δ₀ is a point mass at 0 (real data) and the model Q_θ = δ_θ is a point mass at θ. For every θ ≠ 0 the supports are disjoint, so D_JS(P ‖ Q_θ) = ln 2 ≈ 0.693 nats no matter how far apart they are, and D_KL(P ‖ Q_θ) = ∞. The Wasserstein-1 distance is the cost of moving all the mass a distance |θ|, so W₁ = |θ| and its derivative ±1 always points the model towards the data. Both curves are plotted against the same vertical axis.

WGAN losses#

The critic maximizes the dual objective, so its loss is the negative of it. The generator only appears in the second expectation and wants the critic’s score on fakes to be high:

LD=−Ex∼P[f(x)]+Ez∼pz[f(G(z))],LG=−Ez∼pz[f(G(z))].\begin{aligned} \mathcal L_D &= -\mathbb{E}_{x\sim P}\big[f(x)\big] + \mathbb{E}_{z\sim p_z}\big[f(G(z))\big],\\ \mathcal L_G &= -\mathbb{E}_{z\sim p_z}\big[f(G(z))\big]. \end{aligned}

What does −LD-\mathcal L_D measure? A network family contains only some of the KK-Lipschitz functions, so even its best member gives −LD≤K W1(P,Q)-\mathcal L_D \le K\,W_1(P, Q): a lower bound, tight when the family contains KK times an optimal 1-Lipschitz critic (K=1K = 1 for a 1-Lipschitz family). In training, −LD-\mathcal L_D is a minibatch estimate of that value. Unlike a GAN discriminator, the critic should be trained close to optimality: the better the critic, the more reliable the gradient of W1W_1, whereas a better GAN discriminator saturates. It is therefore updated several times per generator step, ncritic=5n_{\text{critic}} = 5 in the original algorithm (Arjovsky, Chintala and Bottou, 2017, Section 3 and Algorithm 1).

With a constrained critic trained close to optimality, −LD-\mathcal L_D correlates with sample quality during a run, which the GAN discriminator’s loss does not (Section 4.2, Figures 3–4). The constant KK depends on the critic’s architecture, so the number is hard to compare between models with different critics, and the authors do not propose it as an evaluation metric.

The losses alone do not keep ff Lipschitz. The original WGAN clipped every critic weight to [−c,c][-c, c] after each step, which makes the critic KK-Lipschitz for some KK that depends on cc and the architecture. Its authors called this “a clearly terrible way” to enforce the constraint: a large cc makes the critic slow to train to optimality, and a small cc can make gradients vanish (Arjovsky, Chintala and Bottou, 2017, Section 3). WGAN-GP showed further that clipping biases the critic towards overly simple functions, and that without careful tuning of cc the gradients explode or vanish (Gulrajani et al., 2017, Sections 3.1–3.2). The two methods below replace clipping.

WGAN-GP: gradient penalty#

WGAN-GP (Gulrajani et al., 2017) keeps the WGAN losses and adds a penalty to the critic:

LD=Ez∼pz[f(G(z))]−Ex∼P[f(x)]+λ Ex^[(∥∇x^f(x^)∥2−1)2].\begin{aligned} \mathcal L_D = {}& \mathbb{E}_{z\sim p_z}\big[f(G(z))\big] - \mathbb{E}_{x\sim P}\big[f(x)\big]\\ &+ \lambda\,\mathbb{E}_{\hat x}\Big[\big(\|\nabla_{\hat x} f(\hat x)\|_2 - 1\big)^2\Big]. \end{aligned}

The first two terms are the WGAN critic loss written in the other order, and the generator loss LG\mathcal L_G is unchanged. The symbol LD\mathcal L_D now includes the penalty, so −LD-\mathcal L_D is no longer the estimate of the lower bound on K W1K\,W_1 from the previous section: it is that estimate minus λ\lambda times the penalty. To monitor training, log the real-minus-fake score difference EPf−EQf\mathbb E_P f - \mathbb E_Q f and the penalty separately. Read the difference with the earlier caveats, and one more: a soft constraint keeps the critic only approximately 1-Lipschitz, so the difference is not guaranteed to be a lower bound on W1W_1.

Why the gradient norm. For a differentiable ff on Rd\mathbb R^d, being 1-Lipschitz is the same as ∥∇f(x)∥2≤1\|\nabla f(x)\|_2 \le 1 everywhere (one direction from the definition of the derivative, the other from the mean value theorem along a segment). Pushing ∥∇x^f(x^)∥2\|\nabla_{\hat x} f(\hat x)\|_2 towards 11 therefore keeps ff approximately 1-Lipschitz. The literal constraint would be a one-sided penalty, max⁡(0,∥∇f∥2−1)2\max(0, \|\nabla f\|_2 - 1)^2. WGAN-GP uses the two-sided (∥∇f∥2−1)2(\|\nabla f\|_2 - 1)^2, which does not exclude the optimal critic. On a compact space, if the optimal critic f∗f^* is differentiable and the optimal coupling moves every point (π(x=y)=0\pi(x = y) = 0), then f∗f^* has gradient norm 11 along the segments between optimally coupled points, and almost everywhere under PP and QQ (Gulrajani et al., 2017, Proposition 1 and Corollary 1). In their experiments the two-sided penalty also worked slightly better (Section 4 and Appendix C). The constraint is soft: it is only checked at the sampled points x^\hat x.

Where x^\hat x comes from. Pair each real sample with a fake one, draw α∼U(0,1)\alpha \sim U(0, 1) and take a random point on the segment between them:

x^=α xr+(1−α) xf.\hat x = \alpha\,x_r + (1 - \alpha)\,x_f .

Proposition 1 concerns pairs drawn from the optimal coupling, which is unknown. WGAN-GP pairs real and fake samples at random instead. This is a heuristic motivated by the proposition: enforcing the unit norm everywhere is intractable, and enforcing it along these segments works well in practice (Gulrajani et al., 2017, Section 4). In code, α\alpha is drawn once per image and broadcast over all pixels. The gradient of the critic’s output with respect to x^\hat x is computed with torch.autograd.grad(..., create_graph=True), so that the penalty itself can be backpropagated. It is then flattened per sample into a vector gg, and its norm enters the penalty (∥g∥2−1)2{(\|g\|_2 - 1)^2}. The paper uses λ=10\lambda = 10 in all experiments (Section 4).

Figure

The gradient penalty is evaluated between real and fake samples

Interpolated points for the WGAN-GP gradient penaltyA two-dimensional scatter. Seven red real samples on the right and seven blue fake samples on the left. Each real sample is joined to a fake sample by a dashed segment, and a green point x hat lies at a random position along each segment. Faint parallel lines are level sets of the critic f. At one green point an arrow of unit length shows the gradient of f, labelled: the penalty on its norm is evaluated here.real xr ~ Pfake xf = G(z)x̂ = α xr + (1 − α) xf, α ~ U(0, 1)∇f(x̂)level sets of the critic fpenalty (‖∇f(x̂)‖2 − 1)² evaluated hereInterpolated points for the WGAN-GP gradient penaltyA two-dimensional scatter. Seven red real samples on the right and seven blue fake samples on the left. Each real sample is joined to a fake sample by a dashed segment, and a green point x hat lies at a random position along each segment. Faint parallel lines are level sets of the critic f. At one green point an arrow of unit length shows the gradient of f, labelled: the penalty on its norm is evaluated here.real xr ~ Pfake xf = G(z)x̂ = α xr + (1 − α) xf, α ~ U(0, 1)∇f(x̂)level sets of the critic fpenalty (‖∇f(x̂)‖2 − 1)² evaluated here
Seven seeded real samples (red) and fake samples (blue). Each real sample is paired with a random fake one, α is drawn from U(0, 1), and the green point α·(real) + (1 − α)·(fake) is a random point on the segment between them. The penalty λ(‖∇f‖₂ − 1)² is evaluated at these points and pushes the critic's gradient norm towards 1 there. Thin dashed lines are level sets of a critic with unit gradient pointing from the fakes to the reals; for this critic the penalty is zero, and the arrow ∇f, drawn at the plot's scale, has length 1.

No batch normalization in the critic. The penalty treats the critic as a function of one image: it constrains ∥∇x^f(x^)∥2\|\nabla_{\hat x} f(\hat x)\|_2 for each x^\hat x separately. With batch normalization the critic maps a whole minibatch of inputs to a minibatch of outputs, and a penalty on the gradient with respect to each input no longer describes the function that is being constrained. WGAN-GP therefore leaves batch normalization out of the critic and allows only normalizations that do not mix examples; the authors recommend layer normalization (Gulrajani et al., 2017, Section 4). Instance normalization, which normalizes each channel of each image over its spatial positions, also qualifies.

SN-GAN: spectral normalization#

The second approach constrains the weights instead of the gradients (Miyato et al., 2018). Miyato et al. trained their SN-GANs with the standard GAN loss and the hinge loss rather than the Wasserstein loss, with WGAN-GP as a baseline (Section 4, Eqs. 15–17). The normalization itself is a Lipschitz constraint and applies equally to a WGAN critic. Each layer’s weight matrix is divided by its spectral norm, the largest singular value:

W^=Wσmax⁡(W),σmax⁡(W)=max⁡h≠0∥Wh∥2∥h∥2.\begin{gathered} \hat W = \frac{W}{\sigma_{\max}(W)},\\ \sigma_{\max}(W) = \max_{h \ne 0}\frac{\|W h\|_2}{\|h\|_2} . \end{gathered}

What a singular value is. A linear map stretches space. It sends the unit circle to an ellipse, and the singular values say how much it stretches in each direction: the right singular vectors viv_i are mapped to σiui\sigma_i u_i, the semi-axes of the ellipse. The largest one, σmax⁡\sigma_{\max}, is the most any vector can be stretched, so it is the Lipschitz constant of h↦Whh \mapsto W h. After dividing by it, no direction is stretched by more than 11.

Figure

A matrix stretches the unit circle into an ellipse; its largest singular value is the longest semi-axis

Spectral normalization of a 2 by 2 matrixThree panels. First: the unit circle with two perpendicular unit vectors v1 and v2. Second: after multiplying by W the circle becomes a tilted ellipse; its long semi-axis sigma 1 times u1 has length 1.66 and its short semi-axis sigma 2 times u2 has length 0.58; the dashed unit circle is shown for reference. Third: after dividing W by sigma max the ellipse has semi-axes 1 and 0.35 and fits inside the dashed unit circle, touching it at plus and minus u1.unit circle ‖h‖₂ = 1v1v2after W: stretchedσ1u1σ2u2σ₁ = σmax = 1.66σ₂ = σmin = 0.58after Ŵ = W / σmaxu1touches at ±u₁longest semi-axis = 1‖Ŵh‖₂ ≤ ‖h‖₂W÷σ₁Spectral normalization of a 2 by 2 matrixThree panels. First: the unit circle with two perpendicular unit vectors v1 and v2. Second: after multiplying by W the circle becomes a tilted ellipse; its long semi-axis sigma 1 times u1 has length 1.66 and its short semi-axis sigma 2 times u2 has length 0.58; the dashed unit circle is shown for reference. Third: after dividing W by sigma max the ellipse has semi-axes 1 and 0.35 and fits inside the dashed unit circle, touching it at plus and minus u1.unit circle ‖h‖₂ = 1v1v2after W: stretchedσ1u1σ2u2σ₁ = σmax = 1.66σ₂ = σmin = 0.58after Ŵ = W / σmaxu1touches at ±u₁longest semi-axis = 1‖Ŵh‖₂ ≤ ‖h‖₂multiply by Wdivide by σmax
W = [[1.3, 0.7], [0.3, 0.9]]. Its right singular vectors v₁, v₂ are mapped to σ₁u₁ and σ₂u₂, the semi-axes of the image of the unit circle under W: σ₁ = 1.66 and σ₂ = 0.58 (their product 0.96 equals |det W|). Spectral normalization divides by the largest singular value σ₁, so the ellipse of Ŵ = W/σ₁ has semi-axes 1 and 0.35: it touches the unit circle at ±u₁ and lies inside it, so ‖Ŵh‖₂ ≤ ‖h‖₂ for every h.

For a network that alternates linear layers and 1-Lipschitz activations (ReLU, LeakyReLU), Lipschitz constants multiply under composition, so (Miyato et al., 2018, Eq. 7)

∥f∥L≤∏lσmax⁡(Wl),\|f\|_L \le \prod_{l} \sigma_{\max}(W_l),

which is at most 11 after normalization.

Unlike the gradient penalty, the constraint is imposed on the weights rather than checked at sampled points, and there is no λ\lambda to tune. In PyTorch it is a wrapper, torch.nn.utils.spectral_norm(nn.Conv2d(...)) (the newer API is torch.nn.utils.parametrizations.spectral_norm), which estimates σmax⁡\sigma_{\max} with one step of power iteration per forward pass in training mode instead of a full SVD. In practice the bound is approximate, for three reasons. Power iteration only estimates σmax⁡\sigma_{\max}. For a convolution the wrapper normalizes the kernel reshaped into a matrix, which is a proxy for the convolution’s operator norm, not equal to it; the true norm also depends on stride and padding (Gouk et al., 2021, Section 3.2; Miyato et al., 2018, footnote 3). And normalization layers placed between the convolutions are not 1-Lipschitz in general. Spectral normalization therefore keeps the critic’s Lipschitz constant under control rather than guaranteeing that it is at most 11. The product bound also need not be tight, so the normalized critic is KK-Lipschitz for some KK that can be well below 11; a WGAN critic with spectral normalization then estimates a lower bound on K W1K\,W_1 rather than W1W_1 itself.

Two dual views#

Both f-GAN, from the GAN note, and WGAN train the discriminator as the function inside a supremum. f-GAN uses the convex-conjugate bound on an f-divergence, which compares density ratios and therefore inherits the support problem of DJSD_{\mathrm{JS}} and KL. WGAN uses the Kantorovich–Rubinstein dual of a transport cost, which compares locations and stays informative when supports are disjoint. The Lipschitz constraint is the price of the second view: it is what ties the critic to the geometry of the data space.

Notebook#

The WGAN notebook of the HSE-LAMBDA Deep Generative Models repository (pinned commit; cell numbers count every cell, markdown included, from 1) implements all three variants on CelebA at 64×6464 \times 64. All three training functions use Adam with learning rate 2⋅10−42\cdot10^{-4} and betas (0.5,0.9)(0.5, 0.9), and ncritic=5n_{\text{critic}} = 5 critic steps per generator step; the WGAN-GP paper uses learning rate 10−410^{-4} and betas (0,0.9)(0, 0.9) (Gulrajani et al., 2017, Algorithm 1). The basic and WGAN-GP runs are set to 2 epochs, the spectral-normalization run to 20.

  • Cells 1–5: introduction, the earth mover’s distance with its Kantorovich–Rubinstein dual, and the WGAN objective with a real-valued critic.
  • Cells 6–9: data. CelebA: 202,599 aligned and cropped face images of 178 × 218 pixels (width × height) of 10,177 people, each annotated with 40 binary attributes such as smiling or eyeglasses. The course’s dataset class returns the attributes, and this notebook ignores them. The images are resized to 64×6464 \times 64 and scaled to [−1,1][-1, 1], batch size 1024 with drop_last=True (197 batches per epoch), and cell 9 shows a grid of real images. Cell 7 selects the device (CUDA, Apple MPS or CPU). Resize((64, 64)) with a pair of sizes scales the two sides independently, so the aspect ratio changes from 178 : 218 to 1 : 1 and the faces become about 22% wider relative to their height; Resize(64) followed by CenterCrop(64) keeps the proportions.
  • Cells 10–16: basic WGAN. Cell 12 defines the networks. The generator follows the DCGAN guidelines: z∈R100z \in \mathbb R^{100} passes through a bias-free linear layer to 512⋅4⋅4=8192512 \cdot 4 \cdot 4 = 8192 units, BatchNorm1d and ReLU, is reshaped to 512×4×4512 \times 4 \times 4, and four transposed convolutions (kernel 5, stride 2, padding 2, output padding 1) take it through 256, 128 and 64 channels to 3×64×643 \times 64 \times 64, with batch norm and ReLU after the first three and Tanh after the last. A kernel of 5 is not divisible by the stride 2, so these layers can produce checkerboard artifacts. The critic applies four stride-2 convolutions with kernel 5, 3→64→128→256→5123 \to 64 \to 128 \to 256 \to 512 channels, each followed by LeakyReLU(0.2), with InstanceNorm2d(affine=True) after the last three and no normalization at the input, then a 4×44 \times 4 convolution to one score without a sigmoid. train_wgan (cell 14) uses d_loss = -mean(real_score) + mean(fake_score) and g_loss = -mean(fake_score). The baseline applies no Lipschitz constraint, neither clipping nor penalty (cell 11). Its critic objective is therefore unbounded (the supremum above is +∞+\infty), its scores and D_loss can drift without limit, and the loss does not estimate W1W_1. Cell 13 notes that weight clipping can be added by clamping the critic’s weights after each update. Each training function draws 16 latent vectors once (fixed_noise, cells 14, 19 and 24) and decodes them after every epoch with the generator in evaluation mode, so the grids follow the same codes through training.
  • Cells 17–21: WGAN-GP. gradient_penalty (cell 18) draws α∼U(0,1)\alpha \sim U(0,1) per sample, interpolates, differentiates with create_graph=True and penalizes the per-sample L2L_2 norm; lambda_gp = 10. The critic is the same network, and its InstanceNorm2d normalizes each sample separately, so the per-sample penalty remains valid (no batch normalization in the critic). In train_wgan_gp (cell 19) the penalty receives fake_imgs without detach(), so each critic step also backpropagates through the generator. Those gradients are cleared before the generator step, so the results are unaffected, but the computation is wasted.
  • Cells 22–27: spectral normalization. DiscriminatorSN wraps every convolution in spectral_norm; in its inner blocks the normalized convolution is followed by InstanceNorm2d(affine=True) and LeakyReLU, so the bound above holds only approximately. Training uses the plain WGAN losses.
  • Cell 28: summary.

Only cells 7, 9, 26 and 27 have saved outputs: the device (mps), the grid of real images, progress bars of the spectral-normalization run, which was interrupted during epoch 11 of 20, and samples from that partly trained generator. No loss values are saved. The basic and WGAN-GP training and sampling cells have no saved outputs, so for those variants the notebook documents procedures only.

Next#

The WGAN gave the generator a useful gradient, and spectral normalization kept the critic in check. The GANs so far still produce small images of one kind at a time: faces at 64×64, digits, bedrooms. The next note follows what it took to reach large, varied, high-resolution images: growing the networks progressively, self-attention for structure that spans the whole image, and BigGAN, which scales the same recipe to all of ImageNet.

References#