AI-vs-Real Image Detector
A binary image classifier that predicts whether an image is AI-generated or a real photograph, built on an EfficientNet-B0 backbone fine-tuned with PyTorch.
Model Details
- Architecture: EfficientNet-B0 (ImageNet-pretrained backbone), with the last 3 feature blocks fine-tuned and a custom classification head (
Dropout(0.4)+Linear) - Classes:
ai_generated(0),real(1) - Input size: 224×224 RGB
- Normalization: ImageNet mean/std (
[0.485, 0.456, 0.406]/[0.229, 0.224, 0.225]) - Framework: PyTorch
Training Data
Trained on Parveshiiii/AI-vs-Real (13,999 images: ~24% AI-generated, ~76% real), split 70/15/15 into train/val/test with stratification. Class imbalance was handled with a WeightedRandomSampler during training.
Evaluation Results (test set, calibrated threshold = 0.43)
| Metric | Value |
|---|---|
| Accuracy | 99.05% |
| F1 | 0.9937 |
| AUC | 0.9983 |
⚠️ Important Caveat
The near-perfect test metrics above should be read with caution. In this dataset, AI-generated and real images cluster at noticeably different resolutions (e.g. AI images concentrated around 1024×1024, real images spanning a wide range down to 178×218). A model can achieve high accuracy by picking up on resolution or compression artifacts correlated with the source, rather than learning genuine visual signatures of AI generation.
In practical testing on out-of-distribution images (photos and AI images not from this dataset), real-world performance may be noticeably lower than these benchmark numbers suggest. Treat this model as a research/demo tool, not a production-grade forensic detector.
Usage
import torch
import torch.nn as nn
import torch.nn.functional as F
from torchvision import models, transforms
from PIL import Image
from huggingface_hub import hf_hub_download
checkpoint_path = hf_hub_download(
repo_id="bsgcasa/ai-vs-real-image-detector",
filename="checkpoint_full.pth"
)
checkpoint = torch.load(checkpoint_path, map_location="cpu", weights_only=False)
class_names = checkpoint["class_names"]
threshold = float(checkpoint["threshold"])
img_size = checkpoint["img_size"]
model = models.efficientnet_b0(weights=None)
in_features = model.classifier[1].in_features
model.classifier = nn.Sequential(nn.Dropout(0.4), nn.Linear(in_features, len(class_names)))
model.load_state_dict(checkpoint["model_state_dict"])
model.eval()
transform = transforms.Compose([
transforms.Resize((img_size, img_size)),
transforms.ToTensor(),
transforms.Normalize(checkpoint["normalize_mean"], checkpoint["normalize_std"]),
])
image = Image.open("your_image.jpg").convert("RGB")
x = transform(image).unsqueeze(0)
with torch.no_grad():
probs = F.softmax(model(x), dim=1)[0]
real_prob = probs[1].item()
prediction = class_names[1] if real_prob >= threshold else class_names[0]
print(prediction, real_prob)
Intended Use
Educational and research purposes — exploring AI-generated image detection approaches. Not intended as a sole or authoritative source for content moderation, journalism verification, or other high-stakes decisions.
License
Apache 2.0