def test_shift_by_fraction(self): samples = np.array( [ [[0.75, 0.5, -0.25, -0.125], [0.9, 0.5, -0.25, -0.125]], [[1, 0.5, 0.26, 0.125], [1, 0.5, 0.25, 0.125]], ], dtype=np.float32, ) sample_rate = 16000 augment = Shift(min_shift=0.5, max_shift=0.5, shift_unit="fraction", p=1.0) processed_samples = augment( samples=torch.from_numpy(samples), sample_rate=sample_rate ).numpy() assert_almost_equal( processed_samples, np.array( [ [[-0.25, -0.125, 0.75, 0.5], [-0.25, -0.125, 0.9, 0.5]], [[0.26, 0.125, 1, 0.5], [0.25, 0.125, 1, 0.5]], ], dtype=np.float32, ), ) self.assertEqual(processed_samples.dtype, np.float32)
def test_shift_by_1_sample_without_rollover(self): samples = np.array( [ [[0.75, 0.5, -0.25, -0.125, 0.0], [0.9, 0.5, -0.25, -0.125, 0.0]], [[1, 0.5, 0.25, 0.125, 0.0], [1, 0.5, 0.25, 0.125, 0.06]], ], dtype=np.float32, ) sample_rate = 16000 augment = Shift( min_shift=1, max_shift=1, shift_unit="samples", rollover=False, p=1.0 ) processed_samples = augment( samples=torch.from_numpy(samples), sample_rate=sample_rate ).numpy() assert_almost_equal( processed_samples, np.array( [ [[0.0, 0.75, 0.5, -0.25, -0.125], [0.0, 0.9, 0.5, -0.25, -0.125]], [[0.0, 1, 0.5, 0.25, 0.125], [0.00, 1, 0.5, 0.25, 0.125]], ], dtype=np.float32, ), ) self.assertEqual(processed_samples.dtype, np.float32)
def test_negative_shift_by_2_samples(self): samples = np.array( [ [[0.75, 0.5, -0.25, -0.125, 0.0], [0.9, 0.5, -0.25, -0.125, 0.0]], [[1, 0.5, 0.25, 0.125, 0.0], [1, 0.5, 0.25, 0.125, 0.06]], ], dtype=np.float32, ) sample_rate = 16000 augment = Shift(min_shift=-2, max_shift=-2, shift_unit="samples", p=1.0) processed_samples = augment( samples=torch.from_numpy(samples), sample_rate=sample_rate ).numpy() assert_almost_equal( processed_samples, np.array( [ [[-0.25, -0.125, 0.0, 0.75, 0.5], [-0.25, -0.125, 0.0, 0.9, 0.5]], [[0.25, 0.125, 0.0, 1, 0.5], [0.25, 0.125, 0.06, 1, 0.5]], ], dtype=np.float32, ), ) self.assertEqual(processed_samples.dtype, np.float32)
def test_variability_within_batch(self): torch.manual_seed(42) samples = np.array( [[-0.25, -0.125, 0.0, 0.75, 0.5], [-0.25, -0.125, 0.0, 0.9, 0.5]], dtype=np.float32, ) samples = np.stack([samples] * 1000, axis=0) sample_rate = 16000 augment = Shift(min_shift=-1, max_shift=1, shift_unit="samples", p=1.0) processed_samples = augment( samples=torch.from_numpy(samples), sample_rate=sample_rate ).numpy() self.assertEqual(processed_samples.dtype, np.float32) applied_shift_counts = {-1: 0, 0: 0, 1: 0} for i in range(samples.shape[0]): applied_shift = None for shift in range(augment.min_shift, augment.max_shift + 1): if np.array_equal( np.roll(samples[i], shift, axis=-1), processed_samples[i] ): applied_shift = shift break self.assertIsNotNone(applied_shift) applied_shift_counts[applied_shift] += 1 for shift in range(augment.min_shift, augment.max_shift + 1): self.assertGreater(applied_shift_counts[shift], 50)
def test_shift_by_seconds_specify_sample_rate_in_both_init_and_forward(self): samples = np.array( [ [[0.75, 0.5, -0.25, -0.125], [0.9, 0.5, -0.25, -0.125]], [[1, 0.5, 0.26, 0.125], [1, 0.5, 0.25, 0.125]], ], dtype=np.float32, ) init_sample_rate = 42 forward_sample_rate = 1 augment = Shift( min_shift=-3, max_shift=-3, shift_unit="seconds", p=1.0, sample_rate=init_sample_rate, ) # If sample_rate is specified in both __init__ and forward, then the latter will be used processed_samples = augment( samples=torch.from_numpy(samples), sample_rate=forward_sample_rate ).numpy() assert_almost_equal( processed_samples, np.array( [ [[-0.125, 0.75, 0.5, -0.25], [-0.125, 0.9, 0.5, -0.25]], [[0.125, 1, 0.5, 0.26], [0.125, 1, 0.5, 0.25]], ], dtype=np.float32, ), ) self.assertEqual(processed_samples.dtype, np.float32)
def test_shift_by_seconds_specify_sample_rate_in_init(self): samples = np.array( [ [[0.75, 0.5, -0.25, -0.125], [0.9, 0.5, -0.25, -0.125]], [[1, 0.5, 0.26, 0.125], [1, 0.5, 0.25, 0.125]], ], dtype=np.float32, ) sample_rate = 1 augment = Shift( min_shift=-3, max_shift=-3, shift_unit="seconds", p=1.0, sample_rate=sample_rate, ) processed_samples = augment(samples=torch.from_numpy(samples)).numpy() assert_almost_equal( processed_samples, np.array( [ [[-0.125, 0.75, 0.5, -0.25], [-0.125, 0.9, 0.5, -0.25]], [[0.125, 1, 0.5, 0.26], [0.125, 1, 0.5, 0.25]], ], dtype=np.float32, ), ) self.assertEqual(processed_samples.dtype, np.float32)
def test_shift_by_1_sample_3dim(self, device_name): device = torch.device(device_name) samples = torch.arange(4)[None, None].repeat(2, 2, 1).to(device=device) samples[1] += 1 augment = Shift(min_shift=1, max_shift=1, shift_unit="samples", p=1.0) processed_samples = augment(samples) assert_almost_equal( processed_samples.cpu(), [[[3, 0, 1, 2], [3, 0, 1, 2]], [[4, 1, 2, 3], [4, 1, 2, 3]]], )
def test_shift_by_seconds_without_specifying_sample_rate(self): samples = torch.arange(4)[None, None].repeat(2, 2, 1) samples[1] += 1 augment = Shift(min_shift=-3, max_shift=-3, shift_unit="seconds", p=1.0) with pytest.raises(RuntimeError): augment(samples) with pytest.raises(RuntimeError): augment(samples, sample_rate=None)
def test_shift_by_1_sample_without_rollover(self): samples = torch.arange(4)[None, None].repeat(2, 2, 1) samples[1] += 1 augment = Shift(min_shift=1, max_shift=1, shift_unit="samples", rollover=False, p=1.0) processed_samples = augment(samples=samples) assert_almost_equal( processed_samples, [[[0, 0, 1, 2], [0, 0, 1, 2]], [[0, 1, 2, 3], [0, 1, 2, 3]]], )
def test_shift_by_fraction(self): samples = torch.arange(4)[None, None].repeat(2, 2, 1) samples[1] += 1 augment = Shift(min_shift=0.5, max_shift=0.5, shift_unit="fraction", rollover=True, p=1.0) processed_samples = augment(samples=samples) assert_almost_equal( processed_samples, [[[2, 3, 0, 1], [2, 3, 0, 1]], [[3, 4, 1, 2], [3, 4, 1, 2]]], )
def test_shift_by_seconds(self): samples = torch.arange(4)[None, None].repeat(2, 2, 1) samples[1] += 1 augment = Shift(min_shift=-2, max_shift=-2, shift_unit="seconds", p=1.0, sample_rate=1) processed_samples = augment(samples) assert_almost_equal( processed_samples, [[[2, 3, 0, 1], [2, 3, 0, 1]], [[3, 4, 1, 2], [3, 4, 1, 2]]], )
def test_shift_by_seconds_without_specifying_sample_rate(self): samples = np.array( [ [[0.75, 0.5, -0.25, -0.125], [0.9, 0.5, -0.25, -0.125]], [[1, 0.5, 0.26, 0.125], [1, 0.5, 0.25, 0.125]], ], dtype=np.float32, ) augment = Shift(min_shift=-3, max_shift=-3, shift_unit="seconds", p=1.0) with self.assertRaises(RuntimeError): _ = augment(samples=torch.from_numpy(samples)).numpy() with self.assertRaises(RuntimeError): _ = augment(samples=torch.from_numpy(samples), sample_rate=None).numpy()
def test_negative_shift_by_2_samples(self): samples = torch.arange(4)[None, None].repeat(2, 2, 1) samples[1] += 1 augment = Shift( min_shift=-2, max_shift=-2, shift_unit="samples", rollover=True, p=1.0, output_type="dict", ) processed_samples = augment(samples=samples).samples assert_almost_equal( processed_samples, [[[2, 3, 0, 1], [2, 3, 0, 1]], [[3, 4, 1, 2], [3, 4, 1, 2]]], )
def test_shift_by_1_sample_2dim(self): samples = np.array( [[0.75, 0.5, -0.25, -0.125, 0.77], [0.9, 0.5, -0.25, -0.125, 0.33]], dtype=np.float32, ) sample_rate = 16000 augment = Shift(min_shift=1, max_shift=1, shift_unit="samples", p=1.0) processed_samples = augment( samples=torch.from_numpy(samples), sample_rate=sample_rate ).numpy() assert_almost_equal( processed_samples, np.array( [[0.77, 0.75, 0.5, -0.25, -0.125], [0.33, 0.9, 0.5, -0.25, -0.125]], dtype=np.float32, ), ) self.assertEqual(processed_samples.dtype, np.float32)
def test_variability_within_batch(self): torch.manual_seed(42) samples = torch.arange(4)[None, None].repeat(1000, 2, 1) augment = Shift(min_shift=-1, max_shift=1, shift_unit="samples", p=1.0) processed_samples = augment(samples) applied_shift_counts = {-1: 0, 0: 0, 1: 0} for i in range(samples.shape[0]): applied_shift = None for shift in range(augment.min_shift, augment.max_shift + 1): rolled = np.roll(samples[i], shift, axis=1) if np.array_equal(rolled, processed_samples[i]): applied_shift = shift break assert applied_shift is not None applied_shift_counts[applied_shift] += 1 for shift in range(0, augment.max_shift + 1): assert applied_shift_counts[shift] > 50
def test_shift_by_seconds_specify_sample_rate_in_both_init_and_forward( self): samples = torch.arange(4)[None, None].repeat(2, 2, 1) samples[1] += 1 init_sample_rate = 1 forward_sample_rate = 2 augment = Shift( min_shift=1, max_shift=1, shift_unit="seconds", p=1.0, sample_rate=init_sample_rate, rollover=False, ) # If sample_rate is specified in both __init__ and forward, then the latter will be used processed_samples = augment(samples, sample_rate=forward_sample_rate) assert_almost_equal( processed_samples, [[[0, 0, 0, 1], [0, 0, 0, 1]], [[0, 0, 1, 2], [0, 0, 1, 2]]], )
# Differentiable transforms: AddBackgroundNoise(BG_NOISE_PATH, 20, p=1.0, output_type="dict"), ApplyImpulseResponse(IR_PATH, p=1.0, output_type="dict"), Compose( transforms=[ Gain(min_gain_in_db=-15.0, max_gain_in_db=5.0, p=1.0), PolarityInversion(p=1.0), ], output_type="dict", ), Gain(min_gain_in_db=-6.000001, max_gain_in_db=-6, p=1.0, output_type="dict"), PolarityInversion(p=1.0, output_type="dict"), Shift(p=1.0, output_type="dict"), # Non-differentiable transforms: # RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation: # [torch.DoubleTensor [1, 1, 5]], which is output 0 of IndexBackward, is at version 1; expected version 0 instead. # Hint: enable anomaly detection to find the operation that failed to compute its gradient, # with torch.autograd.set_detect_anomaly(True). pytest.param( HighPassFilter(p=1.0, output_type="dict"), marks=pytest.mark.skip("Not differentiable"), ), pytest.param( LowPassFilter(p=1.0, output_type="dict"), marks=pytest.mark.skip("Not differentiable"), ), pytest.param( PeakNormalization(p=1.0, output_type="dict"),
IR_PATH = TEST_FIXTURES_DIR / "ir" @pytest.mark.parametrize( "augment", [ # Differentiable transforms: AddBackgroundNoise(BG_NOISE_PATH, 20, p=1.0), ApplyImpulseResponse(IR_PATH, p=1.0), Compose(transforms=[ Gain(min_gain_in_db=-15.0, max_gain_in_db=5.0, p=1.0), PolarityInversion(p=1.0), ]), Gain(min_gain_in_db=-6.000001, max_gain_in_db=-6, p=1.0), PolarityInversion(p=1.0), Shift(p=1.0), # Non-differentiable transforms: # RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation: # [torch.DoubleTensor [1, 1, 5]], which is output 0 of IndexBackward, is at version 1; expected version 0 instead. # Hint: enable anomaly detection to find the operation that failed to compute its gradient, # with torch.autograd.set_detect_anomaly(True). pytest.param(HighPassFilter(p=1.0), marks=pytest.mark.skip("Not differentiable")), pytest.param(LowPassFilter(p=1.0), marks=pytest.mark.skip("Not differentiable")), pytest.param(PeakNormalization(p=1.0), marks=pytest.mark.skip("Not differentiable")), ], ) def test_transform_is_differentiable(augment): sample_rate = 16000
"instance": Compose( transforms=[ Gain( min_gain_in_db=-18.0, max_gain_in_db=-16.0, mode=mode, p=0.5 ), PolarityInversion(mode=mode, p=0.5), ], shuffle=True, ), "name": "Compose with Gain and PolarityInversion", "num_runs": 5, }, {"instance": Gain(mode=mode, p=1.0), "num_runs": 5}, {"instance": PolarityInversion(mode=mode, p=1.0), "num_runs": 1}, {"instance": PeakNormalization(mode=mode, p=1.0), "num_runs": 1}, {"instance": Shift(mode=mode, p=1.0), "num_runs": 5}, ] execution_times = {} for transform in transforms: augmenter = transform["instance"] transform_name = ( transform.get("name") if transform.get("name") else transform["instance"].__class__.__name__ ) execution_times[transform_name] = [] for i in range(transform["num_runs"]): with timer() as t: augmented_samples = augmenter(
5, }, { "instance": Gain(mode=mode, p=1.0), "num_runs": 5 }, { "instance": PolarityInversion(mode=mode, p=1.0), "num_runs": 1 }, { "instance": PeakNormalization(mode=mode, p=1.0), "num_runs": 1 }, { "instance": Shift(mode=mode, p=1.0), "num_runs": 5 }, ] execution_times = {} for transform in transforms: augmenter = transform["instance"] transform_name = (transform.get("name") if transform.get("name") else transform["instance"].__class__.__name__) execution_times[transform_name] = [] for i in range(transform["num_runs"]): with timer() as t: augmented_samples = augmenter( samples=samples, sample_rate=SAMPLE_RATE).numpy()
{ "get_instance": lambda: PeakNormalization(mode=mode, p=1.0), "num_runs": 1 }, { "get_instance": lambda: PitchShift(sample_rate=SAMPLE_RATE, mode=mode, p=1.0), "num_runs": 5, }, { "get_instance": lambda: PolarityInversion(mode=mode, p=1.0), "num_runs": 1 }, { "get_instance": lambda: Shift(mode=mode, p=1.0), "num_runs": 5 }, { "get_instance": lambda: ShuffleChannels(mode=mode, p=1.0), "num_runs": 5 }, { "get_instance": lambda: SpliceOut(mode=mode, p=1.0), "num_runs": 5, }, { "get_instance": lambda: TimeInversion(mode=mode, p=1.0), "num_runs": 1 }, ]
"get_instance": lambda: Compose( transforms=[ Gain( min_gain_in_db=-18.0, max_gain_in_db=-16.0, mode=mode, p=0.5 ), PolarityInversion(mode=mode, p=0.5), ], shuffle=True, ), "name": "Compose with Gain and PolarityInversion", "num_runs": 5, }, {"get_instance": lambda: Gain(mode=mode, p=1.0), "num_runs": 5}, {"get_instance": lambda: PolarityInversion(mode=mode, p=1.0), "num_runs": 1}, {"get_instance": lambda: PeakNormalization(mode=mode, p=1.0), "num_runs": 1}, {"get_instance": lambda: Shift(mode=mode, p=1.0), "num_runs": 5}, {"get_instance": lambda: ShuffleChannels(mode=mode, p=1.0), "num_runs": 5}, ] execution_times = {} for transform in transforms: try: augmenter = transform["get_instance"]() except ModeNotSupportedException: continue transform_name = ( transform.get("name") if transform.get("name") else augmenter.__class__.__name__ )