| --- |
| title: CNN Autoencoder For Image Denoising |
| emoji: 😻 |
| colorFrom: purple |
| colorTo: pink |
| sdk: gradio |
| sdk_version: 6.5.1 |
| app_file: app.py |
| pinned: false |
| license: mit |
| short_description: U-Net based CNN autoencoder designed to denoise noisy image. |
| models: |
| - AIOmarRehan/CNN-DenoiseU-Net |
| datasets: |
| - AIOmarRehan/Cropped_Yale_Faces |
| --- |
| |
| Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference |
|
|
| --- |
| [If you would like a detailed explanation of this project, please refer to the Medium article below.](https://medium.com/@ai.omar.rehan/a-u-net-based-cnn-autoencoder-for-cleaning-noisy-images-before-classification-132e27b828e2) |
| --- |
|
|
| # A U-Net–Based CNN Autoencoder for Cleaning Noisy Images Before Classification |
|
|
| A practical walkthrough of how I built and trained a deep-learning model to denoise images and boost classification performance. |
|
|
| When I first started working with image-classification tasks, I noticed something that kept hurting my models: **noise**. Even small distortions—random dots, compression artifacts, sensor noise—were enough to confuse the classifier. |
|
|
| The obvious solution was to train on noisy data… but that never felt elegant. Instead, I wanted a **preprocessing model** whose sole job is to take a noisy image and return a clean version of it. The classifier would then work on much better input. |
|
|
| That idea led me to build a **U-Net–based CNN Autoencoder**. |
|
|
| This article walks you through: |
|
|
| * why I chose a U-Net structure |
| * how the autoencoder was built |
| * how noisy images were generated |
| * how the model was trained and evaluated |
| * what results I achieved |
|
|
| **Goal:** |
| *Use a smart deep-learning architecture to clean images before classification.* |
|
|
| --- |
|
|
| ## 1. Setting Up the Environment |
|
|
| I started by loading the usual deep-learning stack: |
|
|
| ```python |
| import tensorflow as tf |
| from tensorflow.keras.layers import * |
| from tensorflow.keras.models import Model |
| import numpy as np |
| import matplotlib.pyplot as plt |
| ``` |
|
|
| This is the typical setup for building custom architectures using Keras. |
|
|
| --- |
|
|
| ## 2. Why a U-Net Autoencoder? |
|
|
| A normal autoencoder compresses an image into a bottleneck and then reconstructs it. It works—but often loses details. |
|
|
| A **U-Net**, however, uses **skip connections**, meaning it: |
|
|
| * compresses the image (downsampling) |
| * learns a compact representation |
| * reconstructs it (upsampling) |
| * *also* reconnects high-resolution features from earlier layers |
|
|
| This makes U-Net excellent for: |
|
|
| * denoising |
| * segmentation |
| * super-resolution |
| * restoration tasks |
|
|
| So instead of a plain autoencoder, I built one using a U-shaped architecture. |
|
|
| --- |
|
|
| ## 3. Building the U-Net Autoencoder |
|
|
| ### Encoder |
|
|
| ```python |
| c1 = Conv2D(64, 3, activation='relu', padding='same')(inputs) |
| p1 = MaxPooling2D((2, 2))(c1) |
| |
| c2 = Conv2D(128, 3, activation='relu', padding='same')(p1) |
| p2 = MaxPooling2D((2, 2))(c2) |
| ``` |
|
|
| ### Bottleneck |
|
|
| ```python |
| bn = Conv2D(256, 3, activation='relu', padding='same')(p2) |
| ``` |
|
|
| ### Decoder |
|
|
| ```python |
| u1 = UpSampling2D((2, 2))(bn) |
| m1 = concatenate([u1, c2]) |
| c3 = Conv2D(128, 3, activation='relu', padding='same')(m1) |
| |
| u2 = UpSampling2D((2, 2))(c3) |
| m2 = concatenate([u2, c1]) |
| c4 = Conv2D(64, 3, activation='relu', padding='same')(m2) |
| ``` |
|
|
| ### Output |
|
|
| ```python |
| outputs = Conv2D(1, 3, activation='sigmoid', padding='same')(c4) |
| ``` |
|
|
| Even though the full architecture is larger, the core idea is: |
|
|
| **down → compress → up → reconnect → reconstruct** |
|
|
| --- |
|
|
| ## 4. Generating & Preprocessing Noisy Images |
|
|
| Instead of downloading a noisy dataset, I artificially added **Gaussian noise** to MNIST digits: |
|
|
| ```python |
| noise_factor = 0.4 |
| x_train_noisy = x_train + noise_factor * np.random.normal( |
| loc=0.0, scale=1.0, size=x_train.shape |
| ) |
| ``` |
|
|
| This created image pairs: |
|
|
| * clean MNIST digit |
| * noisy version of the same digit |
|
|
| Perfect for training an autoencoder. |
|
|
| --- |
|
|
| ## 5. Training the Model |
|
|
| Compile: |
|
|
| ```python |
| model.compile(optimizer='adam', loss='binary_crossentropy') |
| ``` |
|
|
| Train: |
|
|
| ```python |
| model.fit( |
| x_train_noisy, x_train, |
| epochs=10, |
| batch_size=128, |
| validation_split=0.1 |
| ) |
| ``` |
|
|
| The autoencoder learns one simple rule: |
|
|
| **Input:** noisy image |
| **Output:** clean image |
|
|
| --- |
|
|
| ## 6. Visualizing the Results |
|
|
| After training, I checked: |
|
|
| * noisy input |
| * autoencoder output |
| * original clean image |
|
|
| The model consistently removed a large amount of noise, smoothing textures while preserving structure. Not perfect—but for MNIST and a lightweight U-Net, the results were very encouraging. |
|
|
| --- |
|
|
| ## 7. Why This Helps Classification |
|
|
| If you already have (or plan to build) a classifier—CNN, ResNet, etc.—you can use a pipeline like: |
|
|
| ``` |
| Noisy Image → Autoencoder (denoising) → Classifier → Prediction |
| ``` |
|
|
| This helps with real-world noise sources like: |
|
|
| * camera noise |
| * poor lighting |
| * compression artifacts |
| * motion blur |
|
|
| **Clean input → better predictions.** |
|
|
| --- |
|
|
| ## 8. Key Takeaways |
|
|
| - **U-Net skip connections** help preserve important features. |
| - **Autoencoders** serve as powerful preprocessing tools. |
| - **Denoised images** can significantly improve classification accuracy. |
| - The **model is lightweight** and easy to integrate. |
| - The approach **scales to any image dataset**. |
|
|
|
|
| This approach is not just theoretical—it’s extremely practical. |
| Any project involving real-world noisy data can benefit from this denoising layer. |
|
|
| --- |
|
|
| ## 9. Results |
|
|
| [Watch Demo Video](Results/A_U-Net_Autoencoder.mp4) |