Downloads · 30 days
0
husseinelsaadi/aidetect-vit-b16
aidetect-vit-b16 is a image classification model from husseinelsaadi. Use it when you need a label for an image. It is set up for pytorch. The card lists the license as cc-by-nc-4.0.
Binary classifier: real photograph vs AI-generated image. Fine-tuned from the openai/clip-vit-base-patch16 vision tower on ~195,000 images spanning 1,100+ distinct generators, and — the part that usually goes unreport…
Downloads · 30 days
0
Access
Public
Updated Aug 17, 2026
Repo size
54.8 GB
Likes
1
Public
Click a slice to open those files.
.pt4 GB · 100%
From the Hugging Face model README
Binary classifier: real photograph vs AI-generated image. Fine-tuned from the
openai/clip-vit-base-patch16 vision tower on ~195,000 images spanning 1,100+
distinct generators, and — the part that usually goes unreported — measured on
generators it never saw during training.
Published AI-image detectors routinely report 99% and then collapse on anything their training generator did not produce. Wang et al. (2020) documented it; Bird & Lotfi (2024) hit 92.98% on CIFAKE using a single generator and named that as their central limitation. This model is an attempt to answer the question their limitation raises: how far does accuracy actually fall on generators nobody trained against?
The answer here is 97.6% → ~89.8%, and the failures are not where intuition says.
| Evaluation set | What it measures | Accuracy | AUROC |
|---|---|---|---|
| Held-out validation | seen generators | 0.976 | 0.997 |
OpenFake core/test | unseen generators + unseen real sources | 0.898 | 0.960 |
OpenFake reddit/test | in-the-wild Reddit uploads | 0.869 | 0.939 |
| CIFAKE | Bird & Lotfi (2024) benchmark, 32×32 | 0.720 | 0.815 |
Two notes on reading this table honestly:
reddit/test is 83% fake, so read its AUROC rather than its accuracy — a model
that simply answers "always AI" scores 82.6% on it.A ResNet-50 trained on the identical data (2 epochs, fixed budget) reaches 0.945 in-distribution but only 0.813 / AUROC 0.896 on unseen generators. The gap between the two architectures triples once the generator is unfamiliar — which is the argument for CLIP initialisation, arriving as a measurement rather than a claim. Two caveats, so the comparison is read for what it is: the ResNet had 2 epochs against the ViT's 5, and it ran under CLIP normalisation rather than ImageNet normalisation, since the pipeline is shared across every model. Both mildly handicap it — though neither explains why the AUROC gap is far wider out of distribution (6.4 points) than in it (0.8).
Unseen generators are mostly caught. On core/test: gpt-image-1.5 0.962,
z-image-turbo 0.952, flux.2-klein-9b 0.905 — none of them in training. Transfer is not
uniform: midjourney-7 (0.856) and recraft-v3 (0.600) are the weak points. The residual
error is dominated by the other direction: genuine photographs from unfamiliar camera
pipelines (DOCCI, ImageNet) being called AI. Full-range resolution augmentation cut that
false-positive rate from 27.3% to 17.5%, and refitting the decision threshold on
out-of-distribution data (0.38 → 0.71) took it to 9.5%.
Each run changes exactly one thing, so any difference between them is attributable.
runC is the model served by the demo and the one these numbers describe.
| Folder | Training recipe | Unseen-generator accuracy |
|---|---|---|
runA/ | baseline augmentation (crop + flip) | 0.842 |
runB/ | + JPEG q30–100, blur, mild rescale | 0.856 |
runC/ | + full-range resolution collapse — shipped | 0.881 |
runD/ | runC + simulated smartphone pipeline | 0.864 — did not help |
runD is kept because a negative result is still a result: adding a simulated phone
camera pipeline made the detector worse at catching fakes and worse at leaving real
photographs alone. Each folder holds checkpoints/best.pt, checkpoints/last.pt and a
summary.json with the full training history and calibration.
import torch, json
from huggingface_hub import hf_hub_download
from PIL import Image
# preprocessing must match training exactly — see the code repo's preprocess.py
ckpt = hf_hub_download("husseinelsaadi/aidetect-vit-b16", "runC/checkpoints/best.pt")
blob = torch.load(ckpt, map_location="cpu", weights_only=False)
# blob["model"] -> state dict
# blob["extra"]["config"] -> the training configuration
The complete, runnable inference path — canonical preprocessing, whole-frame tiling,
temperature scaling and the tuned threshold — is the
Space's app.py.
Copy it rather than reimplementing: a preprocessing mismatch silently costs several
points of accuracy.
Decision rule. Apply temperature scaling (summary.json → temperature), then
threshold at the published operating point rather than 0.5. The threshold was fitted on
held-out out-of-distribution data, because on a live demo the expensive mistake is
accusing a real photograph, not missing one synthetic image.
| Backbone | openai/clip-vit-base-patch16 vision tower, last 4 blocks + head trainable (~28M params) |
| Data | ~195k images, 50/50 real/fake, 1,115 generators, capped per generator |
| Preprocessing | short side → 320 (LANCZOS), centre crop 256, JPEG q95 re-encode for both classes |
| Augmentation | RandomResizedCrop(224, 0.6–1.0), flip, JPEG q30–100, blur σ0–3, full-range down/upscale |
| Optimiser | AdamW, wd 0.05, head LR 1e-3, backbone 1e-5, layer-wise decay 0.75, 5% warmup → cosine |
| Precision / hardware | bf16 on one NVIDIA L4 |
| Loss | BCEWithLogitsLoss (label smoothing was specified in the plan but never implemented) |
In the source data, fakes are PNGs straight from the generator and reals are JPEGs from photo datasets. Handed that raw, a model scores ~99% by learning "PNG means fake" and has learned nothing about AI. Every image of both classes therefore passes through one re-encoding function with no branch on the label.
The check that this worked: training the same configuration on randomly permuted labels gives 0.511 accuracy — chance. The classes are not separable by format, resolution or compression, so the reported numbers reflect generated-image structure rather than a pipeline artifact.
@misc{elsaadi2026aidetect,
author = {El Saadi, Hussein},
title = {AI Image Detector: CLIP-ViT-B/16 trained across 1,100+ generators},
year = {2026},
note = {CSC625 Deep Learning, Modern University for Business and Science (MUBS)},
url = {https://huggingface.co/husseinelsaadi/aidetect-vit-b16}
}
CSC625 Deep Learning · Hussein El Saadi · Modern University for Business and Science (MUBS) · Summer 2026.