akagtag commited on
Commit
39f9e8e
·
1 Parent(s): 296a5fe

feat(fingerprint): improve CLIP attribution accuracy and add 4th detector

Browse files

- Rewrite GENERATOR_PROMPTS to describe visual forensic artifacts instead of
content style — CLIP picks up texture/frequency cues better than generator names
- Add umm-maybe/AI-image-detector (EfficientNet fine-tuned on AI vs real) as 4th
ensemble detector with weight 0.1; rebalance existing weights to [0.4,0.3,0.2,0.1]
- Raise CLIP confidence threshold 0.25 → 0.32 (2.9× above chance for 9 classes)
to reduce incorrect attributions when CLIP is uncertain

Files changed (1) hide show
  1. src/engines/fingerprint/engine.py +13 -12
src/engines/fingerprint/engine.py CHANGED
@@ -26,18 +26,19 @@ DETECTOR_CANDIDATES = [
26
  "Organika/sdxl-detector",
27
  "haywoodsloan/ai-image-detector-deploy",
28
  "dima806/deepfake_vs_real_image_detection",
 
29
  ]
30
 
31
  GENERATOR_PROMPTS: dict[str, str] = {
32
- "real": "a real photograph taken by a camera with natural lighting and film grain",
33
- "sora": "a Sora text-to-video frame with temporal coherence and photorealistic lighting",
34
- "runway": "a Runway Gen-2 frame with painterly dreamlike motion blur and color grading",
35
- "wav2lip": "a Wav2Lip face-swap with sharp lip boundary artifacts and texture inconsistency at mouth edges",
36
- "stable_diffusion": "an image generated by Stable Diffusion with painterly soft textures and dreamlike quality",
37
- "sdxl": "an image generated by SDXL with high resolution detail, sharp edges and crisp textures",
38
- "midjourney": "an image generated by Midjourney with cinematic dramatic lighting and extreme hyperdetail",
39
- "dall_e": "an image generated by DALL-E with clean flat illustration style and smooth gradients",
40
- "unknown_generative": "an AI-generated image with unidentifiable generator-specific artifacts and synthetic patterns",
41
  }
42
 
43
  FAKE_LABEL_KEYWORDS = (
@@ -185,7 +186,7 @@ class FingerprintEngine:
185
  if not _detectors:
186
  logger.warning("No fingerprint detectors loaded; using neutral fallback score.")
187
 
188
- detector_weights = [0.5, 0.3, 0.2]
189
  total_w = 0.0
190
  weighted_fake = 0.0
191
 
@@ -245,8 +246,8 @@ class FingerprintEngine:
245
  probs = logits.softmax(dim=0).cpu().numpy()
246
  max_prob = float(np.max(probs))
247
 
248
- # Low confidence attribution → unknown generator
249
- if max_prob < 0.25:
250
  generator = "unknown_generative"
251
  else:
252
  generator = list(GENERATOR_PROMPTS.keys())[int(np.argmax(probs))]
 
26
  "Organika/sdxl-detector",
27
  "haywoodsloan/ai-image-detector-deploy",
28
  "dima806/deepfake_vs_real_image_detection",
29
+ "umm-maybe/AI-image-detector",
30
  ]
31
 
32
  GENERATOR_PROMPTS: dict[str, str] = {
33
+ "real": "photograph with natural film grain, uneven organic noise, authentic lens distortion, and real-world lighting imperfections",
34
+ "sora": "AI video frame with unnaturally smooth temporal transitions, photorealistic but physically implausible motion, and over-consistent lighting",
35
+ "runway": "AI video frame with painterly color grading artifacts, dreamlike motion blur inconsistencies, and synthetic depth-of-field",
36
+ "wav2lip": "face with sharp unnatural lip boundary artifacts, texture discontinuity around the mouth region, and mismatched skin tone at lip edges",
37
+ "stable_diffusion": "image with soft overly-smooth skin, color bleeding at object edges, dreamlike over-saturation, and repeating background texture patterns",
38
+ "sdxl": "image with hyper-sharp commercial detail, perfect noise-free skin, unnaturally crisp edges, and over-rendered textures lacking real-world imperfection",
39
+ "midjourney": "image with dramatic cinematic vignette, fantasy color palette, exaggerated contrast, hyper-detailed surreal aesthetic, and painterly over-rendering",
40
+ "dall_e": "image with clean flat graphic style, smooth AI-blended gradients, slightly plastic surface quality, and uniformly lit commercial illustration look",
41
+ "unknown_generative": "image with subtle AI artifacts including unnatural smoothness, inconsistent frequency patterns, and synthetic pixel-level regularities absent in real photos",
42
  }
43
 
44
  FAKE_LABEL_KEYWORDS = (
 
186
  if not _detectors:
187
  logger.warning("No fingerprint detectors loaded; using neutral fallback score.")
188
 
189
+ detector_weights = [0.4, 0.3, 0.2, 0.1]
190
  total_w = 0.0
191
  weighted_fake = 0.0
192
 
 
246
  probs = logits.softmax(dim=0).cpu().numpy()
247
  max_prob = float(np.max(probs))
248
 
249
+ # Low confidence attribution → unknown generator (9 classes: chance=0.11, threshold=2.9×)
250
+ if max_prob < 0.32:
251
  generator = "unknown_generative"
252
  else:
253
  generator = list(GENERATOR_PROMPTS.keys())[int(np.argmax(probs))]