AuralGuard / src /sliding_localization.py
AyoPrince's picture
Upload folder using huggingface_hub
127b976 verified
Raw History Blame Contribute Delete
2.08 kB
from __future__ import annotations
from typing import List, Dict
import torch
import torch.nn.functional as F
@torch.no_grad()
def sliding_window_localization(
model,
wav: torch.Tensor,
sample_rate: int = 16000,
window_sec: float = 2.0,
hop_sec: float = 1.0,
threshold: float = 0.75,
device: str | torch.device = "cpu",
) -> List[Dict[str, float]]:
"""Localize suspicious regions with overlapping windows.
Args:
model: AuralGuardAASISTPP.
wav: Tensor [samples] or [1, samples].
"""
model.eval()
device = torch.device(device)
if wav.ndim == 2:
wav = wav.squeeze(0)
wav = wav.to(device).float()
window = int(window_sec * sample_rate)
hop = int(hop_sec * sample_rate)
if wav.numel() < window:
wav = F.pad(wav, (0, window - wav.numel()))
suspicious = []
for start in range(0, wav.numel() - window + 1, hop):
end = start + window
chunk = wav[start:end].unsqueeze(0)
outputs = model(chunk)
fake_score = torch.softmax(outputs["binary_logits"], dim=-1)[0, 1].item()
if fake_score >= threshold:
suspicious.append({
"start": round(start / sample_rate, 3),
"end": round(end / sample_rate, 3),
"fake_score": round(fake_score, 4),
})
return merge_overlapping_segments(suspicious)
def merge_overlapping_segments(segments: List[Dict[str, float]]) -> List[Dict[str, float]]:
"""Merge overlapping suspicious windows for cleaner output."""
if not segments:
return []
segments = sorted(segments, key=lambda x: x["start"])
merged = [segments[0].copy()]
for seg in segments[1:]:
last = merged[-1]
if seg["start"] <= last["end"]:
last["end"] = max(last["end"], seg["end"])
last["fake_score"] = round(max(last["fake_score"], seg["fake_score"]), 4)
else:
merged.append(seg.copy())
return merged