--- license: unlicense tags: - image-to-image - super-resolution - image-denoising - pytorch - pytorch-lightning - esrgan - rrdbnet library_name: pytorch pipeline_tag: image-to-image --- # RRDBNet — Low-Light Denoising + 4x Super-Resolution (DLP 26T2 NPPE3) An RRDBNet (ESRGAN/Real-ESRGAN generator family) checkpoint trained end-to-end to jointly **denoise low-light images and upscale them 4x**, as part of the DLP 26T2 NPPE3 course competition (scored by PSNR). ## Model description - **Architecture:** RRDBNet — a stack of Residual-in-Residual Dense Blocks (RRDB) followed by 2 pixel-shuffle upsampling stages (2x each, for a total of 4x). - **Config:** `nf=64` feature channels, `nb=23` RRDB blocks, `gc=32` growth channels per dense block, `scale=4`. - **Input / output:** RGB image in `[0, 1]` → RGB image in `[0, 1]`, upscaled 4x in each spatial dimension. Fully convolutional — accepts any input resolution. - **Loss:** Charbonnier loss (a smooth, robust L1 variant), chosen over plain L1/MSE since it tolerates residual sensor noise in the targets better. - **Framework:** implemented from scratch in PyTorch (no `basicsr` dependency), trained with a PyTorch Lightning training loop (Adam optimizer, cosine LR schedule, mixed precision, best-checkpoint selection by validation PSNR). ## Intended uses & limitations - Intended for restoring low-light, noisy images from the DLP 26T2 NPPE3 dataset distribution (LR ≈ 256×160 → HR ≈ 1024×640) and similar low-light noisy photos. - Trained for a PSNR-oriented objective only — no adversarial/perceptual loss was used, so outputs prioritize pixel-accurate reconstruction over perceptual sharpness (edges may look slightly soft compared to GAN-based SR models). - Not evaluated on natural images far outside the training distribution (e.g. well-lit photos, non-photographic content, extreme upscale factors). ## Training data Paired low-resolution/noisy and high-resolution/clean images from the DLP 26T2 NPPE3 competition dataset (`train/low` + `train/gt`, validated against `val/low` + `val/gt`). Training used random 128×128 LR patches (512×512 HR) with random flip/rotation augmentation. ## How to use ```python import torch from rrdbnet import RRDBNet # your model definition module model = RRDBNet(scale=4, nf=64, nb=23, gc=32) # Checkpoint is a PyTorch Lightning .ckpt — state dict keys are prefixed with "model." ckpt = torch.load("best.ckpt", map_location="cpu") state_dict = {k.removeprefix("model."): v for k, v in ckpt["state_dict"].items()} model.load_state_dict(state_dict) model.eval() # inference from PIL import Image import torchvision.transforms.functional as TF lr_img = Image.open("input.png").convert("RGB") lr_tensor = TF.to_tensor(lr_img).unsqueeze(0) with torch.no_grad(): hr_tensor = model(lr_tensor) hr_img = TF.to_pil_image(hr_tensor.squeeze(0).clamp(0, 1)) hr_img.save("output.png") ``` ## Evaluation Validated by PSNR (dB) on the held-out `val` split of the DLP 26T2 NPPE3 dataset during training; best checkpoint selected by peak validation PSNR. ## Limitations - No GAN/perceptual fine-tuning stage — if perceptual sharpness matters more than PSNR for your use case, consider fine-tuning further with an adversarial loss. - Performance on inputs with noise characteristics or lighting conditions very different from the training set is untested. ## Citation If you use this checkpoint, please cite the RRDBNet/ESRGAN architecture it's based on: ``` Wang, X., et al. "ESRGAN: Enhanced Super-Resolution Generative Adversarial Networks." ECCV Workshops, 2018. ```