OpenForensics Deepfake Detector (v2)

A multi-backbone CNN ensemble that classifies face crops as Real or Fake. Backbones: resnet50, vgg16, efficientnetv2b0. Their pooled embeddings are concatenated and read by a shared classifier head.

Output

A single sigmoid: P(Real). Fake is 1 - p.

Decision threshold 0.362 and temperature 0.876 were fitted on a held-out validation split (target_recall criterion) and are carried in serving.json.

Test metrics

Metric Value
Accuracy 0.9480
ROC-AUC 0.9899
PR-AUC 0.9900
Real images called fake 25 (2.5%)

Measured on a held-out test split with horizontal-flip test-time augmentation. The split is content-hash deduplicated against train and validation, so no image appears in more than one split.

Input

Resize to 224x224, scale to [0, 1], shape (N, 224, 224, 3) float32. Per-backbone normalisation happens inside the model โ€” do not apply preprocess_input yourself.

from huggingface_hub import snapshot_download
import tensorflow as tf, numpy as np, json
from PIL import Image

path = snapshot_download("adarshcod30/openforensics-ensemble")
model = tf.keras.models.load_model(f"{path}/model.keras", compile=False)
card = json.load(open(f"{path}/serving.json"))

img = Image.open("face.jpg").convert("RGB").resize((224, 224))
x = np.asarray(img, dtype="float32")[None] / 255.0
p = float(model.predict(x)[0, 0])
print("Real" if p >= card["decision"]["threshold"] else "Fake", p)

Loading needs the PreprocessLayer custom layer from the repo, or pass it via custom_objects.

Training data

The face-cropped OpenForensics distribution (190,334 images at 256x256). Training used corruption-matched augmentation โ€” desaturation, colour cast, noise, speckle, blur, JPEG artefacts, pixelation, brightness shift and occlusion โ€” because the test split is measurably more degraded than train.

Robustness

Accuracy with a single degradation family applied to the whole test set, one at a time.

Degradation Accuracy ROC-AUC vs clean
clean 0.9405 0.9899 โ€”
desaturate 0.9255 0.9874 -0.0150
colour_cast 0.9230 0.9873 -0.0175
gaussian_noise 0.9105 0.9827 -0.0300
speckle 0.8745 0.9786 -0.0660
blur 0.9025 0.9798 -0.0380
jpeg_artifact 0.9260 0.9854 -0.0145
pixelate 0.8725 0.9623 -0.0680
brightness_shift 0.9210 0.9865 -0.0195
occlusion 0.9300 0.9856 -0.0105

Limitations

  • Trained on face crops. Behaviour on full scenes or non-face images is undefined.
  • A score near the threshold is not evidence. Treat the margin as part of the output.
  • Performance degrades on manipulation methods absent from OpenForensics.
  • Research and educational use. Not a forensic authority.
  • Validation tracks test closely. Recall on genuine images at threshold 0.5 is 0.986 on validation and 0.961 on test โ€” a gap of 0.025. The 10th percentile of scores on genuine images is 0.977 and 0.830 respectively, so the operating point fitted on validation transfers. This is a property of the corruption-matched augmentation, not of the benchmark.

Citation

Trung-Nghia Le, Huy H. Nguyen, Junichi Yamagishi, Isao Echizen, "OpenForensics: Large-Scale Challenging Dataset For Multi-Face Forgery Detection And Segmentation In-The-Wild", ICCV 2021.

Downloads last month
77
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support