Deepfake Authenticator commited on
Commit Β·
5840c62
1
Parent(s): 5178cb9
revert: Back to 0.58 threshold and original 55/45 ensemble weighting
Browse files- backend/detector.py +10 -18
backend/detector.py
CHANGED
|
@@ -450,10 +450,7 @@ class DecisionAgent:
|
|
| 450 |
if not fake_probs:
|
| 451 |
results.append(self._heuristic_predict(crop))
|
| 452 |
elif len(fake_probs) == 2:
|
| 453 |
-
|
| 454 |
-
# Model 1 is more reliable, give it more weight
|
| 455 |
-
ensemble_score = fake_probs[0] * 0.60 + fake_probs[1] * 0.40
|
| 456 |
-
results.append(ensemble_score)
|
| 457 |
else:
|
| 458 |
results.append(float(np.mean(fake_probs)))
|
| 459 |
|
|
@@ -627,7 +624,7 @@ class DecisionAgent:
|
|
| 627 |
# Agent 4: Report Generator Agent
|
| 628 |
# βββββββββββββββββββββββββββββββββββββββββββββ
|
| 629 |
class ReportGeneratorAgent:
|
| 630 |
-
BASE_THRESHOLD = 0.
|
| 631 |
|
| 632 |
def generate(self, analysis: dict, metadata: dict,
|
| 633 |
audio: dict | None = None,
|
|
@@ -659,16 +656,12 @@ class ReportGeneratorAgent:
|
|
| 659 |
|
| 660 |
# ββ Adaptive threshold ββββββββββββββββββββββββββββββββββββββββββββ
|
| 661 |
threshold = self.BASE_THRESHOLD
|
| 662 |
-
|
| 663 |
-
|
| 664 |
-
|
| 665 |
-
|
| 666 |
-
|
| 667 |
-
|
| 668 |
-
threshold -= 0.02
|
| 669 |
-
elif consistency < 0.40:
|
| 670 |
-
# Low consistency - be more cautious
|
| 671 |
-
threshold += 0.08
|
| 672 |
|
| 673 |
visual_fake = prob >= threshold
|
| 674 |
|
|
@@ -687,8 +680,7 @@ class ReportGeneratorAgent:
|
|
| 687 |
elif not visual_fake and not audio_fake:
|
| 688 |
is_fake = False
|
| 689 |
elif visual_fake and not audio_fake:
|
| 690 |
-
|
| 691 |
-
is_fake = prob >= (threshold + 0.06)
|
| 692 |
else:
|
| 693 |
is_fake = audio_prob >= 0.75
|
| 694 |
calibrated = self._calibrate(prob)
|
|
@@ -723,7 +715,7 @@ class ReportGeneratorAgent:
|
|
| 723 |
return float(np.clip(conf, 0.88, 0.99))
|
| 724 |
|
| 725 |
def _build_details(self, analysis, metadata, prob, is_fake,
|
| 726 |
-
threshold=0.
|
| 727 |
details = []
|
| 728 |
frame_scores = analysis.get("frame_scores", [])
|
| 729 |
frames_with_faces = analysis.get("frames_with_faces", 0)
|
|
|
|
| 450 |
if not fake_probs:
|
| 451 |
results.append(self._heuristic_predict(crop))
|
| 452 |
elif len(fake_probs) == 2:
|
| 453 |
+
results.append(fake_probs[0] * 0.55 + fake_probs[1] * 0.45)
|
|
|
|
|
|
|
|
|
|
| 454 |
else:
|
| 455 |
results.append(float(np.mean(fake_probs)))
|
| 456 |
|
|
|
|
| 624 |
# Agent 4: Report Generator Agent
|
| 625 |
# βββββββββββββββββββββββββββββββββββββββββββββ
|
| 626 |
class ReportGeneratorAgent:
|
| 627 |
+
BASE_THRESHOLD = 0.58 # Original optimal threshold
|
| 628 |
|
| 629 |
def generate(self, analysis: dict, metadata: dict,
|
| 630 |
audio: dict | None = None,
|
|
|
|
| 656 |
|
| 657 |
# ββ Adaptive threshold ββββββββββββββββββββββββββββββββββββββββββββ
|
| 658 |
threshold = self.BASE_THRESHOLD
|
| 659 |
+
if consistency >= 0.70 and coverage >= 0.50:
|
| 660 |
+
threshold -= 0.06
|
| 661 |
+
elif consistency >= 0.55:
|
| 662 |
+
threshold -= 0.03
|
| 663 |
+
elif consistency < 0.35:
|
| 664 |
+
threshold += 0.07
|
|
|
|
|
|
|
|
|
|
|
|
|
| 665 |
|
| 666 |
visual_fake = prob >= threshold
|
| 667 |
|
|
|
|
| 680 |
elif not visual_fake and not audio_fake:
|
| 681 |
is_fake = False
|
| 682 |
elif visual_fake and not audio_fake:
|
| 683 |
+
is_fake = prob >= (threshold + 0.05)
|
|
|
|
| 684 |
else:
|
| 685 |
is_fake = audio_prob >= 0.75
|
| 686 |
calibrated = self._calibrate(prob)
|
|
|
|
| 715 |
return float(np.clip(conf, 0.88, 0.99))
|
| 716 |
|
| 717 |
def _build_details(self, analysis, metadata, prob, is_fake,
|
| 718 |
+
threshold=0.58, metadata_result=None) -> list[str]:
|
| 719 |
details = []
|
| 720 |
frame_scores = analysis.get("frame_scores", [])
|
| 721 |
frames_with_faces = analysis.get("frames_with_faces", 0)
|