Download scripts/eval_split_real_fake.py from ManhQuangAI/dinov3-deepfake-detection: direct link, hf CLI and curl.
- Browser
- Download file 4.23 kB
-
https://huggingface.co/ManhQuangAI/dinov3-deepfake-detection/resolve/main/scripts/eval_split_real_fake.py
- Command line
-
hf download hf://ManhQuangAI/dinov3-deepfake-detection/scripts/eval_split_real_fake.py
-
curl -L -o eval_split_real_fake.py https://huggingface.co/ManhQuangAI/dinov3-deepfake-detection/resolve/main/scripts/eval_split_real_fake.py
4.23 kB
| """Test riêng trên FAKE rồi trên REAL (frozen backbone + LR probe), tái dùng cache. | |
| Đọc feature memmap đã extract (outputs/features/{tag}_{model}.mmap) — không extract lại. | |
| Fit LR probe trên train (như eval_df40_all_methods), rồi đo 2 phần test riêng biệt: | |
| - FAKE-only (label=1): detection accuracy, precision, recall, F1, per-method | |
| - REAL-only (label=0): real recognition (true-negative rate) + FPR | |
| Chạy: | |
| .venv/bin/python scripts/eval_split_real_fake.py --model vit --tag test_data | |
| .venv/bin/python scripts/eval_split_real_fake.py --model cnn --tag test_data | |
| """ | |
| import argparse | |
| import json | |
| import os | |
| import numpy as np | |
| from sklearn.linear_model import LogisticRegression | |
| from sklearn.metrics import (accuracy_score, precision_score, recall_score, | |
| f1_score, roc_auc_score) | |
| from sklearn.pipeline import make_pipeline | |
| from sklearn.preprocessing import StandardScaler | |
| FEAT_DIM = {"vit": 384, "cnn": 768} | |
| CACHE_DIR = "outputs/features" | |
| def load(tag, key, suffix): | |
| mm = os.path.join(CACHE_DIR, f"{tag}_{key}{suffix}.mmap") | |
| meta = np.load(mm + ".meta.npz") | |
| X = np.memmap(mm, dtype=np.float32, mode="r", shape=(meta["labels"].shape[0], | |
| FEAT_DIM[key])) | |
| return X, meta["labels"], meta["methods"] | |
| def main(): | |
| ap = argparse.ArgumentParser() | |
| ap.add_argument("--model", required=True, choices=["vit", "cnn"]) | |
| ap.add_argument("--tag", default="test_data") | |
| ap.add_argument("--output", default=None) | |
| args = ap.parse_args() | |
| X_tr, y_tr, _ = load(args.tag, args.model, "") | |
| X_te, y_te, m_te = load(args.tag, args.model, "_test") | |
| print(f"Cache {args.model}: train {len(y_tr):,} ({y_tr.sum():,} fake) | " | |
| f"test {len(y_te):,} ({int((y_te==1).sum()):,} fake, {int((y_te==0).sum()):,} real)") | |
| clf = make_pipeline(StandardScaler(), | |
| LogisticRegression(class_weight="balanced", max_iter=2000, | |
| random_state=42)) | |
| clf.fit(X_tr, y_tr) | |
| y_pred = clf.predict(X_te) | |
| y_prob = clf.predict_proba(X_te)[:, 1] | |
| out = {"model": args.model, "tag": args.tag} | |
| # ---- FAKE only ---- | |
| mf = y_te == 1 | |
| yf, pf = y_te[mf], y_pred[mf] | |
| fake_metrics = { | |
| "n": int(mf.sum()), | |
| "accuracy": float(accuracy_score(yf, pf)), # = detection rate | |
| "precision": float(precision_score(yf, pf, zero_division=0)), | |
| "recall": float(recall_score(yf, pf, zero_division=0)), | |
| "f1": float(f1_score(yf, pf, zero_division=0)), | |
| } | |
| # per-method detection (chỉ trên fake test) | |
| per_m = {} | |
| for m in sorted(set(m_te[mf])): | |
| mask = m_te[mf] == m | |
| per_m[m] = {"n": int(mask.sum()), | |
| "detection_rate": float((pf[mask] == 1).mean())} | |
| fake_metrics["per_method"] = per_m | |
| out["fake"] = fake_metrics | |
| # ---- REAL only ---- | |
| mr = y_te == 0 | |
| yr, pr = y_te[mr], y_pred[mr] | |
| real_metrics = { | |
| "n": int(mr.sum()), | |
| "real_accuracy": float(accuracy_score(yr, pr)), # = true-negative rate | |
| "fpr": float((pr == 1).mean()), # false positive rate | |
| } | |
| out["real"] = real_metrics | |
| out["overall_auc"] = float(roc_auc_score(y_te, y_prob)) # toàn bộ test (2 class) | |
| # ---- in ---- | |
| print(f"\n=== {args.model.upper()} — FAKE-ONLY ({fake_metrics['n']:,} ảnh) ===") | |
| print(f" Detection Acc={fake_metrics['accuracy']:.4f} Prec={fake_metrics['precision']:.4f} " | |
| f"Rec={fake_metrics['recall']:.4f} F1={fake_metrics['f1']:.4f}") | |
| print(f" {'method':12s}{'n':>6s}{'det':>8s}") | |
| for m, v in sorted(per_m.items()): | |
| print(f" {m:12s}{v['n']:6d}{v['detection_rate']:8.3f}") | |
| print(f"\n=== {args.model.upper()} — REAL-ONLY ({real_metrics['n']:,} ảnh) ===") | |
| print(f" Real acc (đúng real)={real_metrics['real_accuracy']:.4f} " | |
| f"FPR={real_metrics['fpr']:.4f} | Overall AUC={out['overall_auc']:.4f}") | |
| if args.output: | |
| with open(args.output, "w") as f: | |
| json.dump(out, f, indent=2, ensure_ascii=False) | |
| print(f"\nSaved: {args.output}") | |
| if __name__ == "__main__": | |
| main() | |