siddharthksah commited on
Commit
3680c22
·
1 Parent(s): e16e208

feat: add 5 new video detection services (DFD-FCG, PwTF-DVD, LipFD, RECCE, MINTIME)

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +13 -0
  2. video/dfd-fcg/Dockerfile +59 -0
  3. video/dfd-fcg/app.py +661 -0
  4. video/dfd-fcg/model_code/.gitignore +20 -0
  5. video/dfd-fcg/model_code/assets/demo.png +3 -0
  6. video/dfd-fcg/model_code/assets/teaser.png +3 -0
  7. video/dfd-fcg/model_code/configs/base.yaml +102 -0
  8. video/dfd-fcg/model_code/configs/clip/L14/evl.yaml +7 -0
  9. video/dfd-fcg/model_code/configs/clip/L14/ffg.yaml +15 -0
  10. video/dfd-fcg/model_code/configs/clip/L14/fulltune.yaml +6 -0
  11. video/dfd-fcg/model_code/configs/clip/L14/linear.yaml +6 -0
  12. video/dfd-fcg/model_code/configs/clip/L14/svl.yaml +12 -0
  13. video/dfd-fcg/model_code/configs/clip/L14/vpt.yaml +7 -0
  14. video/dfd-fcg/model_code/configs/data.yaml +54 -0
  15. video/dfd-fcg/model_code/configs/inference.yaml +39 -0
  16. video/dfd-fcg/model_code/configs/logger.yaml +14 -0
  17. video/dfd-fcg/model_code/configs/loo/DF.yaml +14 -0
  18. video/dfd-fcg/model_code/configs/loo/F2F.yaml +14 -0
  19. video/dfd-fcg/model_code/configs/loo/FS.yaml +14 -0
  20. video/dfd-fcg/model_code/configs/loo/NT.yaml +14 -0
  21. video/dfd-fcg/model_code/configs/robustness/BW(1).yaml +14 -0
  22. video/dfd-fcg/model_code/configs/robustness/BW(2).yaml +14 -0
  23. video/dfd-fcg/model_code/configs/robustness/BW(3).yaml +14 -0
  24. video/dfd-fcg/model_code/configs/robustness/BW(4).yaml +14 -0
  25. video/dfd-fcg/model_code/configs/robustness/BW(5).yaml +14 -0
  26. video/dfd-fcg/model_code/configs/robustness/CC(1).yaml +14 -0
  27. video/dfd-fcg/model_code/configs/robustness/CC(2).yaml +14 -0
  28. video/dfd-fcg/model_code/configs/robustness/CC(3).yaml +14 -0
  29. video/dfd-fcg/model_code/configs/robustness/CC(4).yaml +14 -0
  30. video/dfd-fcg/model_code/configs/robustness/CC(5).yaml +14 -0
  31. video/dfd-fcg/model_code/configs/robustness/CS(1).yaml +14 -0
  32. video/dfd-fcg/model_code/configs/robustness/CS(2).yaml +14 -0
  33. video/dfd-fcg/model_code/configs/robustness/CS(3).yaml +14 -0
  34. video/dfd-fcg/model_code/configs/robustness/CS(4).yaml +14 -0
  35. video/dfd-fcg/model_code/configs/robustness/CS(5).yaml +14 -0
  36. video/dfd-fcg/model_code/configs/robustness/GB(1).yaml +14 -0
  37. video/dfd-fcg/model_code/configs/robustness/GB(2).yaml +14 -0
  38. video/dfd-fcg/model_code/configs/robustness/GB(3).yaml +14 -0
  39. video/dfd-fcg/model_code/configs/robustness/GB(4).yaml +14 -0
  40. video/dfd-fcg/model_code/configs/robustness/GB(5).yaml +14 -0
  41. video/dfd-fcg/model_code/configs/robustness/GNC(1).yaml +14 -0
  42. video/dfd-fcg/model_code/configs/robustness/GNC(2).yaml +14 -0
  43. video/dfd-fcg/model_code/configs/robustness/GNC(3).yaml +14 -0
  44. video/dfd-fcg/model_code/configs/robustness/GNC(4).yaml +14 -0
  45. video/dfd-fcg/model_code/configs/robustness/GNC(5).yaml +14 -0
  46. video/dfd-fcg/model_code/configs/robustness/JPEG(1).yaml +14 -0
  47. video/dfd-fcg/model_code/configs/robustness/JPEG(2).yaml +14 -0
  48. video/dfd-fcg/model_code/configs/robustness/JPEG(3).yaml +14 -0
  49. video/dfd-fcg/model_code/configs/robustness/JPEG(4).yaml +14 -0
  50. video/dfd-fcg/model_code/configs/robustness/JPEG(5).yaml +14 -0
.gitattributes CHANGED
@@ -127,3 +127,16 @@ audio/shiftyspeech/speech_synthesis/vocoders/univnet/docs/samples/unseen/officia
127
  image/aide/model_code/docs/Chameleon.jpg filter=lfs diff=lfs merge=lfs -text
128
  image/aide/model_code/docs/network.png filter=lfs diff=lfs merge=lfs -text
129
  video/fake-stormer/model_code/demo/method.png filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
  image/aide/model_code/docs/Chameleon.jpg filter=lfs diff=lfs merge=lfs -text
128
  image/aide/model_code/docs/network.png filter=lfs diff=lfs merge=lfs -text
129
  video/fake-stormer/model_code/demo/method.png filter=lfs diff=lfs merge=lfs -text
