Skip to main content

Face-swap deepfake detection for KYC pipelines

Project description

Universidad EAFIT

deepfakes_hunter

Face-swap deepfake detection for KYC pipelines.

PyPI version Python License: MIT


What is deepfakes_hunter?

deepfakes_hunter is a Python package that exposes a single, ready-to-use class — DeepfakeDetector — for classifying face images as real or face-swapped (deepfake).

Under the hood it runs a ResNet-50 backbone fine-tuned for binary deepfake detection, exported to ONNX for fast, framework-agnostic inference. The model was trained on a curated dataset of 67 528 synthetic face-swaps generated with InSwapper → CodeFormer → Real-ESRGAN, paired with real faces from four public collections (CelebA, Flickr-Faces-HQ, UTKFace, VGGFace2) processed through a biometric-quality ETL.

Full methodology and training details → MODEL_CARD.md


Install

pip install deepfakes_hunter

The model weights are downloaded automatically on first use to ~/.deepfakes_hunter/deepfake_detector.onnx. No manual download required.


Quick start

from PIL import Image
from deepfakes_hunter import DeepfakeDetector

detector = DeepfakeDetector()          # downloads model on first run

img = Image.open("selfie.jpg")
result = detector.predict(img)

print(result)
# {'score': 0.0021, 'pred': 0, 'label': 'real', 'threshold': 0.98}

Predict on a real face vs a face-swap

from PIL import Image
from deepfakes_hunter import DeepfakeDetector

detector = DeepfakeDetector(threshold=0.98)

real_face  = Image.open("real.jpg")
fake_face  = Image.open("faceswap.jpg")

for img, name in [(real_face, "real"), (fake_face, "faceswap")]:
    r = detector.predict(img)
    print(f"{name:>10}  score={r['score']:.4f}  label={r['label']}")

# output:
#       real  score=0.0031  label=real
#   faceswap  score=0.9987  label=deepfake

Load your own model weights

detector = DeepfakeDetector(onnx_path="path/to/your_model.onnx", threshold=0.98)

GPU acceleration

detector = DeepfakeDetector(use_gpu=True)   # requires onnxruntime-gpu

API reference

DeepfakeDetector(onnx_path=None, threshold=0.98, use_gpu=False)

Parameter Type Default Description
onnx_path str | None None Path to a local .onnx file. If None, the model is downloaded automatically.
threshold float 0.98 Score ≥ threshold → predicted deepfake.
use_gpu bool False Use CUDAExecutionProvider (requires onnxruntime-gpu).

.predict(img_pillow, threshold=None) → dict

Key Type Description
score float Sigmoid probability of being a deepfake (0 → real, 1 → deepfake).
pred int 1 if deepfake, 0 if real.
label str "deepfake" or "real".
threshold float Threshold used for this prediction.

Pipeline overview

The model was trained through an end-to-end reproducible pipeline:

End-to-end pipeline

Stage What happens
1 — Data Four public face datasets; RetinaFace detection + 6DRepNet pose filtering (ISO/IEC 19794-5)
2 — Embeddings ArcFace 512-dim embeddings; P50 / P99 cosine-similarity pair selection
3 — Face swaps 67 528 swaps with InSwapper → CodeFormer → Real-ESRGAN
4 — Manual review FaceSwap Tagger web tool; 2 649 (8.27 %) artifacts discarded
5 — Splits Grouped by target_id; 99:1 real:fake imbalance in val / test
6 — Training ResNet-18 (baseline) and ResNet-50 (final) with identical fine-tuning policy

Performance (test set · 11 600 samples · 99:1 imbalance)

Model PR-AUC F1 Recall Precision
ResNet-50 (final) 0.9977 0.983 0.991 0.975
ResNet-18 (baseline) 0.9978 0.970 0.983 0.957

Evaluated at threshold = 0.98 (optimal on validation).


Dataset examples — real vs face-swap

Real faces (post-ETL)

Real face examples

Face-swaps (InSwapper → CodeFormer → Real-ESRGAN)

Face-swap examples


Repository structure

The src/ folder documents the full training pipeline as reproducible Jupyter notebooks:

src/
├── 01_data_preparation/
│   ├── 01_download_datasets.ipynb       ← download CelebA, Flickr, UTKFace, VGGFace2
│   ├── 02_etl_face_detection.ipynb      ← RetinaFace: detect, align, crop
│   ├── 03_etl_pose_filtering.ipynb      ← 6DRepNet: pose filter (ISO/IEC 19794-5)
│   └── 04_etl_demographics.ipynb        ← age & gender characterisation
│
├── 02_faceswap_generation/
│   ├── 01_arcface_embeddings.ipynb      ← extract ArcFace embeddings
│   ├── 02_pair_selection_p50_p99.ipynb  ← cosine-similarity P50/P99 pair selection
│   └── 03_inswapper_codeformer.ipynb   ← InSwapper → CodeFormer → Real-ESRGAN
│
├── 03_training/
│   ├── 01_dataset_assembly_splits.ipynb ← merge real+fake, build splits
│   ├── 02_train_resnet18.ipynb          ← ResNet-18 fine-tuning (baseline)
│   └── 03_train_resnet50.ipynb          ← ResNet-50 fine-tuning (final model)
│
├── 04_evaluation/
│   ├── 01_export_onnx.ipynb             ← export best checkpoint to ONNX
│   └── 02_test_inference.ipynb          ← threshold sweep, confusion matrix, PR curve
│
└── 05_interpretability/
    └── 01_gradcam_analysis.ipynb        ← Grad-CAM activation maps

Authors

Javier Javier Daza Olivella · jjdazao@eafit.edu.co

Advisor: Pablo Andrés Saldarriaga · psaldar2@eafit.edu.co

Universidad EAFIT · Escuela de Ciencias Aplicadas e Ingeniería Maestría en Ciencia de Datos y Analítica · Medellín, 2026


MIT License

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

deepfakes_hunter-1.0.0.tar.gz (5.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

deepfakes_hunter-1.0.0-py3-none-any.whl (5.7 kB view details)

Uploaded Python 3

File details

Details for the file deepfakes_hunter-1.0.0.tar.gz.

File metadata

  • Download URL: deepfakes_hunter-1.0.0.tar.gz
  • Upload date:
  • Size: 5.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.0

File hashes

Hashes for deepfakes_hunter-1.0.0.tar.gz
Algorithm Hash digest
SHA256 39068fc132016a8a5bbfdf4fcc69e755d89c9db6caf4058671824993ea62330f
MD5 3c108d0a7af2ab302b9fd35354fc447a
BLAKE2b-256 de75cbded7640db82e9b52a8e0c646c64163ebc8d6b21faf8e1ffe20e979fa93

See more details on using hashes here.

File details

Details for the file deepfakes_hunter-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for deepfakes_hunter-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8b0b08fb9d6c8b576f65d00e478878a4008bf1faa135bd7a3c8a47ac0225dab0
MD5 df5ef0c9f2f70be4c69152a1ebdb33d6
BLAKE2b-256 6e2dac7cf920e2c4e9eee906d49220a2931fc7553db1fd87b47193633491e401

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page