| # ResNet-18 Clean vs. Noisy Image Classification Model | |
| ## This repository hosts a fine-tuned ResNet-18 model designed to classify images as either Clean (high-quality) or Noisy (distorted). The model was trained on a custom dataset containing two classes: Clean and Noisy images. | |
| π Model Details | |
| - **Model Architecture:** ResNet-18 | |
| - **Task:** Binary Image Classification (Clean vs. Noisy) | |
| - **Dataset:** Custom dataset of Clean and Noisy images | |
| - **Framework:** PyTorch | |
| - **Input Image Size:** 224Γ224 | |
| - **Number of Classes:** 2 (Clean, Noisy) | |
| - **Quantization:** Dynamic quantization applied for efficiency | |
| ## π Usage | |
| ### Installation | |
| ```bash | |
| pip install torch torchvision pillow | |
| ``` | |
| # Loading the Model | |
| ```python | |
| import torch | |
| import torch.nn as nn | |
| from torchvision import models | |
| # Step 1: Define the model architecture (must match the trained model) | |
| model = models.resnet18(pretrained=False) | |
| num_features = model.fc.in_features | |
| model.fc = nn.Linear(num_features, 2) # 2 classes: Clean vs. Noisy | |
| # Step 2: Load the fine-tuned and quantized model weights | |
| model_path = "/path/to/resnet18_quantized.pth" # Update with your path | |
| model.load_state_dict(torch.load(model_path, map_location=torch.device("cpu"))) | |
| # Step 3: Set model to evaluation mode | |
| model.eval() | |
| print("β Model loaded successfully and ready for inference!") | |
| ``` | |
| ## πΌοΈ Performing Inference | |
| ```python | |
| from PIL import Image | |
| import torchvision.transforms as transforms | |
| # Define preprocessing (same as used during training) | |
| transform = transforms.Compose([ | |
| transforms.Resize((224, 224)), # Resize to match model input | |
| transforms.ToTensor(), | |
| transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) | |
| ]) | |
| # Load an image (external or new) | |
| image_path = "/path/to/your/image.jpg" # Replace with your test image path | |
| image = Image.open(image_path).convert("RGB") | |
| image = transform(image).unsqueeze(0) # Add batch dimension | |
| # Perform inference | |
| with torch.no_grad(): | |
| output = model(image) | |
| # Convert output to class prediction | |
| predicted_class = torch.argmax(output, dim=1).item() | |
| # Mapping: 0 => Clean, 1 => Noisy | |
| label_mapping = {0: "Clean", 1: "Noisy"} | |
| print(f"β Predicted Image Label: {label_mapping[predicted_class]}") | |
| ``` | |
| ## π Evaluation Results | |
| After fine-tuning on the custom dataset, the model achieved the following performance on a held-out validation set: | |
| | **Metric** | **Score** | | |
| |---------------------|---------------------------------------| | |
| | **Accuracy** | 95.2% | | |
| | **Precision** | 94.5% | | |
| | **Recall** | 93.7% | | |
| | **F1-Score** | 94.1% | | |
| | **Inference Speed** | Fast (Optimized via Quantization) | | |
| ## Inference Speed Fast (with quantization) | |
| π οΈ Fine-Tuning & Quantization Details | |
| ### Dataset Details | |
| - Dataset Composition: The training data consists of clean (high-quality) images and noisy (distorted) images. | |
| - Dataset Source: Custom/Kaggle dataset. | |
| - Training Configuration | |
| - Epochs: 5β20 (depending on your convergence criteria) | |
| - Batch Size: 16 or 32 | |
| - Optimizer: Adam | |
| - Learning Rate: 1e-4 | |
| - Loss Function: Cross-Entropy | |
| ## Quantization | |
| - Method: Dynamic quantization applied to fully connected layers | |
| - Precision: Lowered to 8-bit integers (qint8) for efficiency | |
| ## β οΈ Limitations | |
| - Domain Shift: The model may misclassify images if the external image quality or noise characteristics differ significantly from the training dataset. | |
| - Misclassification Risk: Similar patterns in clean and noisy images (e.g., subtle noise) might lead to incorrect classifications. | |
| - Generalization: Performance may degrade on images with unusual lighting, contrast, or other artifacts not seen during training. | |