130
+ *.csv filter=lfs diff=lfs merge=lfs -text
131
+ *.gif filter=lfs diff=lfs merge=lfs -text
132
+ *.mp4 filter=lfs diff=lfs merge=lfs -text
133
+ video/mintime/weights/** filter=lfs diff=lfs merge=lfs -text
134
+ *.png filter=lfs diff=lfs merge=lfs -text
135
+ *.jpg filter=lfs diff=lfs merge=lfs -text
136
+ *.jpeg filter=lfs diff=lfs merge=lfs -text
137
+ *.webp filter=lfs diff=lfs merge=lfs -text
138
+ *.dat filter=lfs diff=lfs merge=lfs -text
139
+ *.avi filter=lfs diff=lfs merge=lfs -text
140
+ *.wav filter=lfs diff=lfs merge=lfs -text
141
+ *.flac filter=lfs diff=lfs merge=lfs -text
142
+ *.hdf5 filter=lfs diff=lfs merge=lfs -text
video/dfd-fcg/Dockerfile ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM nvidia/cuda:12.1.1-cudnn8-runtime-ubuntu22.04
2
+
3
+ ENV DEBIAN_FRONTEND=noninteractive
4
+ ENV PYTHONUNBUFFERED=1
5
+
6
+ WORKDIR /app
7
+
8
+ # Install Python 3.10 and system dependencies for OpenCV
9
+ RUN apt-get update && apt-get install -y --no-install-recommends \
10
+ python3 python3-pip \
11
+ libgl1 \
12
+ libglib2.0-0 \
13
+ libsm6 \
14
+ libxext6 \
15
+ libxrender-dev \
16
+ && rm -rf /var/lib/apt/lists/*
17
+
18
+ RUN ln -sf /usr/bin/python3 /usr/bin/python
19
+
20
+ # Install PyTorch with CUDA 12.1
21
+ RUN pip install --no-cache-dir \
22
+ torch==2.5.1 torchvision==0.20.1 \
23
+ --index-url https://download.pytorch.org/whl/cu121
24
+
25
+ # Copy requirements and install
26
+ # facenet-pytorch needs --no-deps due to torch<2.3 pin
27
+ COPY requirements.txt .
28
+ RUN pip install --no-cache-dir --no-deps facenet-pytorch && \
29
+ pip install --no-cache-dir -r requirements.txt
30
+
31
+ # Create logs and weights directories
32
+ RUN mkdir -p logs weights model_code
33
+
34
+ # Copy model code (read-only reference, never modified)
35
+ COPY model_code/ /app/model_code/
36
+
37
+ # Copy weights
38
+ COPY weights/ /app/weights/
39
+
40
+ # Copy application code
41
+ COPY app.py .
42
+
43
+ # Environment variables
44
+ ENV MODEL_PORT=7003
45
+ ENV PRELOAD_MODEL=false
46
+ ENV MODEL_TIMEOUT=1800
47
+ ENV WEIGHTS_PATH=/app/weights/dfd_fcg_checkpoint.pth
48
+ ENV MODEL_CODE_DIR=/app/model_code
49
+
50
+ # Expose port
51
+ EXPOSE 7003
52
+
53
+ # Drop root privileges
54
+ RUN adduser --disabled-password --gecos '' appuser && \
55
+ chown -R appuser:appuser /app/logs /app/weights
56
+ USER appuser
57
+
58
+ # Run the service
59
+ CMD ["python", "app.py"]
video/dfd-fcg/app.py ADDED
@@ -0,0 +1,661 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """DFD-FCG (Deepfake Detection via Facial Component Guidance) service.
2
+
3
+ Wraps the DFD-FCG (CVPR 2025) video deepfake detection model with a
4
+ FastAPI endpoint. Uses CLIP ViT-L/14 with a Synoptic Video Learner
5
+ and Facial Component Guidance for robust face forgery detection.
6
+
7
+ The model analyses temporal and spatial inconsistencies across facial
8
+ components (lips, skin, eyes, nose) using learned synoptic attention
9
+ over multi-frame CLIP embeddings.
10
+
11
+ Reference: "Deepfake Detection via Facial Component Guidance",
12
+ CVPR 2025.
13
+ """
14
+
15
+ import base64
16
+ import gc
17
+ import logging
18
+ import math
19
+ import os
20
+ import platform
21
+ import sys
22
+ import tempfile
23
+ import threading
24
+ import time
25
+ from typing import Any, Dict, List, Optional, Tuple
26
+
27
+ import cv2
28
+ import numpy as np
29
+ import torch
30
+ import torch.nn.functional as F
31
+ import uvicorn
32
+ from fastapi import FastAPI, HTTPException
33
+ from PIL import Image
34
+ from pydantic import BaseModel, ConfigDict, Field
35
+
36
+ logging.basicConfig(level=logging.INFO)
37
+ logger = logging.getLogger(__name__)
38
+
39
+ MODEL_PORT = int(os.environ.get("MODEL_PORT", 7003))
40
+ PRELOAD_MODEL = (
41
+ os.environ.get("PRELOAD_MODEL", "false").lower() == "true"
42
+ )
43
+ MODEL_TIMEOUT = int(os.environ.get("MODEL_TIMEOUT", 1800))
44
+ WEIGHTS_PATH = os.environ.get(
45
+ "WEIGHTS_PATH", "/app/weights/dfd_fcg_checkpoint.pth"
46
+ )
47
+ # Path to serialized face semantic features used by FFG module
48
+ FACE_FEATURES_PATH = os.environ.get(
49
+ "FACE_FEATURES_PATH",
50
+ "/app/model_code/misc/L14_real_semantic_patches_v4_2000.pickle",
51
+ )
52
+
53
+ # DFD-FCG uses CLIP ViT-L/14 at 224x224 (standard CLIP resolution)
54
+ IMAGE_SIZE = 224
55
+ # Number of frames to sample per clip (matches config num_frames=10)
56
+ NUM_FRAMES = 10
57
+ # Frame sampling stride in seconds (matches demo.py stride=0.333)
58
+ FRAME_STRIDE = 0.333
59
+ # Face crop margin factor for MTCNN bounding boxes
60
+ MARGIN_FACTOR = 0.5
61
+
62
+
63
+ def _get_device() -> torch.device:
64
+ """Select optimal device: CUDA (NVIDIA) > MPS (Apple) > CPU."""
65
+ override = os.environ.get("DEEPSAFE_DEVICE", "").strip().lower()
66
+ if override == "cpu":
67
+ return torch.device("cpu")
68
+ if override == "cuda" and torch.cuda.is_available():
69
+ return torch.device("cuda")
70
+ if (
71
+ override == "mps"
72
+ and hasattr(torch.backends, "mps")
73
+ and torch.backends.mps.is_available()
74
+ ):
75
+ return torch.device("mps")
76
+ if torch.cuda.is_available():
77
+ return torch.device("cuda")
78
+ if (
79
+ platform.system() == "Darwin"
80
+ and hasattr(torch.backends, "mps")
81
+ and torch.backends.mps.is_available()
82
+ ):
83
+ return torch.device("mps")
84
+ return torch.device("cpu")
85
+
86
+
87
+ def _build_model_from_config():
88
+ """Build FFGSynoVideoLearner from config parameters.
89
+
90
+ Instantiates the model directly using the same parameters
91
+ defined in configs/clip/L14/ffg.yaml and configs/base.yaml,
92
+ avoiding the heavy ODLightningCLI/trainer machinery that is
93
+ unnecessary for inference.
94
+
95
+ Returns:
96
+ An FFGSynoVideoLearner instance (unloaded weights).
97
+ """
98
+ # Add model_code to sys.path so src.* imports resolve
99
+ model_code_dir = os.environ.get(
100
+ "MODEL_CODE_DIR", "/app/model_code"
101
+ )
102
+ if model_code_dir not in sys.path:
103
+ sys.path.insert(0, model_code_dir)
104
+
105
+ # Suppress wandb import in svl.py (it imports wandb at top)
106
+ if "wandb" not in sys.modules:
107
+ import types
108
+ wandb_stub = types.ModuleType("wandb")
109
+ sys.modules["wandb"] = wandb_stub
110
+
111
+ from src.model.clip.svl import FFGSynoVideoLearner
112
+
113
+ model = FFGSynoVideoLearner(
114
+ # FFG-specific params (from configs/clip/L14/ffg.yaml)
115
+ face_feature_path=FACE_FEATURES_PATH,
116
+ face_parts=["lips", "skin", "eyes", "nose"],
117
+ architecture="ViT-L/14",
118
+ num_frames=NUM_FRAMES,
119
+ ksize_s=5,
120
+ ksize_t=5,
121
+ s_k_attr="k",
122
+ s_v_attr="emb",
123
+ t_attrs=["q", "k", "v"],
124
+ # Defaults from base model
125
+ text_embed=False,
126
+ op_mode=["S", "T"],
127
+ )
128
+ return model
129
+
130
+
131
+ # ── Global state ───────────────────────────────────────────────────
132
+
133
+ _model = None
134
+ _face_detector = None
135
+ _transform = None
136
+ _device: Optional[torch.device] = None
137
+ _load_lock = threading.Lock()
138
+
139
+
140
+ def _load_models() -> None:
141
+ """Load DFD-FCG model and MTCNN face detector (thread-safe)."""
142
+ global _model, _face_detector, _transform, _device
143
+
144
+ if _model is not None:
145
+ return
146
+
147
+ with _load_lock:
148
+ if _model is not None:
149
+ return
150
+
151
+ _device = _get_device()
152
+ if _device.type == "cuda":
153
+ torch.backends.cudnn.benchmark = True
154
+ torch.set_float32_matmul_precision("high")
155
+ if _device.type == "cuda":
156
+ logger.info(
157
+ "Device: cuda (%s, %.1f GB VRAM)",
158
+ torch.cuda.get_device_name(0),
159
+ torch.cuda.get_device_properties(0).total_mem
160
+ / 1024**3,
161
+ )
162
+ else:
163
+ logger.warning(
164
+ "Device: %s (no CUDA -- check "
165
+ "nvidia-container-toolkit)",
166
+ _device,
167
+ )
168
+ logger.info("Loading DFD-FCG model on %s ...", _device)
169
+
170
+ # ── Face detector (MTCNN) ──────────────────────────────
171
+ from facenet_pytorch import MTCNN
172
+
173
+ _face_detector = MTCNN(
174
+ keep_all=True,
175
+ device=_device,
176
+ post_process=False,
177
+ )
178
+
179
+ # ── DFD-FCG model ──────────────────────────────────────
180
+ if not os.path.exists(WEIGHTS_PATH):
181
+ raise FileNotFoundError(
182
+ f"DFD-FCG weights not found at {WEIGHTS_PATH}"
183
+ )
184
+
185
+ model = _build_model_from_config()
186
+ model_cls = model.__class__
187
+
188
+ # The checkpoint stores face_feature_path as a
189
+ # relative path (e.g. "misc/..."). We must set CWD
190
+ # to model_code/ so load_from_checkpoint can resolve
191
+ # it when replaying the constructor.
192
+ model_code_dir = os.environ.get(
193
+ "MODEL_CODE_DIR", "/app/model_code"
194
+ )
195
+ original_cwd = os.getcwd()
196
+ os.chdir(model_code_dir)
197
+
198
+ try:
199
+ model = model_cls.load_from_checkpoint(
200
+ WEIGHTS_PATH
201
+ )
202
+ except Exception:
203
+ logger.info(
204
+ "Strict checkpoint load failed, "
205
+ "retrying non-strict."
206
+ )
207
+ model = model_cls.load_from_checkpoint(
208
+ WEIGHTS_PATH, strict=False
209
+ )
210
+ finally:
211
+ os.chdir(original_cwd)
212
+
213
+ model = model.to(_device)
214
+ model.requires_grad_(False)
215
+ # Use torch eval -- demo.py uses the same pattern
216
+ model.train(False)
217
+
218
+ _transform = model.transform
219
+ _model = model
220
+ logger.info("DFD-FCG model loaded successfully.")
221
+
222
+
223
+ def _is_model_loaded() -> bool:
224
+ """Return True if model and face detector are loaded."""
225
+ return _model is not None and _face_detector is not None
226
+
227
+
228
+ # ── FastAPI app ────────────────────────────────────────────────────
229
+
230
+ app = FastAPI(
231
+ title="DFD-FCG Detection Service",
232
+ description=(
233
+ "Deepfake Detection via Facial Component Guidance "
234
+ "(CLIP ViT-L/14, CVPR 2025)"
235
+ ),
236
+ version="1.0.0",
237
+ )
238
+
239
+
240
+ class PredictRequest(BaseModel):
241
+ """Incoming prediction request."""
242
+
243
+ video_data: str # Base64-encoded video bytes
244
+ threshold: float = 0.5
245
+
246
+
247
+ class PredictResponse(BaseModel):
248
+ """Outgoing prediction result."""
249
+
250
+ model_config = ConfigDict(populate_by_name=True)
251
+
252
+ model: str = "dfd_fcg_detection"
253
+ probability: float
254
+ prediction: int
255
+ class_name: str = Field(..., alias="class")
256
+ inference_time: float
257
+ metadata: Dict[str, Any]
258
+
259
+
260
+ @app.on_event("startup")
261
+ async def startup_event():
262
+ """Optionally preload model at startup."""
263
+ if PRELOAD_MODEL:
264
+ _load_models()
265
+
266
+
267
+ @app.get("/")
268
+ def root():
269
+ """Service info endpoint."""
270
+ return {
271
+ "service": "dfd_fcg_detection",
272
+ "port": MODEL_PORT,
273
+ "model_loaded": _is_model_loaded(),
274
+ "device": str(_device) if _device else "unknown",
275
+ }
276
+
277
+
278
+ def _gpu_health_info() -> dict:
279
+ """Return GPU metrics for the health endpoint."""
280
+ if (
281
+ torch.cuda.is_available()
282
+ and _device is not None
283
+ and _device.type == "cuda"
284
+ ):
285
+ return {
286
+ "gpu_name": torch.cuda.get_device_name(0),
287
+ "vram_used_mb": round(
288
+ torch.cuda.memory_allocated(0) / 1024**2
289
+ ),
290
+ "vram_total_mb": round(
291
+ torch.cuda.get_device_properties(0).total_mem
292
+ / 1024**2
293
+ ),
294
+ }
295
+ return {}
296
+
297
+
298
+ @app.get("/health")
299
+ def health():
300
+ """Health check endpoint."""
301
+ return {
302
+ "status": "healthy",
303
+ "model": "dfd_fcg_detection",
304
+ "device": str(_device) if _device else "cpu",
305
+ "model_loaded": _is_model_loaded(),
306
+ "weights_exist": os.path.exists(WEIGHTS_PATH),
307
+ **_gpu_health_info(),
308
+ }
309
+
310
+
311
+ # ── Video / face utilities ─────────────────────────────────────────
312
+
313
+
314
+ def _extract_dense_frames(
315
+ video_path: str,
316
+ ) -> Tuple[List[np.ndarray], float]:
317
+ """Extract all frames from a video for clip-based sampling.
318
+
319
+ Args:
320
+ video_path: Path to the video on disk.
321
+
322
+ Returns:
323
+ Tuple of (list of RGB uint8 arrays, fps).
324
+ """
325
+ cap = cv2.VideoCapture(video_path)
326
+ fps = cap.get(cv2.CAP_PROP_FPS) or 30.0
327
+ frames: List[np.ndarray] = []
328
+
329
+ while True:
330
+ ret, frame = cap.read()
331
+ if not ret:
332
+ break
333
+ frames.append(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
334
+
335
+ cap.release()
336
+ return frames, fps
337
+
338
+
339
+ def _crop_face(
340
+ img: np.ndarray,
341
+ bbox: Tuple[float, float, float, float],
342
+ margin: float = MARGIN_FACTOR,
343
+ ) -> np.ndarray:
344
+ """Crop a face region from an image with a relative margin.
345
+
346
+ Args:
347
+ img: RGB image array (H, W, 3).
348
+ bbox: (x0, y0, x1, y1) face bounding box.
349
+ margin: Fraction of bbox dimension to add as padding.
350
+
351
+ Returns:
352
+ Cropped face region as a numpy array.
353
+ """
354
+ h_img, w_img = img.shape[:2]
355
+ x0, y0, x1, y1 = bbox
356
+ w = x1 - x0
357
+ h = y1 - y0
358
+
359
+ x0_new = max(0, int(x0 - w * margin / 2))
360
+ x1_new = min(w_img, int(x1 + w * margin / 2) + 1)
361
+ y0_new = max(0, int(y0 - h * margin / 2))
362
+ y1_new = min(h_img, int(y1 + h * margin / 2) + 1)
363
+
364
+ return img[y0_new:y1_new, x0_new:x1_new]
365
+
366
+
367
+ def _detect_and_crop_face(
368
+ frame: np.ndarray,
369
+ ) -> Optional[np.ndarray]:
370
+ """Detect the largest face in a frame and return the crop.
371
+
372
+ Uses MTCNN for detection, selects the largest bounding box,
373
+ crops with margin, and returns the face region.
374
+
375
+ Args:
376
+ frame: RGB image array (H, W, 3).
377
+
378
+ Returns:
379
+ Face crop as uint8 array, or None if no face found.
380
+ """
381
+ assert _face_detector is not None
382
+
383
+ pil_img = Image.fromarray(frame)
384
+ boxes, _ = _face_detector.detect(pil_img)
385
+
386
+ if boxes is None or len(boxes) == 0:
387
+ return None
388
+
389
+ # Select the largest face by bounding box area
390
+ areas = [
391
+ (b[2] - b[0]) * (b[3] - b[1]) for b in boxes
392
+ ]
393
+ best_idx = int(np.argmax(areas))
394
+ box = boxes[best_idx]
395
+
396
+ x0, y0, x1, y1 = box.tolist()
397
+ face = _crop_face(frame, (x0, y0, x1, y1))
398
+ if face.size == 0:
399
+ return None
400
+
401
+ return face
402
+
403
+
404
+ def _prepare_clip_tensor(
405
+ face_crops: List[np.ndarray],
406
+ ) -> Optional[torch.Tensor]:
407
+ """Apply the model's CLIP transform to face crops.
408
+
409
+ Converts a list of face crop arrays into a single tensor
410
+ of shape (1, num_frames, 3, 224, 224) suitable for the
411
+ DFD-FCG model.
412
+
413
+ Args:
414
+ face_crops: List of RGB uint8 face crop arrays.
415
+
416
+ Returns:
417
+ Tensor of shape (1, T, 3, 224, 224) or None.
418
+ """
419
+ if not face_crops or _transform is None:
420
+ return None
421
+
422
+ # The model transform expects either PIL or tensor input.
423
+ # Convert each crop to a torch tensor (C, H, W) uint8,
424
+ # which the custom _to_tensor in clip.py handles (divides
425
+ # by 255 if max > 1).
426
+ transformed = []
427
+ for crop in face_crops:
428
+ # Convert HWC uint8 -> CHW tensor
429
+ t = torch.from_numpy(crop).permute(2, 0, 1)
430
+ t = _transform(t)
431
+ transformed.append(t)
432
+
433
+ # Stack into (T, C, H, W), then add batch dim
434
+ clip_tensor = torch.stack(transformed, dim=0)
435
+ clip_tensor = clip_tensor.unsqueeze(0) # (1, T, C, H, W)
436
+ return clip_tensor
437
+
438
+
439
+ def _find_nearest_crop(
440
+ crops: List[Optional[np.ndarray]],
441
+ idx: int,
442
+ ) -> Optional[np.ndarray]:
443
+ """Find the nearest non-None face crop to a given index.
444
+
445
+ Searches outward from idx in both directions to find the
446
+ closest frame that had a detected face.
447
+
448
+ Args:
449
+ crops: List of face crops (may contain None entries).
450
+ idx: Target index.
451
+
452
+ Returns:
453
+ The nearest non-None crop, or None if all are None.
454
+ """
455
+ n = len(crops)
456
+ for offset in range(n):
457
+ for candidate in (idx - offset, idx + offset):
458
+ if (
459
+ 0 <= candidate < n
460
+ and crops[candidate] is not None
461
+ ):
462
+ return crops[candidate]
463
+ return None
464
+
465
+
466
+ # ── Prediction endpoint ────────────────────────────────────────────
467
+
468
+
469
+ @app.post("/predict", response_model=PredictResponse)
470
+ async def predict(request: PredictRequest):
471
+ """Run DFD-FCG deepfake detection on a base64-encoded video.
472
+
473
+ Pipeline:
474
+ 1. Decode video and write to temp file.
475
+ 2. Extract all frames from the video.
476
+ 3. Detect and crop the main face per frame (MTCNN).
477
+ 4. Build overlapping clips of NUM_FRAMES face crops.
478
+ 5. Run each clip through the DFD-FCG model.
479
+ 6. Average per-clip fake probabilities.
480
+
481
+ If no faces are detected in any frame, the service returns
482
+ probability=0.5 (undetermined) rather than raising an error.
483
+ """
484
+ if not _is_model_loaded():
485
+ _load_models()
486
+
487
+ start_time = time.time()
488
+
489
+ # ── Decode video ───────────────────────────────────────────
490
+ with tempfile.NamedTemporaryFile(
491
+ suffix=".mp4", delete=False
492
+ ) as tmp:
493
+ try:
494
+ video_bytes = base64.b64decode(request.video_data)
495
+ tmp.write(video_bytes)
496
+ tmp_path = tmp.name
497
+ except Exception as e:
498
+ raise HTTPException(
499
+ status_code=400,
500
+ detail=f"Failed to decode video: {e}",
501
+ )
502
+
503
+ try:
504
+ # ── Extract frames ─────────────────────────────────────
505
+ frames, fps = _extract_dense_frames(tmp_path)
506
+ if not frames:
507
+ raise HTTPException(
508
+ status_code=400,
509
+ detail="Could not extract frames from video.",
510
+ )
511
+
512
+ # ── Detect and crop faces ──────────────────────────────
513
+ face_crops: List[Optional[np.ndarray]] = []
514
+ faces_detected = 0
515
+ for frame in frames:
516
+ crop = _detect_and_crop_face(frame)
517
+ face_crops.append(crop)
518
+ if crop is not None:
519
+ faces_detected += 1
520
+
521
+ if faces_detected == 0:
522
+ # No faces in any frame -- undetermined
523
+ return PredictResponse(
524
+ probability=0.5,
525
+ prediction=0,
526
+ class_name="real",
527
+ inference_time=time.time() - start_time,
528
+ metadata={
529
+ "frames_total": len(frames),
530
+ "frames_with_faces": 0,
531
+ "clips_evaluated": 0,
532
+ "device": str(_device),
533
+ },
534
+ )
535
+
536
+ # ── Build clips and run inference ──────────────────────
537
+ # Sample clip indices matching the demo.py pattern:
538
+ # indices spaced by stride*fps, NUM_FRAMES per clip
539
+ stride_frames = max(
540
+ 1, int(math.floor(FRAME_STRIDE * fps))
541
+ )
542
+ clip_indices = [
543
+ i * stride_frames for i in range(NUM_FRAMES)
544
+ ]
545
+ max_start = len(frames) - clip_indices[-1] - 1
546
+
547
+ probs: List[float] = []
548
+ batch_size = 8
549
+
550
+ if max_start <= 0:
551
+ # Video too short for stride-based sampling;
552
+ # uniformly sample NUM_FRAMES frames instead.
553
+ sample_idx = np.linspace(
554
+ 0,
555
+ len(frames) - 1,
556
+ NUM_FRAMES,
557
+ endpoint=True,
558
+ dtype=int,
559
+ )
560
+ clip_crops = []
561
+ for idx in sample_idx:
562
+ c = face_crops[idx]
563
+ if c is None:
564
+ c = _find_nearest_crop(face_crops, idx)
565
+ if c is not None:
566
+ clip_crops.append(c)
567
+
568
+ if len(clip_crops) == NUM_FRAMES:
569
+ tensor = _prepare_clip_tensor(clip_crops)
570
+ if tensor is not None:
571
+ tensor = tensor.to(_device)
572
+ with torch.no_grad():
573
+ result = _model.evaluate(tensor)
574
+ p = (
575
+ result["logits"]
576
+ .softmax(dim=-1)[:, 1]
577
+ .cpu()
578
+ .item()
579
+ )
580
+ probs.append(p)
581
+ else:
582
+ # Process clips in batches
583
+ clip_starts = list(range(0, max_start + 1))
584
+ for batch_start in range(
585
+ 0, len(clip_starts), batch_size
586
+ ):
587
+ batch_clips = clip_starts[
588
+ batch_start: batch_start + batch_size
589
+ ]
590
+ tensors = []
591
+ for start in batch_clips:
592
+ clip_crops = []
593
+ for offset in clip_indices:
594
+ idx = start + offset
595
+ c = face_crops[idx]
596
+ if c is None:
597
+ c = _find_nearest_crop(
598
+ face_crops, idx
599
+ )
600
+ if c is not None:
601
+ clip_crops.append(c)
602
+
603
+ if len(clip_crops) == NUM_FRAMES:
604
+ t = _prepare_clip_tensor(clip_crops)
605
+ if t is not None:
606
+ tensors.append(t)
607
+
608
+ if tensors:
609
+ batch_tensor = torch.cat(
610
+ tensors, dim=0
611
+ ).to(_device)
612
+ with torch.no_grad():
613
+ result = _model.evaluate(
614
+ batch_tensor
615
+ )
616
+ batch_probs = (
617
+ result["logits"]
618
+ .softmax(dim=-1)[:, 1]
619
+ .flatten()
620
+ .cpu()
621
+ .tolist()
622
+ )
623
+ probs.extend(batch_probs)
624
+
625
+ # ── Aggregate ──────────────────────────────────────────
626
+ if probs:
627
+ probability = float(np.mean(probs))
628
+ else:
629
+ probability = 0.5
630
+
631
+ prediction = (
632
+ 1 if probability >= request.threshold else 0
633
+ )
634
+ class_name = "fake" if prediction == 1 else "real"
635
+
636
+ return PredictResponse(
637
+ probability=probability,
638
+ prediction=prediction,
639
+ class_name=class_name,
640
+ inference_time=time.time() - start_time,
641
+ metadata={
642
+ "frames_total": len(frames),
643
+ "frames_with_faces": faces_detected,
644
+ "clips_evaluated": len(probs),
645
+ "device": str(_device),
646
+ },
647
+ )
648
+
649
+ except HTTPException:
650
+ raise
651
+ except Exception as e:
652
+ logger.exception("Error during DFD-FCG prediction")
653
+ raise HTTPException(status_code=500, detail=str(e))
654
+ finally:
655
+ if os.path.exists(tmp_path):
656
+ os.remove(tmp_path)
657
+ gc.collect()
658
+
659
+
660
+ if __name__ == "__main__":
661
+ uvicorn.run(app, host="0.0.0.0", port=MODEL_PORT)
video/dfd-fcg/model_code/.gitignore ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ logs
2
+ __pycache__
3
+ .ipynb_checkpoints
4
+ .DS_Store
5
+ *.swp
6
+ wandb/
7
+ *.env
8
+ datasets/
9
+ datasets
10
+ .cache/
11
+ .cache
12
+ lightning_logs/
13
+ .lr_find_*
14
+ RealForensicPreds/
15
+ results/
16
+ checkpoint/
17
+ .vscode/
18
+ resources/cropped/
19
+ resources/frame_data/
20
+ *.pt
video/dfd-fcg/model_code/assets/demo.png ADDED

Git LFS Details

  • SHA256: 851b385ddad9b9987bc24909f0a888281a71b454fbccd59f0df81514a6e09894
  • Pointer size: 132 Bytes
  • Size of remote file: 2.03 MB
video/dfd-fcg/model_code/assets/teaser.png ADDED

Git LFS Details

  • SHA256: af1e18a5bf18f7570b440d6d011a691860a84ef7e9e73350303126003b23b6ec
  • Pointer size: 131 Bytes
  • Size of remote file: 849 kB
video/dfd-fcg/model_code/configs/base.yaml ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # lightning.pytorch==2.0.7
2
+ seed_everything: 1019
3
+ trainer:
4
+ accelerator: auto
5
+ strategy: auto
6
+ devices: 4
7
+ num_nodes: 1
8
+ precision: 16
9
+ logger: logger.yaml
10
+ callbacks: null
11
+ fast_dev_run: false
12
+ max_epochs: 30
13
+ min_epochs: null
14
+ max_steps: -1
15
+ min_steps: null
16
+ max_time: null
17
+ limit_train_batches: null
18
+ limit_val_batches: 10
19
+ limit_test_batches: null
20
+ limit_predict_batches: null
21
+ overfit_batches: 0.0
22
+ val_check_interval: 1.0
23
+ check_val_every_n_epoch: 1
24
+ num_sanity_val_steps: null
25
+ log_every_n_steps: 10
26
+ enable_checkpointing: null
27
+ enable_progress_bar: null
28
+ enable_model_summary: null
29
+ accumulate_grad_batches: 1
30
+ gradient_clip_val: 0.1
31
+ gradient_clip_algorithm: norm
32
+ deterministic: true
33
+ benchmark: null
34
+ inference_mode: true
35
+ use_distributed_sampler: true
36
+ profiler: null
37
+ detect_anomaly: false
38
+ barebones: false
39
+ plugins: null
40
+ sync_batchnorm: false
41
+ reload_dataloaders_every_n_epochs: 0
42
+ default_root_dir: "./logs/"
43
+ early_stop:
44
+ monitor: "valid/FFPP/auc"
45
+ min_delta: 0.0
46
+ patience: 10
47
+ verbose: false
48
+ mode: max
49
+ strict: true
50
+ check_finite: true
51
+ stopping_threshold: null
52
+ divergence_threshold: null
53
+ check_on_train_epoch_end: null
54
+ log_rank_zero_only: false
55
+ checkpoint:
56
+ dirpath: null
57
+ filename: null
58
+ monitor: "valid/FFPP/auc"
59
+ verbose: false
60
+ save_last: true
61
+ save_top_k: 1
62
+ save_weights_only: false
63
+ mode: max
64
+ auto_insert_metric_name: true
65
+ every_n_train_steps: null
66
+ train_time_interval: null
67
+ every_n_epochs: null
68
+ save_on_train_epoch_end: null
69
+ lr_monitor:
70
+ logging_interval: epoch
71
+ log_momentum: false
72
+ progress_bar:
73
+ refresh_rate: 1
74
+ leave: false
75
+ theme:
76
+ description: '#8250E5'
77
+ progress_bar: '#7FFF00'
78
+ progress_bar_finished: '#7FFF00'
79
+ progress_bar_pulse: '#7FFF00'
80
+ batch_progress: '#5398FE'
81
+ time: grey54
82
+ processing_speed: grey70
83
+ metrics: white
84
+ console_kwargs: null
85
+ optimizer:
86
+ lr: 0.0001
87
+ betas:
88
+ - 0.9
89
+ - 0.999
90
+ eps: 1.0e-08
91
+ weight_decay: 0.001
92
+ amsgrad: false
93
+ maximize: false
94
+ foreach: null
95
+ differentiable: false
96
+ lr_scheduler:
97
+ start_factor: 1.0
98
+ end_factor: 1.0
99
+ total_iters: 1
100
+ last_epoch: -1
101
+ verbose: false
102
+ data: data.yaml
video/dfd-fcg/model_code/configs/clip/L14/evl.yaml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ model:
2
+ class_path: src.model.clip.evl.EfficientVideoLearner
3
+ init_args:
4
+ num_frames: 10
5
+ architecture: ViT-L/14
6
+ trainer:
7
+ accumulate_grad_batches: 1
video/dfd-fcg/model_code/configs/clip/L14/ffg.yaml ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ model:
2
+ class_path: src.model.clip.svl.FFGSynoVideoLearner
3
+ init_args:
4
+ num_frames: 10
5
+ architecture: ViT-L/14
6
+ ksize_s: 5
7
+ ksize_t: 5
8
+ s_k_attr: 'k'
9
+ s_v_attr: 'emb'
10
+ t_attrs: ["q","k","v"]
11
+ face_feature_path: "misc/L14_real_semantic_patches_v4_2000.pickle"
12
+ face_parts: ["lips","skin","eyes","nose"]
13
+
14
+ trainer:
15
+ accumulate_grad_batches: 1
video/dfd-fcg/model_code/configs/clip/L14/fulltune.yaml ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ model:
2
+ class_path: src.model.clip.finetune.FullTuneVideoLearner
3
+ init_args:
4
+ architecture: ViT-L/14
5
+ trainer:
6
+ accumulate_grad_batches: 1
video/dfd-fcg/model_code/configs/clip/L14/linear.yaml ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ model:
2
+ class_path: src.model.clip.linear.LinearVideoLearner
3
+ init_args:
4
+ architecture: ViT-L/14
5
+ trainer:
6
+ accumulate_grad_batches: 1
video/dfd-fcg/model_code/configs/clip/L14/svl.yaml ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ model:
2
+ class_path: src.model.clip.svl.SynoVideoLearner
3
+ init_args:
4
+ num_frames: 10
5
+ architecture: ViT-L/14
6
+ ksize_s: 5
7
+ ksize_t: 5
8
+ s_k_attr: 'k'
9
+ s_v_attr: 'emb'
10
+ t_attrs: ["q","k","v"]
11
+ trainer:
12
+ accumulate_grad_batches: 1
video/dfd-fcg/model_code/configs/clip/L14/vpt.yaml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ model:
2
+ class_path: src.model.clip.vpt.PromptedLinearVideoLearner
3
+ init_args:
4
+ architecture: ViT-L/14
5
+ num_prompts: 1
6
+ trainer:
7
+ accumulate_grad_batches: 1
video/dfd-fcg/model_code/configs/data.yaml ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class_path: src.dataset.base.ODDeepFakeDataModule
2
+ init_args:
3
+ batch_size: 20
4
+ num_workers: 4
5
+ clip_duration: 3
6
+ num_frames: 10
7
+ train_datamodules:
8
+ - class_path: src.dataset.ffpp.FFPPDataModule
9
+ init_args:
10
+ batch_size: 30
11
+ df_types: ['REAL','DF','FS','F2F','NT']
12
+ compressions: ['c23']
13
+ strategy: FORCE_PAIR
14
+ augmentations:
15
+ - NORMAL
16
+ - VIDEO
17
+ - VIDEO_RRC
18
+ - FRAME
19
+ force_random_speed: null
20
+ data_dir: 'datasets/ffpp/'
21
+ vid_ext: '.avi'
22
+ pack: false
23
+ max_clips: 3
24
+ val_datamodules:
25
+ - class_path: src.dataset.ffpp.FFPPDataModule
26
+ init_args:
27
+ df_types: ['REAL','DF','FS','F2F','NT']
28
+ compressions: ['c23']
29
+ strategy: NORMAL
30
+ augmentations:
31
+ - NONE
32
+ data_dir: 'datasets/ffpp/'
33
+ vid_ext: '.avi'
34
+ pack: false
35
+ max_clips: 1
36
+ - class_path: src.dataset.cdf.CDFDataModule
37
+ init_args:
38
+ data_dir: 'datasets/cdf/'
39
+ vid_ext: '.avi'
40
+ pack: false
41
+ max_clips: 1
42
+ - class_path: src.dataset.dfdc.DFDCDataModule
43
+ init_args:
44
+ data_dir: 'datasets/dfdc/'
45
+ vid_ext: '.avi'
46
+ pack: false
47
+ max_clips: 1
48
+ - class_path: src.dataset.fsh.FShDataModule
49
+ init_args:
50
+ compressions: ['c23']
51
+ data_dir: 'datasets/ffpp/'
52
+ vid_ext: '.avi'
53
+ pack: false
54
+ max_clips: 1
video/dfd-fcg/model_code/configs/inference.yaml ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ # - class_path: src.dataset.ffpp.FFPPDataModule
6
+ # init_args:
7
+ # df_types: ['REAL','DF','FS','F2F','NT']
8
+ # compressions: ['c23']
9
+ # strategy: NORMAL
10
+ # augmentations:
11
+ # - NONE
12
+ # force_random_speed: null
13
+ # data_dir: 'datasets/ffpp/'
14
+ # vid_ext: .avi
15
+ - class_path: src.dataset.cdf.CDFDataModule
16
+ init_args:
17
+ data_dir: 'datasets/cdf/'
18
+ vid_ext: .avi
19
+ - class_path: src.dataset.dfdc.DFDCDataModule
20
+ init_args:
21
+ data_dir: 'datasets/dfdc/'
22
+ vid_ext: .avi
23
+ - class_path: src.dataset.fsh.FShDataModule
24
+ init_args:
25
+ data_dir: 'datasets/ffpp/'
26
+ compressions: ['c23']
27
+ vid_ext: .avi
28
+ - class_path: src.dataset.dfo.DFoDataModule
29
+ init_args:
30
+ data_dir: 'datasets/dfo/'
31
+ vid_ext: .avi
32
+ # - class_path: src.dataset.wdf.WDFDataModule
33
+ # init_args:
34
+ # data_dir: 'datasets/wdf/'
35
+ # vid_ext: .avi
36
+ # - class_path: src.dataset.heygen.HeyGenDataModule
37
+ # init_args:
38
+ # data_dir: 'datasets/heygen/'
39
+ # vid_ext: .avi
video/dfd-fcg/model_code/configs/logger.yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class_path: lightning.pytorch.loggers.WandbLogger
2
+ init_args:
3
+ name: null
4
+ save_dir: './logs/'
5
+ version: null
6
+ offline: false
7
+ dir: null
8
+ id: null
9
+ anonymous: null
10
+ project: 'DFD-FCG'
11
+ log_model: false
12
+ prefix: ''
13
+ checkpoint_name: null
14
+ entity: ""
video/dfd-fcg/model_code/configs/loo/DF.yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/ffpp/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/loo/F2F.yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','F2F']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/ffpp/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/loo/FS.yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','FS']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/ffpp/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/loo/NT.yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/ffpp/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/BW(1).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/BW/1/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/BW(2).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/BW/2/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/BW(3).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/BW/3/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/BW(4).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/BW/4/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/BW(5).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/BW/5/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/CC(1).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/CC/1/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/CC(2).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/CC/2/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/CC(3).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/CC/3/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/CC(4).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/CC/4/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/CC(5).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/CC/5/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/CS(1).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/CS/1/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/CS(2).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/CS/2/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/CS(3).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/CS/3/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/CS(4).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/CS/4/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/CS(5).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/CS/5/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/GB(1).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/GB/1/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/GB(2).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/GB/2/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/GB(3).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/GB/3/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/GB(4).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/GB/4/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/GB(5).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/GB/5/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/GNC(1).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/GNC/1/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/GNC(2).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/GNC/2/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/GNC(3).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/GNC/3/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/GNC(4).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/GNC/4/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/GNC(5).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/GNC/5/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/JPEG(1).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/JPEG/1/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/JPEG(2).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/JPEG/2/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/JPEG(3).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/JPEG/3/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/JPEG(4).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/JPEG/4/'
14
+ vid_ext: .avi
video/dfd-fcg/model_code/configs/robustness/JPEG(5).yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ data:
2
+ class_path: src.dataset.base.ODDeepFakeDataModule
3
+ init_args:
4
+ test_datamodules:
5
+ - class_path: src.dataset.ffpp.FFPPDataModule
6
+ init_args:
7
+ df_types: ['REAL','DF','FS','F2F','NT']
8
+ compressions: ['c23']
9
+ strategy: NORMAL
10
+ augmentations:
11
+ - NONE
12
+ force_random_speed: null
13
+ data_dir: 'datasets/robustness/JPEG/5/'
14
+ vid_ext: .avi