Code Architecture — Pix2Pix (Image-to-Image Translation with Conditional Adversarial Networks) Notebook Structure 1. Setup & Imports Install/import PyTorch, torchvision, matplotlib, numpy Set device (CUDA if available, else CPU) Define hyperparameters: image size (256×256), batch size, learning rate (0.0002), β1=0.5, λ_L1=100, epochs 2. Dataset Preparation Edges2Shoes dataset (from the Berkeley pix2pix repository): paired edge maps → shoe photos Download a small subset (~200 pairs) for demonstration Custom Dataset class: loads paired images, splits input (edges) and target (shoes), applies transforms (resize, normalize to [-1, 1], random jitter/mirror for augmentation) DataLoader with batch_size=1 (as in the paper for best results) 3. Generator Architecture (U-Net) Encoder: 8 downsampling blocks — each: Conv2d(stride=2) → BatchNorm2d → LeakyReLU(0.2) Channels: 3→64→128→256→512→512→512→512→512 (last block no BatchNorm) Decoder: 8 upsampling blocks — each: ConvTranspose2d(stride=2) → BatchNorm2d → Dropout(0.5) → ReLU Channels: 512→512→512→512→256→128→64→3 Skip connections: concatenate encoder layer i output with decoder layer n-i input Final layer: Tanh activation (output in [-1, 1] range) Input: 3-channel edge image (256×256) → Output: 3-channel generated image (256×256) 4. Discriminator Architecture (PatchGAN) 70×70 PatchGAN: 4 convolutional layers Conv2d(3+3→64, kernel=4, stride=2) → LeakyReLU(0.2) [no BatchNorm] Conv2d(64→128, kernel=4, stride=2) → BatchNorm → LeakyReLU(0.2) Conv2d(128→256, kernel=4, stride=2) → BatchNorm → LeakyReLU(0.2) Conv2d(256→512, kernel=4, stride=1) → BatchNorm → LeakyReLU(0.2) Conv2d(512→1, kernel=4, stride=1) → Sigmoid Input: concatenation of input image + target (real) or input image + generated (fake) Output: N×N probability map (each value = probability that patch is real), averaged to scalar 5. Loss Functions GAN Loss: Binary Cross Entropy with Logits (BCEWithLogitsLoss) D real loss: D(real_pair) should be 1 D fake loss: D(fake_pair) should be 0 G adversarial loss: D(fake_pair) should be 1 (fool D) L1 Loss: L1Loss between generated and target images, weighted by λ=100 6. Training Loop For each epoch, for each batch: Forward pass: G(input) → fake_output Train D: maximize log(D(real)) + log(1 - D(fake)), with .detach() on fake Train G: minimize -log(D(fake)) + λ * L1(fake, target) Use Adam optimizer for both G and D Apply dropout in G during both train and test Track losses for plotting 7. Visualization Side-by-side grid: Input (edges) | Generated | Target (real shoes) Loss curves for G and D over epochs Save sample outputs at intervals Key Functions/Classes Component Description UNetGenerator U-Net with 8 encoder + 8 decoder blocks, skip connections, dropout on first 3 decoder blocks PatchGANDiscriminator 70×70 PatchGAN, 4 conv layers, outputs patch-level real/fake map Edge2ShoeDataset Custom Dataset: loads paired images, splits, augments train_epoch() One epoch: D step then G step, returns losses visualize_results() Grid of input/generated/target triples
Data Flow / Shapes Input: edges (B, 3, 256, 256)
→ Generator (U-Net)
→ Encoder: 256→128→64→32→16→8→4→2→1 (spatial), 64→128→256→512 channels
→ Decoder: 1→2→4→8→16→32→64→128→256 (spatial) with skip concat
→ Output: (B, 3, 256, 256) in [-1, 1]
Discriminator input: cat(input, target_or_fake) → (B, 6, 256, 256)
→ 4 conv layers → (B, 1, 30, 30) patch map
→ mean → scalar probability
Deliberate Simplifications vs Full Paper Dataset size: Using ~200 paired images instead of the full edges2shoes dataset (~50k). Results will be lower quality but demonstrate the architecture. Training duration: 200 epochs (reduced for Kaggle time limits) vs the paper’s ~200 epochs on full data. We use a smaller dataset so convergence is faster. Noise injection: Paper uses dropout at test time; we apply dropout during training only for simplicity and stability on a small dataset. No FCN-score evaluation: We skip the FCN-8s semantic segmentation metric and use visual inspection only. No AMT perceptual study: We don’t run Amazon Mechanical Turk evaluations. Single task: We demonstrate on edges→shoes only, whereas the paper tests on 8+ tasks. Image size: 256×256 as in the paper — no change here.