Real vs Fake Image Classifier

Fine-tuned ResNet18 (ImageNet-pretrained) for binary classification: real vs fake.

Results

  • Train size: 202 | Valid size: 41
  • Best validation accuracy: 1.0000
  • Trained 15 epochs, ~2.7 min

Note: validation set is small (41 images), so treat the 100% val accuracy as an upper-bound sanity check rather than a guarantee of generalization to unseen data.

Files

  • best_model.pt โ€” state_dict with highest validation accuracy (this run: epoch with val_acc=1.0)
  • final_model.pt โ€” state_dict from the last training epoch
  • class_to_idx.json โ€” label mapping: {"fake": 0, "real": 1}
  • config.json โ€” training configuration
  • history.json โ€” per-epoch loss/accuracy
  • metrics.json โ€” summary metrics
  • training_curves.png โ€” loss/accuracy plots

Usage

!pip install -q huggingface_hub torch torchvision pillow

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

REPO_ID = "bsgcasa/deepfake-face-classifier"

# Download files from the Hub
model_path = hf_hub_download(repo_id=REPO_ID, filename="best_model.pt")
class_map_path = hf_hub_download(repo_id=REPO_ID, filename="class_to_idx.json")

with open(class_map_path) as f:
    class_to_idx = json.load(f)
idx_to_class = {v: k for k, v in class_to_idx.items()}

# Rebuild architecture and load weights
model = models.resnet18(weights=None)
model.fc = nn.Sequential(nn.Dropout(0.4), nn.Linear(model.fc.in_features, len(class_to_idx)))
model.load_state_dict(torch.load(model_path, map_location="cpu"))
model.eval()

# Preprocessing (must match validation transform used in training)
preprocess = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])

# Predict on an image
def predict(image_path):
    img = Image.open(image_path).convert("RGB")
    x = preprocess(img).unsqueeze(0)
    with torch.no_grad():
        outputs = model(x)
        probs = torch.softmax(outputs, dim=1)[0]
        pred_idx = probs.argmax().item()
    return idx_to_class[pred_idx], probs[pred_idx].item()

label, confidence = predict("path/to/your/image.jpg")
print(f"Prediction: {label} ({confidence*100:.2f}% confidence)")

Training details

  • Base model: ResNet18 pretrained on ImageNet
  • Fine-tuning strategy: backbone frozen up to layer3; layer3, layer4, and the classifier head are trainable
  • Classifier head: Dropout(0.4) โ†’ Linear(in_features, 2)
  • Optimizer: AdamW, lr=1e-4, weight_decay=1e-4
  • Scheduler: ReduceLROnPlateau (mode="max", factor=0.5, patience=2)
  • Augmentation: random horizontal flip, random rotation (ยฑ10ยฐ), color jitter
  • Image size: 224x224, ImageNet normalization
Downloads last month
348
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support