Skip to main content

Image Colorization with a Conditional GAN in CIELAB

·457 words·3 mins
Hakan Ates
Author
Hakan Ates
I build full-stack applications and LLM-powered tools.
A Pix2Pix-style conditional GAN that colorizes grayscale CIFAR-10 images by predicting only the a/b chrominance channels from lightness. Course project for Neural Networks and Deep Learning at the University of Padua.
3x3 grid comparing ground truth, grayscale input, and generated colorizations
Ground truth, grayscale input, and generated output on 32x32 CIFAR-10 images. Two rows are convincing; the fox in the middle row comes out miscolored.

Highlights
#

  • Built a Pix2Pix-style conditional GAN in PyTorch, pairing a U-Net generator with a CNN discriminator to colorize grayscale CIFAR-10 with adversarial plus L1 loss.
  • Designed the data pipeline around CIELAB color space so the generator predicts only the two a/b chrominance channels from the L channel.
  • Diagnosed two GAN training failure modes: overfitting when trained on a 1% data subset, then discriminator dominance on the full 50,000-image set.

How it works
#

flowchart TD
    A[CIFAR-10 RGB image] --> B[Convert to CIELAB]
    B --> C[L channel input]
    C --> D[U-Net generator]
    D --> E["Predicted a/b channels"]
    C --> F["Concatenate L + a/b"]
    E --> F
    F --> G["CNN discriminator
real vs generated"]

Case Study
#

Problem. Recovering color from a grayscale image is underdetermined: many colorings are consistent with the same lightness values. For the course project, our three-person team (with Fikriye Sari and Natalija Tonic) built a conditional GAN to learn plausible colorizations from data.

Approach. We followed the Pix2Pix idea: a U-Net generator conditioned on the grayscale input and a CNN discriminator classifying real versus generated colorizations. The decision we defended in the report was to work in CIELAB and predict only the a/b chrominance channels from the L channel, then concatenate. Predicting 2 channels is an easier, more stable task than predicting 3 RGB values per pixel, and Lab separates luminance from color in a perceptually uniform way. I wrote the model and training code and the CIELAB data pipeline; training used Adam (lr 0.0002, betas 0.5/0.999), binary cross-entropy for the discriminator, and adversarial plus L1 loss for the generator on CIFAR-10 (50,000 train / 10,000 test images, normalized to [0,1]).

What was hard. I first trained on 1% of the training set for 277 epochs and the model overfitted, with test performance notably worse than training. When I switched to the full dataset the opposite problem appeared: the discriminator became too good (its loss averaged around 1.2 against roughly 9 for the generator), leaving the generator little room to improve. The report proposes noise injection to slow the discriminator and data augmentation as next steps.

Outcome. On the test set the generated colorizations were visually plausible, with structure and details preserved. We evaluated results visually; no quantitative image-quality metric was computed, only loss values.

Links. Project report (PDF, Google Drive) · Kaggle notebook

Stack
#

PyTorch, conditional GAN (U-Net generator, CNN discriminator), CIELAB color conversion, CIFAR-10, Kaggle.