CoolFace
Apppublic

Skylorjustine/Video-Action-Recognition

sourceHugging Faceupdated 11mo agoView on Hugging Face
0likes
debug_tensor_fix.py237 linesDownload Raw Back to root
1#!/usr/bin/env python32"""3Debug script to test and verify the tensor creation fix.4This script isolates the problematic code and tests various scenarios.5"""6 7import sys8import tempfile9from pathlib import Path10import logging11import numpy as np12from PIL import Image13 14# Configure detailed logging15logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')16 17def create_test_frames(num_frames=8, size=(224, 224)):18    """Create synthetic test frames to simulate video processing."""19    frames = []20    for i in range(num_frames):21        # Create a simple gradient image22        img_array = np.zeros((*size, 3), dtype=np.uint8)23 24        # Add some variation between frames25        gradient = np.linspace(0, 255, size[0]).astype(np.uint8)26        for j in range(3):  # RGB channels27            img_array[:, :, j] = gradient + (i * 10) % 25628 29        # Convert to PIL Image30        frame = Image.fromarray(img_array, 'RGB')31        frames.append(frame)32 33    return frames34 35def test_processor_approaches():36    """Test different approaches to fix the tensor creation issue."""37 38    print("๐Ÿ” Testing Tensor Creation Fix")39    print("=" * 50)40 41    try:42        from transformers import AutoImageProcessor, TimesformerForVideoClassification43        import torch44    except ImportError as e:45        print(f"โŒ Missing dependencies: {e}")46        return False47 48    # Load processor (but not full model to save time/memory)49    try:50        processor = AutoImageProcessor.from_pretrained("facebook/timesformer-base-finetuned-k400")51        print("โœ… Processor loaded successfully")52    except Exception as e:53        print(f"โŒ Failed to load processor: {e}")54        return False55 56    # Test with different frame scenarios57    test_scenarios = [58        {"name": "Standard 8 frames", "frames": 8, "size": (224, 224)},59        {"name": "Different count (6 frames)", "frames": 6, "size": (224, 224)},60        {"name": "Different size frames", "frames": 8, "size": (256, 256)},61        {"name": "Single frame", "frames": 1, "size": (224, 224)},62    ]63 64    success_count = 065 66    for scenario in test_scenarios:67        print(f"\n๐Ÿ“‹ Testing: {scenario['name']}")68        print("-" * 30)69 70        frames = create_test_frames(scenario["frames"], scenario["size"])71        required_frames = 8  # TimeSformer default72 73        # Apply the same logic as in our fix74        if len(frames) != required_frames:75            print(f"โš ๏ธ  Frame count mismatch: {len(frames)} vs {required_frames}")76            if len(frames) < required_frames:77                frames.extend([frames[-1]] * (required_frames - len(frames)))78                print(f"๐Ÿ”ง Padded to {len(frames)} frames")79            else:80                frames = frames[:required_frames]81                print(f"๐Ÿ”ง Truncated to {len(frames)} frames")82 83        # Ensure consistent frame sizes84        if frames:85            target_size = (224, 224)  # Standard size for TimeSformer86            frames = [frame.resize(target_size) if frame.size != target_size else frame for frame in frames]87            print(f"๐Ÿ”ง Normalized all frames to {target_size}")88 89        # Test different processor approaches90        approaches = [91            ("Direct with padding", lambda: processor(images=frames, return_tensors="pt", padding=True)),92            ("List wrapped with padding", lambda: processor(images=[frames], return_tensors="pt", padding=True)),93            ("Direct without padding", lambda: processor(images=frames, return_tensors="pt")),94            ("Manual tensor creation", lambda: create_manual_tensor(frames, processor)),95        ]96 97        for approach_name, approach_func in approaches:98            try:99                print(f"  ๐Ÿงช Trying: {approach_name}")100                inputs = approach_func()101 102                # Check tensor properties103                if 'pixel_values' in inputs:104                    tensor = inputs['pixel_values']105                    print(f"    โœ… Success! Tensor shape: {tensor.shape}")106                    print(f"    ๐Ÿ“Š Tensor dtype: {tensor.dtype}")107                    print(f"    ๐Ÿ“ˆ Tensor range: [{tensor.min():.3f}, {tensor.max():.3f}]")108                    success_count += 1109                    break110                else:111                    print(f"    โŒ No pixel_values in output: {inputs.keys()}")112 113            except Exception as e:114                print(f"    โŒ Failed: {str(e)[:100]}...")115                continue116        else:117            print(f"  ๐Ÿ’ฅ All approaches failed for {scenario['name']}")118 119    print(f"\n๐Ÿ“Š Summary: {success_count}/{len(test_scenarios)} scenarios passed")120    return success_count == len(test_scenarios)121 122def create_manual_tensor(frames, processor):123    """Manual tensor creation as final fallback."""124    if not frames:125        raise ValueError("No frames provided")126 127    frame_arrays = []128    for frame in frames:129        # Ensure RGB mode130        if frame.mode != 'RGB':131            frame = frame.convert('RGB')132        # Resize to standard size133        frame = frame.resize((224, 224))134        frame_array = np.array(frame)135        frame_arrays.append(frame_array)136 137    # Stack frames: (num_frames, height, width, channels)138    video_array = np.stack(frame_arrays)139 140    # Convert to tensor and normalize141    video_tensor = torch.tensor(video_array, dtype=torch.float32) / 255.0142 143    # Rearrange dimensions for TimeSformer: (batch, channels, num_frames, height, width)144    video_tensor = video_tensor.permute(3, 0, 1, 2).unsqueeze(0)145 146    return {'pixel_values': video_tensor}147 148def test_video_processing():149    """Test with actual video processing simulation."""150    print(f"\n๐ŸŽฌ Testing Video Processing Pipeline")151    print("=" * 50)152 153    try:154        # Create a temporary "video" by saving frames as images155        with tempfile.TemporaryDirectory() as tmp_dir:156            tmp_path = Path(tmp_dir)157 158            # Create test frames and save them159            frames = create_test_frames(8, (640, 480))  # Different size to test resizing160            frame_paths = []161 162            for i, frame in enumerate(frames):163                frame_path = tmp_path / f"frame_{i:03d}.jpg"164                frame.save(frame_path)165                frame_paths.append(frame_path)166 167            print(f"โœ… Created {len(frame_paths)} test frames")168 169            # Load frames back (simulating video reading)170            loaded_frames = []171            for frame_path in frame_paths:172                frame = Image.open(frame_path)173                loaded_frames.append(frame)174 175            print(f"โœ… Loaded {len(loaded_frames)} frames")176 177            # Test processing178            return test_single_scenario(loaded_frames, "Video simulation")179 180    except Exception as e:181        print(f"โŒ Video processing test failed: {e}")182        return False183 184def test_single_scenario(frames, scenario_name):185    """Test a single scenario with comprehensive error handling."""186    print(f"\n๐ŸŽฏ Testing scenario: {scenario_name}")187 188    try:189        from transformers import AutoImageProcessor190        import torch191 192        processor = AutoImageProcessor.from_pretrained("facebook/timesformer-base-finetuned-k400")193 194        # Apply our fix logic195        required_frames = 8196 197        if len(frames) != required_frames:198            if len(frames) < required_frames:199                frames.extend([frames[-1]] * (required_frames - len(frames)))200            else:201                frames = frames[:required_frames]202 203        # Normalize frame sizes204        target_size = (224, 224)205        frames = [frame.resize(target_size) if frame.size != target_size else frame for frame in frames]206 207        # Try our primary approach208        inputs = processor(images=frames, return_tensors="pt", padding=True)209 210        print(f"โœ… Success! Tensor shape: {inputs['pixel_values'].shape}")211        return True212 213    except Exception as e:214        print(f"โŒ Failed: {e}")215        return False216 217if __name__ == "__main__":218    print("๐Ÿ› Tensor Creation Debug Suite")219    print("=" * 60)220 221    # Test 1: Processor approaches222    test1_passed = test_processor_approaches()223 224    # Test 2: Video processing simulation225    test2_passed = test_video_processing()226 227    print(f"\n๐Ÿ Final Results:")228    print(f"   Processor tests: {'โœ… PASSED' if test1_passed else 'โŒ FAILED'}")229    print(f"   Video tests: {'โœ… PASSED' if test2_passed else 'โŒ FAILED'}")230 231    if test1_passed and test2_passed:232        print(f"\n๐ŸŽ‰ All tests passed! The tensor fix should work correctly.")233        sys.exit(0)234    else:235        print(f"\n๐Ÿ’ฅ Some tests failed. Check the logs above for details.")236        sys.exit(1)237