CoolFace
Apppublic

jone/Music_Source_Separation

sourceHugging Faceupdated 4y agoView on Hugging Face
3likes
batch_data_preprocessors.py142 linesDownload Raw Back to data
1from typing import Dict, List2 3import torch4 5 6class BasicBatchDataPreprocessor:7    def __init__(self, target_source_types: List[str]):8        r"""Batch data preprocessor. Used for preparing mixtures and targets for9        training. If there are multiple target source types, the waveforms of10        those sources will be stacked along the channel dimension.11 12        Args:13            target_source_types: List[str], e.g., ['vocals', 'bass', ...]14        """15        self.target_source_types = target_source_types16 17    def __call__(self, batch_data_dict: Dict) -> List[Dict]:18        r"""Format waveforms and targets for training.19 20        Args:21            batch_data_dict: dict, e.g., {22                'mixture': (batch_size, channels_num, segment_samples),23                'vocals': (batch_size, channels_num, segment_samples),24                'bass': (batch_size, channels_num, segment_samples),25                ...,26            }27 28        Returns:29            input_dict: dict, e.g., {30                'waveform': (batch_size, channels_num, segment_samples),31            }32            output_dict: dict, e.g., {33                'target': (batch_size, target_sources_num * channels_num, segment_samples)34            }35        """36        mixtures = batch_data_dict['mixture']37        # mixtures: (batch_size, channels_num, segment_samples)38 39        # Concatenate waveforms of multiple targets along the channel axis.40        targets = torch.cat(41            [batch_data_dict[source_type] for source_type in self.target_source_types],42            dim=1,43        )44        # targets: (batch_size, target_sources_num * channels_num, segment_samples)45 46        input_dict = {'waveform': mixtures}47        target_dict = {'waveform': targets}48 49        return input_dict, target_dict50 51 52class ConditionalSisoBatchDataPreprocessor:53    def __init__(self, target_source_types: List[str]):54        r"""Conditional single input single output (SISO) batch data55        preprocessor. Select one target source from several target sources as56        training target and prepare the corresponding conditional vector.57 58        Args:59            target_source_types: List[str], e.g., ['vocals', 'bass', ...]60        """61        self.target_source_types = target_source_types62 63    def __call__(self, batch_data_dict: Dict) -> List[Dict]:64        r"""Format waveforms and targets for training.65 66        Args:67            batch_data_dict: dict, e.g., {68                'mixture': (batch_size, channels_num, segment_samples),69                'vocals': (batch_size, channels_num, segment_samples),70                'bass': (batch_size, channels_num, segment_samples),71                ...,72            }73 74        Returns:75            input_dict: dict, e.g., {76                'waveform': (batch_size, channels_num, segment_samples),77                'condition': (batch_size, target_sources_num),78            }79            output_dict: dict, e.g., {80                'target': (batch_size, channels_num, segment_samples)81            }82        """83 84        batch_size = len(batch_data_dict['mixture'])85        target_sources_num = len(self.target_source_types)86 87        assert (88            batch_size % target_sources_num == 089        ), "Batch size should be \90            evenly divided by target sources number."91 92        mixtures = batch_data_dict['mixture']93        # mixtures: (batch_size, channels_num, segment_samples)94 95        conditions = torch.zeros(batch_size, target_sources_num).to(mixtures.device)96        # conditions: (batch_size, target_sources_num)97 98        targets = []99 100        for n in range(batch_size):101 102            k = n % target_sources_num  # source class index103            source_type = self.target_source_types[k]104 105            targets.append(batch_data_dict[source_type][n])106 107            conditions[n, k] = 1108 109        # conditions will looks like:110        # [[1, 0, 0, 0],111        #  [0, 1, 0, 0],112        #  [0, 0, 1, 0],113        #  [0, 0, 0, 1],114        #  [1, 0, 0, 0],115        #  [0, 1, 0, 0],116        #  ...,117        # ]118 119        targets = torch.stack(targets, dim=0)120        # targets: (batch_size, channels_num, segment_samples)121 122        input_dict = {123            'waveform': mixtures,124            'condition': conditions,125        }126 127        target_dict = {'waveform': targets}128 129        return input_dict, target_dict130 131 132def get_batch_data_preprocessor_class(batch_data_preprocessor_type: str) -> object:133    r"""Get batch data preprocessor class."""134    if batch_data_preprocessor_type == 'BasicBatchDataPreprocessor':135        return BasicBatchDataPreprocessor136 137    elif batch_data_preprocessor_type == 'ConditionalSisoBatchDataPreprocessor':138        return ConditionalSisoBatchDataPreprocessor139 140    else:141        raise NotImplementedError142