ResNet-34 Signature Verification System

PyTorch GCP License: MIT

This repository hosts a fine-tuned ResNet-34 model designed for high-precision signature authentication. It distinguishes between Genuine (Original) and Forged signatures by analyzing stroke patterns, pressure points, and curvature nuances.


πŸ“Œ Project Highlights

  • Accuracy: Achieved near-zero test loss (<0.0001) after 10 epochs.
  • Architecture: ResNet-34 backbone with a custom dropout-enhanced classification head.
  • Framework: Built entirely with PyTorch and Torchvision.
  • Dataset: Trained on the benchmark CEDAR Signature Dataset.

βš™οΈ Model Architecture

The model utilizes Transfer Learning from the ImageNet-pretrained ResNet-34 weights. The final fully connected layer was replaced to accommodate binary classification:

# Custom Head Implementation
model.fc = nn.Sequential(
    nn.Dropout(0.1),
    nn.Linear(512, 2)  # Mapping features to ['Forged', 'Original']
)

πŸ› οΈ How It Works (The Pipeline)

This project is built as a modular MLOps pipeline. Here is the step-by-step logic:

  1. Data Ingestion: Images are pulled from Google Cloud Storage (GCS) buckets into the local environment.

  2. Data Transformation:

    • Resizing: All signatures are standardized to 224 x 224 pixels.
    • Augmentation: Random rotations (Β±20Β°) are applied to make the model robust to different signing angles.
    • Normalization: Applied using ImageNet stats ($mean=[0.485, 0.456, 0.406]$) to ensure stable training.
  3. Model Training:

    • Uses a 60/30/10 split (Train/Val/Test).
    • Optimized using SGD Momentum (0.9) and a learning rate of $1e^{-3}$.
    • The model learns to identify micro-features like stroke pressure and curvature.
  4. Evaluation: Performance is tracked via TensorBoard, monitoring the convergence of Training and Validation loss.

  5. Model Pushing: Once peak accuracy is reached, the final model.pt artifact is pushed to the cloud for production readiness.


πŸš€ How to Use (Inference Script)

Since the model was saved as a complete serialized object, you can load it and run inference in just a few lines:

import torch
from torchvision import transforms
from PIL import Image

# 1. Setup Device
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# 2. Load the entire model object
# Ensure the 'model.pt' file is in your working directory
model = torch.load("model.pt", map_location=device)
model.eval()

# 3. Define Prediction Function
def predict(image_path):
    img = Image.open(image_path).convert('RGB')

    # Matches the transformation pipeline used during training
    transform = transforms.Compose([
        transforms.Resize((224, 224)),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ])

    img_tensor = transform(img).unsqueeze(0).to(device)

    with torch.no_grad():
        output = model(img_tensor)
        probs = torch.softmax(output, dim=1)
        prediction = torch.argmax(probs, dim=1).item()

    labels = ['Forged', 'Original']
    return labels[prediction]

# Example run:
# print(f"Verdict: {predict('test_signature.png')}")
Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support