CoolFace
Apppublic

Hamzah-ALQadasi/Video_Authenticity.Anamoly_Detection.Temporal_Modeling

sourceHugging Faceapache-2.0updated 10mo agoView on Hugging Face
0likes
outliers_removal_algorithm.py212 linesDownload Raw Back to root
1#!/usr/bin/env python32"""3Outlier removal algorithm for video frame embeddings using DBSCAN.4 5Reads embeddings, detects outliers, and exports predictions to CSV files.6GPU acceleration is automatically detected and used if available.7 8Usage:9  # Process CLIP embeddings from outlier_artifacts10  python outliers_removal_algorithm.py --embeddings-dir ./outlier_artifacts/embeddings --output-dir ./outlier_artifacts/cleaned_CSVs --model-type clip11 12  # Process DINOv2 embeddings13  python outliers_removal_algorithm.py --embeddings-dir ./outlier_artifacts/embeddings --output-dir ./outlier_artifacts/cleaned_CSVs --model-type dinov214 15  # Process ResNet18 embeddings16  python outliers_removal_algorithm.py --embeddings-dir ./outlier_artifacts/embeddings --output-dir ./outlier_artifacts/cleaned_CSVs --model-type resnet1817 18  # Custom DBSCAN parameters with CLIP embeddings19  python outliers_removal_algorithm.py --embeddings-dir ./outlier_artifacts/embeddings --output-dir ./outlier_artifacts/cleaned_CSVs --model-type clip --eps 0.45 --min-samples 5020 21  # Filter to specific action category22  python outliers_removal_algorithm.py --embeddings-dir ./outlier_artifacts/embeddings --output-dir ./outlier_artifacts/cleaned_CSVs --model-type clip --action-filter Crawling23 24  # Limit processing to first 10 videos25  python outliers_removal_algorithm.py --embeddings-dir ./outlier_artifacts/embeddings --output-dir ./outlier_artifacts/cleaned_CSVs --model-type clip --max-videos 1026 27Note: To generate cleaned videos from predictions, use generate_cleaned_videos_from_predictions.py28"""29 30import os31import glob32import csv33import argparse34import numpy as np35import torch36from pathlib import Path37 38try:39    import cupy as cp40    from cuml.cluster import DBSCAN as cuDBSCAN41    CUML_AVAILABLE = True42except ImportError:43    CUML_AVAILABLE = False44 45from sklearn.cluster import DBSCAN as skDBSCAN46 47# Automatically detect GPU availability48USE_GPU = CUML_AVAILABLE and torch.cuda.is_available()49 50 51def to_numpy(x):52    """Convert tensor or array to numpy float32."""53    if isinstance(x, torch.Tensor):54        x = x.detach().cpu().numpy()55    return np.asarray(x, dtype=np.float32)56 57 58def dbscan_outliers(X, eps=0.55, min_samples=10):59    """60    Detect outliers using DBSCAN (noise points).61 62    Args:63        X: Feature matrix (N, D)64        eps: DBSCAN epsilon parameter65        min_samples: DBSCAN minimum samples parameter66 67    Returns:68        Boolean array of shape (N,) where True = outlier69    """70    X = to_numpy(X)71 72    # Ensure X is 2D: (n_samples, n_features)73    if X.ndim > 2:74        X = X.reshape(X.shape[0], -1)75 76    if USE_GPU:77        labels = cuDBSCAN(eps=eps, min_samples=min_samples).fit_predict(cp.asarray(X)).get()78    else:79        labels = skDBSCAN(eps=eps, min_samples=min_samples, n_jobs=-1).fit_predict(X)80    return labels == -181 82 83def extract_action_name(filename, model_type):84    """Extract action category from embedding filename based on model type."""85    name = os.path.basename(filename)86    suffix = f'_{model_type}_embeddings'87    name = name.replace(suffix + '.pt', '').replace(suffix + '.pth', '')88    return name89 90 91def process_all_embeddings(emb_dir, eps, min_samples, output_dir, model_type='clip',92                           max_videos=None, action_filter=None):93    """94    Process all embeddings and export predictions to CSV files.95 96    Args:97        emb_dir: Directory containing embedding .pt files98        eps: DBSCAN epsilon parameter99        min_samples: DBSCAN minimum samples parameter100        output_dir: Directory to save CSV predictions101        model_type: Model type to load ('clip', 'dinov2', or 'resnet18')102        max_videos: Limit processing to first N videos103        action_filter: Filter to specific action category104    """105    # Filter files by model type (e.g., *_clip_embeddings.pt, *_dinov2_embeddings.pt, or *_resnet18_embeddings.pt)106    pattern = f"*_{model_type}_embeddings.pt"107    pt_files = sorted(glob.glob(os.path.join(emb_dir, pattern)))108 109    if action_filter:110        pt_files = [f for f in pt_files if action_filter.lower() in os.path.basename(f).lower()]111        print(f"Filtering to action: {action_filter}")112        print(f"Found {len(pt_files)} matching file(s)")113 114    # Create output directory115    output_path = Path(output_dir)116    output_path.mkdir(exist_ok=True, parents=True)117 118    print("=" * 80)119    print("OUTLIER REMOVAL ALGORITHM - DBSCAN")120    print("=" * 80)121    print(f"Model type: {model_type.upper()}")122    print(f"GPU Acceleration: {'Enabled (cuML)' if USE_GPU else 'Disabled (CPU/sklearn)'}")123    print(f"Embeddings dir: {emb_dir}")124    print(f"Output dir: {output_dir}")125    print(f"DBSCAN parameters: eps={eps}, min_samples={min_samples}")126    print(f"Total embedding files: {len(pt_files)}")127    print("=" * 80)128 129    total_videos = 0130 131    for pt_path in pt_files:132        data = torch.load(pt_path, map_location="cpu")133        action_name = extract_action_name(pt_path, model_type)134        print(f"Processing action: {action_name}")135 136        # Create CSV for this action137        csv_path = output_path / f"{action_name}.csv"138 139        with open(csv_path, 'w', newline='') as csvfile:140            writer = csv.writer(csvfile)141            writer.writerow(['video_id', 'predicted_outliers_list'])142 143            for video_name, video_data in data.items():144                if max_videos and total_videos >= max_videos:145                    break146 147                total_videos += 1148                embeddings = video_data["embeddings"]149 150                # Run DBSCAN outlier detection151                predictions = dbscan_outliers(embeddings, eps=eps, min_samples=min_samples)152 153                # Convert boolean array to list of outlier indices154                outlier_indices = np.where(predictions)[0].tolist()155                outliers_str = ",".join(map(str, outlier_indices))156 157                # Write to CSV158                writer.writerow([video_name, outliers_str])159 160                num_outliers = predictions.sum()161                num_frames = len(embeddings)162 163        if max_videos and total_videos >= max_videos:164            break165 166    print("\n" + "=" * 80)167    print("PROCESSING COMPLETE")168    print("=" * 80)169    print(f"Total videos processed: {total_videos}")170    print(f"CSV files saved to: {output_path.absolute()}")171    print("\nNext step: Use generate_cleaned_videos_from_predictions.py to create cleaned videos")172    print("=" * 80)173 174 175def main():176    parser = argparse.ArgumentParser(177        description="Outlier removal algorithm using DBSCAN: detect outliers and export predictions to CSV"178    )179 180    parser.add_argument("--embeddings-dir", required=True,181                       help="Directory containing embedding .pt files")182    parser.add_argument("--output-dir", default="./outlier_artifacts/cleaned_CSVs",183                       help="Directory to save prediction CSV files")184    parser.add_argument("--model-type", type=str, choices=['clip', 'dinov2', 'resnet18'], default='clip',185                       help="Model type to load: 'clip', 'dinov2', or 'resnet18' (default: clip)")186    parser.add_argument("--max-videos", type=int,187                       help="Limit processing to first N videos")188    parser.add_argument("--action-filter",189                       help="Filter to specific action category (e.g., 'Crawling')")190 191    # DBSCAN parameters192    parser.add_argument("--eps", type=float, default=0.5,193                       help="DBSCAN: Epsilon parameter")194    parser.add_argument("--min-samples", type=int, default=40,195                       help="DBSCAN: Minimum samples parameter")196 197    args = parser.parse_args()198 199    process_all_embeddings(200        emb_dir=args.embeddings_dir,201        eps=args.eps,202        min_samples=args.min_samples,203        output_dir=args.output_dir,204        model_type=args.model_type,205        max_videos=args.max_videos,206        action_filter=args.action_filter207    )208 209 210if __name__ == "__main__":211    main()212