Instructions to use adarshcod30/openforensics-ensemble with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Keras
How to use adarshcod30/openforensics-ensemble with Keras:
# Available backend options are: "jax", "torch", "tensorflow". import os os.environ["KERAS_BACKEND"] = "jax" import keras model = keras.saving.load_model("hf://adarshcod30/openforensics-ensemble") - Notebooks
- Google Colab
- Kaggle
| license: mit | |
| tags: [deepfake-detection, image-classification, forensics, tensorflow, keras] | |
| library_name: keras | |
| pipeline_tag: image-classification | |
| # 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. | |
| ```python | |
| 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](https://github.com/adarshcod30/OpenForensics), 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. | |