From cd31d318c2dc03e759f7a08ec16296746934b466 Mon Sep 17 00:00:00 2001 From: Marco Bazzani Date: Tue, 22 Aug 2023 11:28:17 -0700 Subject: [PATCH 1/5] MVP implementation --- pyha_analyzer/augmentations.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/pyha_analyzer/augmentations.py b/pyha_analyzer/augmentations.py index cf33262..217b7c7 100644 --- a/pyha_analyzer/augmentations.py +++ b/pyha_analyzer/augmentations.py @@ -4,6 +4,7 @@ """ import logging import os +import time from pathlib import Path from typing import Any, Callable, Dict, List, Optional, Tuple, Iterable @@ -16,6 +17,12 @@ logger = logging.getLogger("acoustic_multiclass_training") +def get_training_proportion(__start_time=time.time()): + approximate_training_time_sec = 6 * 3600; + elapsed_time_sec = time.time()-__start_time + return elapsed_time_sec/approximate_training_time_sec + + def invert(seq: Iterable[int]) -> List[float]: """ Replace each element in list with its inverse @@ -24,14 +31,18 @@ def invert(seq: Iterable[int]) -> List[float]: raise ValueError('Passed iterable cannot contain zero') return [1/x for x in seq] +def get_unnormed_probabilities(seq: Iterable[int]) -> Iterable[float]: + power = 2 * (0.9 - get_training_proportion()) + return [1/(x**power) for x in seq] + def hyperbolic(seq: Iterable[int]) -> List[Tuple[float, int]]: """ Takes a list of numbers and assigns them a probability distribution accourding to the inverse of their values """ - invert_seq = invert(seq) - norm_factor = sum(invert_seq) - probabilities = [x/norm_factor for x in invert_seq] + unnormed_probabilities = get_unnormed_probabilities(seq) + norm_factor = sum(unnormed_probabilities) + probabilities = [x/norm_factor for x in unnormed_probabilities] return list(zip(probabilities, seq)) def sample(distribution: List[Tuple[float, int]]) -> int: @@ -225,9 +236,10 @@ def forward(self, clip: torch.Tensor)->torch.Tensor: Returns: Clip mixed with noise according to noise_type and alpha """ + alpha = self.alpha * get_training_proportion() * 1.3 noise_function = self.noise_names[self.noise_type] noise = noise_function(len(clip)).to(self.device) - return (1 - self.alpha) * clip + self.alpha* noise + return (1 - self.alpha) * clip + self.alpha * noise class RandomEQ(torch.nn.Module): @@ -309,6 +321,8 @@ def forward(self, clip: torch.Tensor) -> torch.Tensor: """ # Skip loading if no noise path alpha = utils.rand(*self.alpha_range) + training_proportion = get_training_proportion() + alpha = alpha + (training_proportion-0.5) * alpha * 1.3 if self.noise_path_str == "": return clip # If loading fails, skip for now From 7f1bc8e1b310f39a5f971f7be211f8191f863535 Mon Sep 17 00:00:00 2001 From: Marco Bazzani Date: Thu, 24 Aug 2023 11:59:37 -0700 Subject: [PATCH 2/5] Rework curriculum learning to use epoch --- pyha_analyzer/augmentations.py | 15 +++++++++++---- pyha_analyzer/train.py | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/pyha_analyzer/augmentations.py b/pyha_analyzer/augmentations.py index 217b7c7..23fcbae 100644 --- a/pyha_analyzer/augmentations.py +++ b/pyha_analyzer/augmentations.py @@ -17,7 +17,10 @@ logger = logging.getLogger("acoustic_multiclass_training") -def get_training_proportion(__start_time=time.time()): +def get_training_proportion(): + total_epochs = config.cfg.epochs + current_epoch = config.cfg.current_epoch + return current_epoch/total_epochs approximate_training_time_sec = 6 * 3600; elapsed_time_sec = time.time()-__start_time return elapsed_time_sec/approximate_training_time_sec @@ -236,10 +239,12 @@ def forward(self, clip: torch.Tensor)->torch.Tensor: Returns: Clip mixed with noise according to noise_type and alpha """ - alpha = self.alpha * get_training_proportion() * 1.3 + alpha = (self.alpha + * get_training_proportion() + * self.cfg.curriculum_learning_scale_factor) noise_function = self.noise_names[self.noise_type] noise = noise_function(len(clip)).to(self.device) - return (1 - self.alpha) * clip + self.alpha * noise + return (1 - alpha) * clip + alpha * noise class RandomEQ(torch.nn.Module): @@ -322,7 +327,9 @@ def forward(self, clip: torch.Tensor) -> torch.Tensor: # Skip loading if no noise path alpha = utils.rand(*self.alpha_range) training_proportion = get_training_proportion() - alpha = alpha + (training_proportion-0.5) * alpha * 1.3 + alpha = alpha + ((training_proportion-0.5) + * alpha + * cfg.curriculum_learning_scale_factor) if self.noise_path_str == "": return clip # If loading fails, skip for now diff --git a/pyha_analyzer/train.py b/pyha_analyzer/train.py index e4c1ca2..c40ca97 100644 --- a/pyha_analyzer/train.py +++ b/pyha_analyzer/train.py @@ -323,7 +323,6 @@ def main(in_sweep=True) -> None: """ logger.info("Device is: %s, Preprocessing Device is %s", cfg.device, cfg.prepros_device) set_seed(cfg.seed) - if in_sweep: run = wandb.init() for key, val in dict(wandb.config).items(): @@ -360,6 +359,7 @@ def main(in_sweep=True) -> None: for epoch in range(cfg.epochs): logger.info("Epoch %d", epoch) + setattr(cfg, "current_epoch", epoch) best_valid_cmap = train(model_for_run, train_dataloader, From ee5412c6a25ce7f222bce8426de571458f036221 Mon Sep 17 00:00:00 2001 From: Marco Bazzani Date: Thu, 24 Aug 2023 12:03:15 -0700 Subject: [PATCH 3/5] Add curriculum learning params to config --- pyha_analyzer/augmentations.py | 4 ---- pyha_analyzer/default_config.yml | 3 +++ 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/pyha_analyzer/augmentations.py b/pyha_analyzer/augmentations.py index 23fcbae..50cd43a 100644 --- a/pyha_analyzer/augmentations.py +++ b/pyha_analyzer/augmentations.py @@ -21,10 +21,6 @@ def get_training_proportion(): total_epochs = config.cfg.epochs current_epoch = config.cfg.current_epoch return current_epoch/total_epochs - approximate_training_time_sec = 6 * 3600; - elapsed_time_sec = time.time()-__start_time - return elapsed_time_sec/approximate_training_time_sec - def invert(seq: Iterable[int]) -> List[float]: """ diff --git a/pyha_analyzer/default_config.yml b/pyha_analyzer/default_config.yml index 725cc61..8a369e8 100644 --- a/pyha_analyzer/default_config.yml +++ b/pyha_analyzer/default_config.yml @@ -7,6 +7,9 @@ infer_csv: # Optional, automatically generates class order if not given class_list: +#Curriculum learning +curriculum_learning_scale_factor: 1.3 + # Dataframe column names offset_col: "OFFSET" duration_col: "DURATION" From ee939f6d09fd5dad0c114cde864b29692caf454d Mon Sep 17 00:00:00 2001 From: Marco Bazzani Date: Thu, 24 Aug 2023 15:18:21 -0700 Subject: [PATCH 4/5] Bug fixes --- pyha_analyzer/augmentations.py | 4 +++- pyha_analyzer/train.py | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pyha_analyzer/augmentations.py b/pyha_analyzer/augmentations.py index 50cd43a..83967b8 100644 --- a/pyha_analyzer/augmentations.py +++ b/pyha_analyzer/augmentations.py @@ -227,6 +227,7 @@ def __init__(self, cfg: config.Config): self.noise_type = cfg.noise_type self.alpha = cfg.noise_alpha self.device = cfg.prepros_device + self.cfg = cfg def forward(self, clip: torch.Tensor)->torch.Tensor: """ @@ -298,6 +299,7 @@ def __init__(self, cfg: config.Config, norm=False): self.length = cfg.chunk_length_s self.device = cfg.prepros_device self.norm = norm + self.cfg = cfg if self.noise_path_str != "" and cfg.bg_noise_p > 0.0: files = list(os.listdir(self.noise_path)) audio_extensions = (".mp3",".wav",".ogg",".flac",".opus",".sphere",".pt") @@ -325,7 +327,7 @@ def forward(self, clip: torch.Tensor) -> torch.Tensor: training_proportion = get_training_proportion() alpha = alpha + ((training_proportion-0.5) * alpha - * cfg.curriculum_learning_scale_factor) + * self.cfg.curriculum_learning_scale_factor) if self.noise_path_str == "": return clip # If loading fails, skip for now diff --git a/pyha_analyzer/train.py b/pyha_analyzer/train.py index c40ca97..5dd3481 100644 --- a/pyha_analyzer/train.py +++ b/pyha_analyzer/train.py @@ -321,6 +321,8 @@ def logging_setup() -> None: def main(in_sweep=True) -> None: """ Main function """ + + setattr(cfg, "current_epoch", 0) logger.info("Device is: %s, Preprocessing Device is %s", cfg.device, cfg.prepros_device) set_seed(cfg.seed) if in_sweep: From 362be9ead816c495f9ef44bd088977dda27f3271 Mon Sep 17 00:00:00 2001 From: Marco Bazzani Date: Thu, 24 Aug 2023 15:25:55 -0700 Subject: [PATCH 5/5] =?UTF-8?q?Made=20my=20best=20friend=20pylint=20super?= =?UTF-8?q?=20happy!=20=F0=9F=A5=B0=F0=9F=A5=B0=F0=9F=A5=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyha_analyzer/augmentations.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pyha_analyzer/augmentations.py b/pyha_analyzer/augmentations.py index 83967b8..a656502 100644 --- a/pyha_analyzer/augmentations.py +++ b/pyha_analyzer/augmentations.py @@ -4,9 +4,8 @@ """ import logging import os -import time from pathlib import Path -from typing import Any, Callable, Dict, List, Optional, Tuple, Iterable +from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple import numpy as np import pandas as pd @@ -18,6 +17,7 @@ logger = logging.getLogger("acoustic_multiclass_training") def get_training_proportion(): + """ Returns proportion of training done """ total_epochs = config.cfg.epochs current_epoch = config.cfg.current_epoch return current_epoch/total_epochs @@ -31,6 +31,10 @@ def invert(seq: Iterable[int]) -> List[float]: return [1/x for x in seq] def get_unnormed_probabilities(seq: Iterable[int]) -> Iterable[float]: + """ + Get probabilities for each element in seq + Spread changes over time due to curriculum learning + """ power = 2 * (0.9 - get_training_proportion()) return [1/(x**power) for x in seq]