FAST-VQA and FasterVQA

repository·dev·Indexed 43 days ago

https://github.com/vqassessment/fast-vqa-and-fastervqa

Open-source, end-to-end video quality assessment (VQA) toolboxes providing efficient methods for evaluating video quality using fragment and 3D sampling. Supports multiple model types including FasterVQA, FasterVQA-MS, FasterVQA-MT, FAST-VQA, and FAST-VQA-M, with backbones such as Video Swin Transformer and ConvNext-I3D.

Tokens
4.1K
Snippets
12
Records
14
Agent score
56%

What's inside FAST-VQA

  1. Understand the modular architecture for development

    dev

    The project is designed with modular components to allow developers to modify backbone structures, sampling hyper-parameters, and loss functions.

    Data Preprocessing

    Core transformations are located in fastvqa/datasets/fusion_datasets.py. Specifically, examine the FusionDataset class and the get_spatial_and_temporal_samples function.

    Spatial Sampling Approaches:

    • fragments
    • resize
    • arp_resize (resizes while keeping the original Aspect Ratio)
    • crop
    • Note: These can be combined for multi-branch networks.

    Temporal Sampling Approaches:

    • SampleFrames (continuous frames, imported from MMAction2)
    • FragmentSampleFrames (discontinuous, fragment-like frames)

    Network Components

    • Backbones: Supports Video Swin Transformer (with GRPB or vanilla) and ConvNext-I3D (vanilla).
    • Heads: Supports the IP-NLR Head, which can generate local quality maps for videos.
  2. Finetune models on small datasets

    dev

    To finetune FAST-VQA-B or FAST-VQA-B-3D (FasterVQA) on smaller datasets, use the split_train.py script. This process automatically splits the dataset into 10 random train/test splits (using seed 42) and reports the best result on the test split.

    Supported Datasets:

    • KoNViD-1k
    • LIVE_VQC
    • CVD2014
    • LIVE-Qualcomm
    • YouTube-UGC

    Configuration Files: Finetune configuration files can be found in the ./options/finetune/ directory. For example:

    • fast-b for FAST-VQA-B
    • fast-3d for FasterVQA
    python split_train.py -opt [YOUR_OPTION_FILE]
  3. Train models on large datasets (LSVQ)

    dev

    To train the core models from scratch or using large-scale datasets like LSVQ, use the new_train.py script with the appropriate configuration file.

    • FAST-VQA-B: Use options/fast/fast-b.yml
    • FAST-VQA-M: Use options/fast/fast-m.yml
    • FasterVQA (FAST-VQA-B-3D): Use options/fast/f3dvqa-b.yml
    # Train FAST-VQA-B
    python new_train.py -o options/fast/fast-b.yml
    
    # Train FAST-VQA-M
    python new_train.py -o options/fast/fast-m.yml
    
    # Train FasterVQA
    python new_train.py -o options/fast/f3dvqa-b.yml
  4. Install FAST-VQA and FasterVQA

    dev

    You can install the project using two methods: installing dependencies from the requirements file or performing a direct editable installation.

    Method 1: Install Dependencies Ensure you have the required packages listed in requirements.txt.

    Method 2: Direct Editable Install Clone the repository and install it in editable mode (-e). This is recommended if you intend to customize the package or import your own version.

    System Requirements:

    • Python 3.8.8
    • Torch 1.10.2
    • Torchvision 0.11.3
    • decord module (used for reading original videos without manual transforms)
    # Method 1
    pip install -r requirements.txt
    
    # Method 2
    git clone htps://github.com/QualityAssessment/FAST-VQA-and-FasterVQA.git
    cd FAST-VQA-and-FasterVQA
    pip install -e .
  5. Infer video quality for a single MP4 video

    dev

    You can perform inference on a single MP4 video using the vqa.py script. The script outputs a quality score rescaled between [0, 1] using a sigmoid function.

    Score Interpretation:

    • Near 0: Extremely bad quality
    • 0.25: Bad quality
    • 0.5: Fair quality
    • 0.75: Good quality
    • Near 1.0: Extremely good quality

    Available Model Types (-m):

    • FasterVQA (and its efficient versions: FasterVQA-MS, FasterVQA-MT)
    • FAST-VQA (and its efficient version: FAST-VQA-M)
    python vqa.py -m [MODEL_TYPE] -v [YOUR_INPUT_FILE_PATH]
  6. Run a Quick Benchmark

    dev

    To perform a quick benchmark of the video quality assessment models, follow these three steps:

    1. Get Pretrained Weights: Download the weights corresponding to your desired model version (e.g., FAST-VQA-B, FasterVQA, or FAST-VQA-M). Ensure you use the correct .yml configuration file associated with the weights.
    2. Download Datasets: Obtain the required datasets such as LSVQ, KoNViD-1k, or LIVE-VQC.
    3. Execute Benchmark: Run the new_test.py script using your chosen options file.

    Model Weight Reference Table:

    NameConfig FileModel Weight Link
    FAST-VQA-B (ECCV2022)options/fast/fast-b.ymlDownload
    FasterVQA (:sparkles: New!)options/fast/f3dvqa-b.ymlDownload
    FAST-VQA-M (ECCV2022)options/fast/fast-m.ymlDownload
    FAST-VQA-B-From-Scratchoptions/fast/fast-b.ymlDownload
    FAST-VQA-B-3D-From-Scratchoptions/fast/f3dvqa-b.ymlDownload
    python new_test.py -o [YOUR_OPTIONS]
  7. Initialize BaseEvaluator for 'fast' or 'faster' models

    dev

    For more granular control, you can manually instantiate a BaseEvaluator. The configuration depends on whether you are using the fast or faster architecture.

    • fast: Uses a standard backbone.
    • faster: Requires a backbone dictionary defining window_size and frag_biases.

    When loading checkpoints, note that the weights may require a key transformation where 'cls' is replaced with 'vqa' in the state dictionary keys.

    from fastvqa.models import BaseEvaluator
    import torch
    from collections import OrderedDict
    
    model_type = 'fast' # or 'faster'
    device = 'cuda'
    
    # Configure backbone for 'faster' model
    backbone = dict(window_size=(4,4,4), frag_biases=[False,False,True,False]) if model_type=='faster' else dict()
    model = BaseEvaluator(backbone=backbone).to(device)
    
    # Load and transform checkpoint
    load_path = f'pretrained_weights/{model_type}_vqa_v0_3.pth'
    state_dict = torch.load(load_path, map_location='cpu')
    
    if 'state_dict' in state_dict:
        state_dict = state_dict['state_dict']
        i_state_dict = OrderedDict()
        for key, value in state_dict.items():
            if 'cls' in key:
                tkey = key.replace('cls', 'vqa')
                i_state_dict[tkey] = value
            else:
                i_state_dict[key] = value
        model.load_state_dict(i_state_dict)
  8. Calculate pyramid ensemble coefficients

    dev

    The pyramid_ensemble_coefficients function evaluates the performance of an ensemble of varying sizes (from 1 to the total number of results) using a sliding window approach.

    For each ensemble size i, it calculates the average of four metrics across all possible contiguous windows of that size:

    1. Spearman Rank Correlation (spearmanr)
    2. Pearson Correlation (pearsonr)
    3. Kendall Tau (kendallr)
    4. RMSE (Root Mean Square Error)

    Input results should be a list of dictionaries where each dictionary contains 'pr_labels' (predicted labels) and 'gt_label' (ground truth label).

    def pyramid_ensemble_coefficients(results):
        ens_result_len = results[0].get('pr_labels').shape[0]
        gt_labels = [r['gt_label'] for r in results]
        p_results = defaultdict()
    
        for i in range(1, ens_result_len + 1):
            scores = np.zeros(4)
            for j in range(ens_result_len - i + 1):
                pr_labels = [np.mean(r['pr_labels'][j:(j+i)]) for r in results]
                pr_labels = rescale(pr_labels, gt_labels)
                scores += np.array([
                    spearmanr(gt_labels, pr_labels)[0], 
                    pearsonr(gt_labels, pr_labels)[0], 
                    kendallr(gt_labels, pr_labels)[0], 
                    np.sqrt(((gt_labels - pr_labels) ** 2).mean())
                ])
            scores /= ens_result_len - i + 1
            p_results[i] = scores
    
        return p_results
  9. Calculate pyramid ensemble standard deviations

    dev

    The pyramid_ensemble_stds function measures the stability/variance of the ensemble predictions. It calculates the mean standard deviation of the predicted labels across different ensemble window sizes.

    It returns a dictionary s_results where keys are the ensemble size i and values are an array containing the mean standard deviation across two different axes (typically representing different dimensions of the prediction array).

    def pyramid_ensemble_stds(results):
        ens_result_len = results[0].get('pr_labels').shape[0]
        gt_labels = [r['gt_label'] for r in results]
        s_results = defaultdict()
    
        for i in range(1, ens_result_len + 1):
            all_pr_labels = []
            stds = np.zeros(2)
    
            for j in range(ens_result_len - i + 1):
                pr_labels = [np.mean(r['pr_labels'][j:(j+i)]) for r in results]
                pr_labels = rescale(pr_labels, gt_labels)
                all_pr_labels.append(pr_labels)
    
            all_pr_labels = np.stack(all_pr_labels, 1)
            for q in range(2):
                stds[q] = np.mean(np.std(all_pr_labels, q))
            s_results[i] = stds
    
        return s_results
  10. Rescale predicted labels to ground truth distribution

    dev

    The rescale function adjusts the distribution of predicted labels (pr) to match the mean and standard deviation of ground truth labels (gt). This is useful for normalizing scores before calculating correlation metrics.

    If gt is not provided, the function performs standard score normalization (z-score) on pr using its own mean and standard deviation.

    def rescale(pr, gt=None):
        if gt is None:
            pr = ((pr - np.mean(pr)) / np.std(pr))
        else:
            pr = ((pr - np.mean(pr)) / np.std(pr)) * np.std(gt) + np.mean(gt)
        return pr
  11. Extract spatial-temporal attention and quality maps

    dev

    The BaseEvaluator provides a forward_with_attention method that returns both the quality results and the attention maps used for localization.

    • demo_result: The quality scores per fragment. Reshape this to (-1, H, W) to align with spatial dimensions.
    • demo_attention: The attention weights. These often require reshaping (e.g., to (64, 7, 7)) and potentially rolling/shifting to align with the spatial-temporal structure of the video fragments.
    # Assuming 'model' is a BaseEvaluator and 'vfrag' is a video tensor
    demo_result, demo_attention = model.forward_with_attention(vfrag)
    
    # Reshape results for spatial analysis
    demo_result = demo_result.reshape((-1,) + demo_result.shape[-2:])
    
    # Calculate mean score
    score = torch.mean(demo_result)
    print(f'Quality score: {score.item()}')