Skip to content

mtkl6/cat-dog-classifier

Repository files navigation

Cat vs Dog Classifier 🐱🐶

License: MIT Python 3.9+ PyTorch Model on HF

A ResNet50 transfer-learning image classifier that tells cats from dogs at ~94% validation accuracy (AUC 0.98) — trained in two stages on the Oxford-IIIT Pet dataset, with Grad-CAM heatmaps to show where the model is looking.

It also ships as a complete, beginner-friendly tutorial: a ~40-page guide (guide.pdf) walks you through building the whole thing from scratch, from PyTorch basics to two-stage fine-tuning. See Learn by building.

Grad-CAM in action

Each prediction comes with a heatmap highlighting the pixels that drove the decision — red = "this is why I said dog/cat":

Input Grad-CAM Input Grad-CAM

Results

Stage What trains Val accuracy Precision Recall AUC
1 — frozen backbone new head only 86.3% 0.92 0.96 0.93
2 — fine-tune layer4 head + deepest block 94.2% 0.96 0.97 0.98

Oxford-IIIT Pet, ResNet50 (ImageNet1K), 10 + 10 epochs, ~5,900 train / ~1,500 val.

Quickstart

Requires Python ≥ 3.9 and PyTorch. MPS (Apple Silicon), CUDA, and CPU are all supported automatically.

git clone https://github.com/mtkl6/cat-dog-classifier.git
cd cat-dog-classifier
python -m venv venv && source venv/bin/activate
pip install -r requirements.txt

Predict on your own images (with Grad-CAM)

Download the trained weights from the Hugging Face model page:

pip install huggingface_hub
python -c "from huggingface_hub import hf_hub_download as d; \
  d('mtkl6/cat-dog-classifier','cat_dog_classifier.pt',local_dir='.')"

python test.py path/to/your/image.jpg     # or: python test.py   (uses pic/)

This prints each prediction with a confidence score and writes a heatmap overlay to gradcam/.

Train it yourself

python train.py          # downloads the dataset on first run, trains both stages
tensorboard --logdir runs   # watch the curves (see TENSORBOARD.md)

Two checkpoints are written — best_model_stage1.pt, best_model_stage2.pt — plus the final cat_dog_classifier.pt.

How it works

Transfer learning reuses a ResNet50 already trained on ImageNet and adapts it to cats-vs-dogs instead of learning from zero:

  1. Stage 1 — frozen backbone. Freeze all of ResNet50, replace its 1000-class head with Dropout(0.4) → Linear(2048, 1), and train only that head (lr 1e-3). Fast, and it can't damage the pretrained features.
  2. Stage 2 — gentle fine-tune. Unfreeze just the deepest block (layer4) and nudge it with a tiny lr 1e-5 so task-specific features adapt without forgetting the generic ones.

The head outputs a single logit; sigmoid(logit) > 0.5 means dog (cats are 0, dogs are 1). Training uses BCEWithLogitsLoss, the Adam optimizer, ReduceLROnPlateau, data augmentation (flip / rotate / crop / color jitter), early stopping, and logs loss/accuracy/precision/recall/AUC to TensorBoard.

Load the model in code

The checkpoint is a raw state_dict; rebuild the architecture, then load:

import torch, torch.nn as nn
from torchvision import models, transforms
from PIL import Image

model = models.resnet50()
model.fc = nn.Sequential(nn.Dropout(0.4), nn.Linear(2048, 1))
model.load_state_dict(torch.load("cat_dog_classifier.pt", weights_only=True))
model.eval()

tf = transforms.Compose([
    transforms.Resize((224, 224)), transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),
])
x = tf(Image.open("cat.jpg").convert("RGB")).unsqueeze(0)
p_dog = torch.sigmoid(model(x)).item()
print("dog" if p_dog > 0.5 else "cat", f"({max(p_dog, 1-p_dog):.1%})")

Learn by building

This repo started life as a teaching project, and the guide is still its heart. guide.pdf (source: guide.typ) is a 13-chapter, beginner-oriented walkthrough that has you write train.py yourself:

setup → the dataset → data pipeline → augmentation → neural-net basics → transfer learning → building the model → the training loop → stage 1 → stage 2 → evaluation → inference → resources

train.py is written as a readable, heavily-commented learner scaffold; solution/train.py is a complete reference implementation (using the lighter MobileNetV2) for comparison.

Project structure

train.py            two-stage transfer-learning trainer (ResNet50), TensorBoard logging
test.py             inference + Grad-CAM heatmap generation
solution/train.py   reference implementation (MobileNetV2 variant)
guide.pdf / .typ    the full beginner's guide (Typst source + rendered PDF)
pic/                sample input images
gradcam/            example Grad-CAM outputs
TENSORBOARD.md      how to view training curves
requirements.txt

Dataset & licensing

The code and guide are MIT-licensed (see LICENSE).

The model trains on the Oxford-IIIT Pet dataset (Parkhi et al., 2012), downloaded automatically by torchvision on first run and not redistributed here (data/ is gitignored). The dataset is provided for research/educational use under its own terms; please cite the original authors if you use it.

Citation

If you use this project, please cite it (see CITATION.cff):

@software{cat_dog_classifier_2026,
  author = {Moritz (mtkl6)},
  title  = {Cat vs Dog Classifier: a ResNet50 transfer-learning tutorial},
  year   = {2026},
  url    = {https://github.com/mtkl6/cat-dog-classifier}
}

Acknowledgements

  • Backbone: ResNet50 via torchvision.
  • Dataset: Oxford-IIIT Pet.
  • Grad-CAM: Selvaraju et al., Grad-CAM: Visual Explanations from Deep Networks (2017).

About

ResNet50 transfer-learning cat/dog classifier (~94% acc) with Grad-CAM — and a full beginner's guide to building it

Topics

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages