mattricesound commited on
Commit
051ea71
·
2 Parent(s): f65f2ca f0e35fe

Merge pull request #41 from mhrice/initial-cleanup

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. README.md +141 -73
  2. cfg/config.yaml +16 -9
  3. cfg/exp/0-0.yaml +29 -0
  4. cfg/exp/1-1.yaml +4 -3
  5. cfg/exp/2-2.yaml +4 -3
  6. cfg/exp/3-3.yaml +4 -3
  7. cfg/exp/4-4.yaml +4 -3
  8. cfg/exp/5-1.yaml +3 -2
  9. cfg/exp/5-5.yaml +4 -3
  10. cfg/exp/5-5_full.yaml +29 -0
  11. cfg/exp/{5-5_cls.yaml → 5-5_full_cls.yaml} +2 -2
  12. cfg/exp/{5-5_cls_dynamic.yaml → 5-5_full_cls_dynamic.yaml} +1 -1
  13. cfg/exp/chain_inference.yaml +3 -2
  14. cfg/exp/chain_inference_aug.yaml +3 -2
  15. cfg/exp/chain_inference_aug_classifier.yaml +4 -4
  16. cfg/exp/chain_inference_custom.yaml +3 -2
  17. cfg/exp/chorus.yaml +6 -9
  18. cfg/exp/{reverb_only.yaml → chorus_aug.yaml} +11 -6
  19. cfg/exp/compression.yaml +5 -8
  20. cfg/exp/{distortion_only.yaml → compression_aug.yaml} +10 -5
  21. cfg/exp/default.yaml +2 -1
  22. cfg/exp/delay.yaml +6 -9
  23. cfg/exp/{chorus_only.yaml → delay_aug.yaml} +11 -6
  24. cfg/exp/delay_only.yaml +0 -24
  25. cfg/exp/distortion.yaml +5 -8
  26. cfg/exp/{compression_only.yaml → distortion_aug.yaml} +10 -5
  27. cfg/exp/remfx_all.yaml +88 -0
  28. cfg/exp/remfx_detect.yaml +88 -0
  29. cfg/exp/remfx_oracle.yaml +72 -0
  30. cfg/exp/reverb.yaml +6 -9
  31. cfg/exp/reverb_aug.yaml +29 -0
  32. cfg/model/audio_diffusion.yaml +0 -16
  33. diffusion_test2.ipynb +0 -188
  34. download_ckpts.sh +12 -0
  35. download_eval_datasets.sh +25 -0
  36. eval.sh +48 -0
  37. notebooks/Experiments.ipynb +0 -0
  38. notebooks/diffusion_test.ipynb +0 -0
  39. notebooks/egfx.ipynb +0 -603
  40. notebooks/guitar_generation_test.ipynb +0 -0
  41. remfx/callbacks.py +3 -3
  42. remfx/classifier.py +15 -15
  43. remfx/datasets.py +12 -44
  44. remfx/models.py +23 -73
  45. remfx/tcn.py +0 -1
  46. remfx/utils.py +4 -34
  47. remfx_detect.sh +39 -0
  48. scripts/download.py +48 -39
  49. scripts/download_egfx.sh +0 -22
  50. scripts/generate_dataset.py +15 -0
README.md CHANGED
@@ -1,56 +1,161 @@
 
 
 
 
 
1
 
2
  # Setup
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
- ## Install Packages
5
- 1. `python3 -m venv env`
6
- 2. `source env/bin/activate`
7
- 3. `pip install -e .`
8
- 4. `git submodule update --init --recursive`
9
- 5. `pip install -e umx`
10
-
11
- ## Download [VocalSet Dataset](https://zenodo.org/record/1193957)
12
- 1. `wget https://zenodo.org/record/1442513/files/VocalSet1-2.zip?download=1`
13
- 2. `mv VocalSet.zip?download=1 VocalSet.zip`
14
- 3. `unzip VocalSet.zip`
15
-
16
- # Training
17
- ## Steps
18
- 1. Change Wandb and data root variables in `shell_vars.sh` and `source shell_vars.sh`
19
- 2. `python scripts/train.py +exp=default`
20
-
21
- ## Experiments
22
- Training parameters can be configured in `cfg/exp/default.yaml`. Here are some descriptions
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  - `num_kept_effects={[min, max]}` range of <b> Kept </b> effects to apply to each file. Inclusive.
24
  - `num_removed_effects={[min, max]}` range of <b> Removed </b> effects to apply to each file. Inclusive.
25
- - `model={model}` architecture to use (see 'Models')
26
- - `effects_to_keep={[effect]}` Effects to apply but not remove (see 'Effects')
27
  - `effects_to_remove={[effect]}` Effects to remove (see 'Effects')
28
  - `accelerator=null/'gpu'` Use GPU (1 device) (default: null)
29
  - `render_files=True/False` Render files. Disable to skip rendering stage (default: True)
30
- - `render_root={path/to/dir}`. Root directory to render files to (default: DATASET_ROOT)
31
-
32
- These can also be specified on the command line.
33
- see `cfg/exp/default.yaml` for an example.
34
 
35
-
36
- ## Models
37
  - `umx`
38
  - `demucs`
39
  - `tcn`
40
  - `dcunet`
41
  - `dptnet`
42
 
43
- ## Effects
 
 
 
 
 
 
44
  - `chorus`
45
  - `compressor`
46
  - `distortion`
47
  - `reverb`
48
  - `delay`
49
 
50
- ## Chain Inference
51
- `python scripts/chain_inference.py +exp=chain_inference`
52
-
53
- ## Run inference on directory
54
  Assumes directory is structured as
55
  - root
56
  - clean
@@ -62,49 +167,12 @@ Assumes directory is structured as
62
  - file2.wav
63
  - file3.wav
64
 
65
- Change root path in `shell_vars.sh` and `source shell_vars.sh`
66
-
67
- `python scripts/chain_inference.py +exp=chain_inference_custom`
68
-
69
-
70
-
71
- ## Misc.
72
- By default, files are rendered to `input_dir / processed / {string_of_effects} / {train|val|test}`.
73
-
74
-
75
- Download datasets:
76
-
77
  ```
78
- python scripts/download.py vocalset guitarset idmt-smt-guitar idmt-smt-bass idmt-smt-drums
79
  ```
80
 
81
- To run audio effects classifiction:
82
  ```
83
- python scripts/train.py model=classifier "effects_to_use=[compressor, distortion, reverb, chorus, delay]" "effects_to_remove=[]" max_kept_effects=5 max_removed_effects=0 shuffle_kept_effects=True shuffle_removed_effects=True accelerator='gpu' render_root=/scratch/RemFX render_files=True
84
- ```
85
-
86
- ```
87
- srun --comment harmonai --partition=g40 --gpus=1 --cpus-per-gpu=12 --job-name=harmonai --pty bash -i
88
- source env/bin/activate
89
- rsync -aP /fsx/home-csteinmetz1/data/EffectSet_cjs.tar /scratch
90
- tar -xvf EffectSet_cjs.tar
91
- mv scratch/EffectSet_cjs ./EffectSet_cjs
92
-
93
- export DATASET_ROOT="/admin/home-csteinmetz1/data/remfx-data"
94
- export WANDB_PROJECT="RemFX"
95
- export WANDB_ENTITY="cjstein"
96
-
97
- python scripts/train.py +exp=5-5.yaml model=cls_vggish render_files=False logs_dir=/scratch/cjs-log datamodule.batch_size=64
98
- python scripts/train.py +exp=5-5.yaml model=cls_panns_pt render_files=False logs_dir=/scratch/cjs-log datamodule.batch_size=64
99
- python scripts/train.py +exp=5-5.yaml model=cls_wav2vec2 render_files=False logs_dir=/scratch/cjs-log datamodule.batch_size=64
100
- python scripts/train.py +exp=5-5.yaml model=cls_wav2clip render_files=False logs_dir=/scratch/cjs-log datamodule.batch_size=64
101
- ```
102
-
103
- ### Installing HEAR models
104
-
105
- wav2clip
106
  ```
107
- pip install hearbaseline
108
- pip install git+https://github.com/hohsiangwu/wav2clip-hear.git
109
- pip install git+https://github.com/qiuqiangkong/HEAR2021_Challenge_PANNs
110
- wget https://zenodo.org/record/6332525/files/hear2021-panns_hear.pth
 
1
+ # General Purpose Audio Effect Removal
2
+ Removing multiple audio effects from multiple sources using compositional audio effect removal and source separation and speech enhancement models.
3
+
4
+ This repo contains the code for the paper [General Purpose Audio Effect Removal](https://arxiv.org/abs/2110.00484). (Todo: Link broken, Add video, Add img, citation)
5
+
6
 
7
  # Setup
8
+ ```
9
+ git clone https://github.com/mhrice/RemFx.git
10
+ cd RemFx
11
+ git submodule update --init --recursive
12
+ pip install -e . ./umx
13
+ ```
14
+ # Usage
15
+ This repo can be used for many different tasks. Here are some examples.
16
+ ## Run RemFX Detect on a single file - []
17
+ First, need to download the checkpoints from [zenodo](https://zenodo.org/record/8179396)
18
+ ```
19
+ ./download_checkpoints.sh
20
+ ./remfx_detect.sh wet.wav -o dry.wav
21
+ ```
22
+ ## Download the [General Purpose Audio Effect Removal evaluation datasets](https://zenodo.org/record/8183649/) - [x]
23
+ ```
24
+ ./download_eval_datasets.sh
25
+ ```
26
+
27
+ ## Download the starter datasets - [x]
28
+ ```
29
+ python scripts/download.py vocalset guitarset dsd100 idmt-smt-drums
30
+ ```
31
+ By default, the starter datasets are downloaded to `./data/remfx-data`. To change this, pass `--output_dir={path/to/datasets}` to `download.py`
32
+
33
+ Then set the dataset root :
34
+ ```
35
+ export DATASET_ROOT={path/to/datasets}
36
+ ```
37
+
38
+ ## Training - [x]
39
+ Before training, it is important that you have downloaded the starter datasets (see above) and set DATASET_ROOT.
40
+ This project uses the [pytorch-lightning](https://www.pytorchlightning.ai/index.html) framework and [hydra](https://hydra.cc/) for configuration management. All experiments are defined in `cfg/exp/`. To train with an existing experiment run
41
+ ```
42
+ python scripts/train.py +exp={experiment_name}
43
+ ```
44
 
45
+ Here are some selected experiment types from the paper, which use different datasets and configurations. See `cfg/exp/` for a full list of experiments and parameters.
46
+
47
+ | Experiment Type | Config Name | Example |
48
+ | ----------------------- | ------------ | ----------------- |
49
+ | Effect-specific | {effect} | +exp=chorus |
50
+ | Effect-specific + FXAug | {effect}_aug | +exp=chorus_aug |
51
+ | Monolithic (1 FX) | 5-1 | +exp=5-1 |
52
+ | Monolithic (<=5 FX) | 5-5_full | +exp=5-5_full |
53
+ | Classifier | 5-5_full_cls | +exp=5-5_full_cls |
54
+
55
+ To change the configuration, simply edit the experiment file, or override the configuration on the command line. A description of some of these variables is in the Misc. section below.
56
+ You can also create a custom experiment by creating a new experiment file in `cfg/exp/` and overriding the default parameters in `config.yaml`.
57
+
58
+ At the end of training, the train script will automatically evaluate the test set using the best checkpoint (by validation loss). If epoch 0 is not finished, it will throw an error. To evaluate a specific checkpoint, run
59
+
60
+ ```
61
+ python scripts/test.py +exp={experiment_name} +ckpt_path="{path/to/checkpoint}" render_files=False
62
+ ```
63
+
64
+ The checkpoints will be saved in `./logs/ckpts/{timestamp}`
65
+ Metrics and hyperparams will be logged in `./lightning_logs/{timestamp}`
66
+
67
+ By default, the dataset needed for the experiment is generated before training.
68
+ If you have generated the dataset separately (see Generate datasets used in the paper), be sure to set `render_files=False` in the config or command-line, and set `render_root={path/to/dataset}` if it is in a custom location.
69
+
70
+ Also note that the training assumes you have a GPU. To train on CPU, set `accelerator=null` in the config or command-line.
71
+
72
+ ## Evaluate models on the General Purpose Audio Effect Removal evaluation datasets (Table 4 from the paper) - []
73
+ First download the General Purpose Audio Effect Removal evaluation datasets (see above).
74
+ To use the pretrained RemFX model, download the checkpoints
75
+ ```
76
+ ./download_checkpoints.sh
77
+ ```
78
+ Then run the evaluation script, select the RemFX configuration, between `remfx_oracle`, `remfx_detect`, and `remfx_all`. Then select N, the number of effects to remove.
79
+ ```
80
+ ./eval.sh remfx_detect 0-0
81
+ ./eval.sh remfx_detect 1-1
82
+ ./eval.sh remfx_detect 2-2
83
+ ./eval.sh remfx_detect 3-3
84
+ ./eval.sh remfx_detect 4-4
85
+ ./eval.sh remfx_detect 5-5
86
+
87
+ ```
88
+ To eval a custom monolithic model, first train a model (see Training)
89
+ Then run the evaluation script, with the config used and checkpoint_path.
90
+ ```
91
+ ./eval.sh distortion_aug 0-0 -ckpt "logs/ckpts/2023-07-26-10-10-27/epoch\=05-valid_loss\=8.623.ckpt"
92
+ ./eval.sh distortion_aug 1-1 -ckpt "logs/ckpts/2023-07-26-10-10-27/epoch\=05-valid_loss\=8.623.ckpt"
93
+ ./eval.sh distortion_aug 2-2 -ckpt "logs/ckpts/2023-07-26-10-10-27/epoch\=05-valid_loss\=8.623.ckpt"
94
+ ./eval.sh distortion_aug 3-3 -ckpt "logs/ckpts/2023-07-26-10-10-27/epoch\=05-valid_loss\=8.623.ckpt"
95
+ ./eval.sh distortion_aug 4-4 -ckpt "logs/ckpts/2023-07-26-10-10-27/epoch\=05-valid_loss\=8.623.ckpt"
96
+ ./eval.sh distortion_aug 5-5 -ckpt "logs/ckpts/2023-07-26-10-10-27/epoch\=05-valid_loss\=8.623.ckpt"
97
+ ```
98
+
99
+ To eval a custom effect-specific model as part of the inference chain, first train a model (see Training), then edit `cfg/exp/remfx_{desired_configuration}.yaml` -> ckpts -> {effect}.
100
+ Then run the evaluation script.
101
+ ```
102
+ ./eval.sh remfx_detect 0-0
103
+ ```
104
+
105
+ The script assumes that RemFX_eval_datasets is in the top-level directory.
106
+ Metrics and hyperparams will be logged in `./lightning_logs/{timestamp}`
107
+
108
+ ## Generate other datasets - [x]
109
+ The datasets used in the experiments are customly generated from the starter datasets. In short, for each training/val/testing example, we select a random 5.5s segment from one of the starter datasets and apply a random number of effects to it. The number of effects applied is controlled by the `num_kept_effects` and `num_removed_effects` parameters. The effects applied are controlled by the `effects_to_keep` and `effects_to_remove` parameters.
110
+
111
+ Before generating datasets, it is important that you have downloaded the starter datasets (see above) and set DATASET_ROOT.
112
+
113
+ To generate one of the datasets used in the paper, use of the experiments defined in `cfg/exp/`.
114
+ For example, to generate the `chorus` FXAug dataset, which includes files with 5 possible effects, up to 4 kept effects (distortion, reverb, compression, delay), and 1 removed effects (chorus), run
115
+ ```
116
+ python scripts/generate_dataset.py +exp=chorus_aug
117
+ ```
118
+
119
+ See the Misc. section below for a description of the parameters.
120
+ By default, files are rendered to `{render_root} / processed / {string_of_effects} / {train|val|test}`.
121
+
122
+ If training, this process will be done automatically at the start of training. To disable this, set `render_files=False` in the config or command-line, and set `render_root={path/to/dataset}` if it is in a custom location.
123
+
124
+ # Misc.
125
+ ## Experimental parameters
126
+ Some relevant dataset/training parameters descriptions
127
  - `num_kept_effects={[min, max]}` range of <b> Kept </b> effects to apply to each file. Inclusive.
128
  - `num_removed_effects={[min, max]}` range of <b> Removed </b> effects to apply to each file. Inclusive.
129
+ - `model={model}` architecture to use (see 'Effect Removal Models/Effect Classification Models')
130
+ - `effects_to_keep={[effect]}` Effects to apply but not remove (see 'Effects'). Used for FXAug.
131
  - `effects_to_remove={[effect]}` Effects to remove (see 'Effects')
132
  - `accelerator=null/'gpu'` Use GPU (1 device) (default: null)
133
  - `render_files=True/False` Render files. Disable to skip rendering stage (default: True)
134
+ - `render_root={path/to/dir}`. Root directory to render files to (default: ./data)
135
+ - `datamodule.train_batch_size={batch_size}`. Change batch size (default: varies)
 
 
136
 
137
+ ### Effect Removal Models
 
138
  - `umx`
139
  - `demucs`
140
  - `tcn`
141
  - `dcunet`
142
  - `dptnet`
143
 
144
+ ### Effect Classification Models
145
+ - `cls_vggish`
146
+ - `cls_panns_pt`
147
+ - `cls_wav2vec2`
148
+ - `cls_wav2clip`
149
+
150
+ ### Effects
151
  - `chorus`
152
  - `compressor`
153
  - `distortion`
154
  - `reverb`
155
  - `delay`
156
 
157
+ # DO WE NEED THIS?
158
+ ## Evaluate RemFXwith a custom directory - []
 
 
159
  Assumes directory is structured as
160
  - root
161
  - clean
 
167
  - file2.wav
168
  - file3.wav
169
 
170
+ First set the dataset root:
 
 
 
 
 
 
 
 
 
 
 
171
  ```
172
+ export DATASET_ROOT={path/to/datasets}
173
  ```
174
 
175
+ Then run
176
  ```
177
+ python scripts/chain_inference.py +exp=chain_inference_custom
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
178
  ```
 
 
 
 
cfg/config.yaml CHANGED
@@ -63,7 +63,7 @@ datamodule:
63
  shuffle_removed_effects: ${shuffle_removed_effects}
64
  render_files: ${render_files}
65
  render_root: ${render_root}
66
- parallel: True
67
  val_dataset:
68
  _target_: remfx.datasets.EffectDataset
69
  total_chunks: 1000
@@ -80,6 +80,7 @@ datamodule:
80
  shuffle_removed_effects: ${shuffle_removed_effects}
81
  render_files: ${render_files}
82
  render_root: ${render_root}
 
83
  test_dataset:
84
  _target_: remfx.datasets.EffectDataset
85
  total_chunks: 1000
@@ -96,21 +97,27 @@ datamodule:
96
  shuffle_removed_effects: ${shuffle_removed_effects}
97
  render_files: ${render_files}
98
  render_root: ${render_root}
 
99
 
100
- batch_size: 16
 
101
  num_workers: 8
102
  pin_memory: True
103
  persistent_workers: True
104
 
 
 
 
 
 
 
 
 
 
105
  logger:
106
- _target_: pytorch_lightning.loggers.WandbLogger
107
- project: ${oc.env:WANDB_PROJECT}
108
- entity: ${oc.env:WANDB_ENTITY}
109
- # offline: False # set True to store all logs only locally
110
- job_type: "train"
111
- group: ""
112
  save_dir: "."
113
- log_model: True
114
 
115
  trainer:
116
  _target_: pytorch_lightning.Trainer
 
63
  shuffle_removed_effects: ${shuffle_removed_effects}
64
  render_files: ${render_files}
65
  render_root: ${render_root}
66
+ parallel: False
67
  val_dataset:
68
  _target_: remfx.datasets.EffectDataset
69
  total_chunks: 1000
 
80
  shuffle_removed_effects: ${shuffle_removed_effects}
81
  render_files: ${render_files}
82
  render_root: ${render_root}
83
+ parallel: False
84
  test_dataset:
85
  _target_: remfx.datasets.EffectDataset
86
  total_chunks: 1000
 
97
  shuffle_removed_effects: ${shuffle_removed_effects}
98
  render_files: ${render_files}
99
  render_root: ${render_root}
100
+ parallel: False
101
 
102
+ train_batch_size: 16
103
+ test_batch_size: 1
104
  num_workers: 8
105
  pin_memory: True
106
  persistent_workers: True
107
 
108
+ # logger:
109
+ # _target_: pytorch_lightning.loggers.WandbLogger
110
+ # project: ${oc.env:WANDB_PROJECT}
111
+ # entity: ${oc.env:WANDB_ENTITY}
112
+ # # offline: False # set True to store all logs only locally
113
+ # job_type: "train"
114
+ # group: ""
115
+ # save_dir: "."
116
+ # log_model: True
117
  logger:
118
+ _target_: pytorch_lightning.loggers.CSVLogger
 
 
 
 
 
119
  save_dir: "."
120
+ version: ${now:%Y-%m-%d-%H-%M-%S}
121
 
122
  trainer:
123
  _target_: pytorch_lightning.Trainer
cfg/exp/0-0.yaml ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # @package _global_
2
+ defaults:
3
+ - override /model: demucs
4
+ - override /effects: all
5
+ seed: 12345
6
+ sample_rate: 48000
7
+ chunk_size: 262144 # 5.5s
8
+ logs_dir: "./logs"
9
+ render_files: True
10
+
11
+ accelerator: "gpu"
12
+ log_audio: True
13
+ # Effects
14
+ num_kept_effects: [0,0] # [min, max]
15
+ num_removed_effects: [0,0] # [min, max]
16
+ shuffle_kept_effects: True
17
+ shuffle_removed_effects: True
18
+ num_classes: 5
19
+ effects_to_keep:
20
+ effects_to_remove:
21
+ - distortion
22
+ - compressor
23
+ - reverb
24
+ - chorus
25
+ - delay
26
+ datamodule:
27
+ train_batch_size: 16
28
+ test_batch_size: 1
29
+ num_workers: 8
cfg/exp/1-1.yaml CHANGED
@@ -7,12 +7,12 @@ sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
- render_root: "/scratch/EffectSet"
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
14
  num_kept_effects: [0,0] # [min, max]
15
- num_removed_effects: [0,1] # [min, max]
16
  shuffle_kept_effects: True
17
  shuffle_removed_effects: True
18
  num_classes: 5
@@ -24,5 +24,6 @@ effects_to_remove:
24
  - chorus
25
  - delay
26
  datamodule:
27
- batch_size: 16
 
28
  num_workers: 8
 
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
+
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
14
  num_kept_effects: [0,0] # [min, max]
15
+ num_removed_effects: [1,1] # [min, max]
16
  shuffle_kept_effects: True
17
  shuffle_removed_effects: True
18
  num_classes: 5
 
24
  - chorus
25
  - delay
26
  datamodule:
27
+ train_batch_size: 16
28
+ test_batch_size: 1
29
  num_workers: 8
cfg/exp/2-2.yaml CHANGED
@@ -7,12 +7,12 @@ sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
- render_root: "/scratch/EffectSet"
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
14
  num_kept_effects: [0,0] # [min, max]
15
- num_removed_effects: [0,2] # [min, max]
16
  shuffle_kept_effects: True
17
  shuffle_removed_effects: True
18
  num_classes: 5
@@ -24,5 +24,6 @@ effects_to_remove:
24
  - chorus
25
  - delay
26
  datamodule:
27
- batch_size: 16
 
28
  num_workers: 8
 
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
+
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
14
  num_kept_effects: [0,0] # [min, max]
15
+ num_removed_effects: [2,2] # [min, max]
16
  shuffle_kept_effects: True
17
  shuffle_removed_effects: True
18
  num_classes: 5
 
24
  - chorus
25
  - delay
26
  datamodule:
27
+ train_batch_size: 16
28
+ test_batch_size: 1
29
  num_workers: 8
cfg/exp/3-3.yaml CHANGED
@@ -7,12 +7,12 @@ sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
- render_root: "/scratch/EffectSet"
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
14
  num_kept_effects: [0,0] # [min, max]
15
- num_removed_effects: [0,3] # [min, max]
16
  shuffle_kept_effects: True
17
  shuffle_removed_effects: True
18
  num_classes: 5
@@ -24,5 +24,6 @@ effects_to_remove:
24
  - chorus
25
  - delay
26
  datamodule:
27
- batch_size: 16
 
28
  num_workers: 8
 
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
+
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
14
  num_kept_effects: [0,0] # [min, max]
15
+ num_removed_effects: [3,3] # [min, max]
16
  shuffle_kept_effects: True
17
  shuffle_removed_effects: True
18
  num_classes: 5
 
24
  - chorus
25
  - delay
26
  datamodule:
27
+ train_batch_size: 16
28
+ test_batch_size: 1
29
  num_workers: 8
cfg/exp/4-4.yaml CHANGED
@@ -7,12 +7,12 @@ sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
- render_root: "/scratch/EffectSet"
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
14
  num_kept_effects: [0,0] # [min, max]
15
- num_removed_effects: [0,4] # [min, max]
16
  shuffle_kept_effects: True
17
  shuffle_removed_effects: True
18
  num_classes: 5
@@ -24,5 +24,6 @@ effects_to_remove:
24
  - chorus
25
  - delay
26
  datamodule:
27
- batch_size: 16
 
28
  num_workers: 8
 
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
+
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
14
  num_kept_effects: [0,0] # [min, max]
15
+ num_removed_effects: [4,4] # [min, max]
16
  shuffle_kept_effects: True
17
  shuffle_removed_effects: True
18
  num_classes: 5
 
24
  - chorus
25
  - delay
26
  datamodule:
27
+ train_batch_size: 16
28
+ test_batch_size: 1
29
  num_workers: 8
cfg/exp/5-1.yaml CHANGED
@@ -7,7 +7,7 @@ sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
- render_root: "/scratch/EffectSet"
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
@@ -24,5 +24,6 @@ effects_to_remove:
24
  - chorus
25
  - delay
26
  datamodule:
27
- batch_size: 16
 
28
  num_workers: 8
 
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
+
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
 
24
  - chorus
25
  - delay
26
  datamodule:
27
+ train_batch_size: 16
28
+ test_batch_size: 1
29
  num_workers: 8
cfg/exp/5-5.yaml CHANGED
@@ -7,12 +7,12 @@ sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
- render_root: "/scratch/EffectSet"
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
14
  num_kept_effects: [0,0] # [min, max]
15
- num_removed_effects: [0,5] # [min, max]
16
  shuffle_kept_effects: True
17
  shuffle_removed_effects: True
18
  num_classes: 5
@@ -24,5 +24,6 @@ effects_to_remove:
24
  - chorus
25
  - delay
26
  datamodule:
27
- batch_size: 16
 
28
  num_workers: 8
 
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
+
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
14
  num_kept_effects: [0,0] # [min, max]
15
+ num_removed_effects: [5,5] # [min, max]
16
  shuffle_kept_effects: True
17
  shuffle_removed_effects: True
18
  num_classes: 5
 
24
  - chorus
25
  - delay
26
  datamodule:
27
+ train_batch_size: 16
28
+ test_batch_size: 1
29
  num_workers: 8
cfg/exp/5-5_full.yaml ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # @package _global_
2
+ defaults:
3
+ - override /model: demucs
4
+ - override /effects: all
5
+ seed: 12345
6
+ sample_rate: 48000
7
+ chunk_size: 262144 # 5.5s
8
+ logs_dir: "./logs"
9
+ render_files: True
10
+
11
+ accelerator: "gpu"
12
+ log_audio: True
13
+ # Effects
14
+ num_kept_effects: [0,0] # [min, max]
15
+ num_removed_effects: [0,5] # [min, max]
16
+ shuffle_kept_effects: True
17
+ shuffle_removed_effects: True
18
+ num_classes: 5
19
+ effects_to_keep:
20
+ effects_to_remove:
21
+ - distortion
22
+ - compressor
23
+ - reverb
24
+ - chorus
25
+ - delay
26
+ datamodule:
27
+ train_batch_size: 16
28
+ test_batch_size: 1
29
+ num_workers: 8
cfg/exp/{5-5_cls.yaml → 5-5_full_cls.yaml} RENAMED
@@ -1,13 +1,13 @@
1
  # @package _global_
2
  defaults:
3
- - override /model: demucs
4
  - override /effects: all
5
  seed: 12345
6
  sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "/scratch/cjs-logs"
9
  render_files: True
10
- render_root: "/scratch/EffectSet_cjs"
11
  accelerator: "gpu"
12
  log_audio: False
13
  # Effects
 
1
  # @package _global_
2
  defaults:
3
+ - override /model: cls_panns_48k
4
  - override /effects: all
5
  seed: 12345
6
  sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "/scratch/cjs-logs"
9
  render_files: True
10
+
11
  accelerator: "gpu"
12
  log_audio: False
13
  # Effects
cfg/exp/{5-5_cls_dynamic.yaml → 5-5_full_cls_dynamic.yaml} RENAMED
@@ -7,7 +7,7 @@ sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "/scratch/cjs-logs"
9
  render_files: True
10
- render_root: "/scratch/EffectSet_cjs"
11
  accelerator: "gpu"
12
  log_audio: False
13
  # Effects
 
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "/scratch/cjs-logs"
9
  render_files: True
10
+
11
  accelerator: "gpu"
12
  log_audio: False
13
  # Effects
cfg/exp/chain_inference.yaml CHANGED
@@ -6,7 +6,7 @@ seed: 12345
6
  sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
- render_root: "/scratch/EffectSet"
10
  accelerator: "gpu"
11
  log_audio: True
12
  # Effects
@@ -23,7 +23,8 @@ effects_to_remove:
23
  - chorus
24
  - delay
25
  datamodule:
26
- batch_size: 16
 
27
  num_workers: 8
28
 
29
  dcunet:
 
6
  sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
+
10
  accelerator: "gpu"
11
  log_audio: True
12
  # Effects
 
23
  - chorus
24
  - delay
25
  datamodule:
26
+ train_batch_size: 16
27
+ test_batch_size: 1
28
  num_workers: 8
29
 
30
  dcunet:
cfg/exp/chain_inference_aug.yaml CHANGED
@@ -6,7 +6,7 @@ seed: 12345
6
  sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
- render_root: "/scratch/EffectSet"
10
  accelerator: "gpu"
11
  log_audio: True
12
  # Effects
@@ -23,7 +23,8 @@ effects_to_remove:
23
  - chorus
24
  - delay
25
  datamodule:
26
- batch_size: 16
 
27
  num_workers: 8
28
 
29
  dcunet:
 
6
  sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
+
10
  accelerator: "gpu"
11
  log_audio: True
12
  # Effects
 
23
  - chorus
24
  - delay
25
  datamodule:
26
+ train_batch_size: 16
27
+ test_batch_size: 1
28
  num_workers: 8
29
 
30
  dcunet:
cfg/exp/chain_inference_aug_classifier.yaml CHANGED
@@ -6,7 +6,7 @@ seed: 12345
6
  sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
- render_root: "/scratch/EffectSet"
10
  accelerator: "gpu"
11
  log_audio: True
12
  # Effects
@@ -23,7 +23,8 @@ effects_to_remove:
23
  - chorus
24
  - delay
25
  datamodule:
26
- batch_size: 16
 
27
  num_workers: 8
28
 
29
  dcunet:
@@ -56,7 +57,7 @@ classifier:
56
  n_mels: 128
57
  sample_rate: ${sample_rate}
58
  model_sample_rate: ${sample_rate}
59
- specaugment: False
60
  classifier_ckpt: "ckpts/classifier.ckpt"
61
 
62
  ckpts:
@@ -75,7 +76,6 @@ ckpts:
75
  RandomPedalboardDelay:
76
  model: ${dcunet}
77
  ckpt_path: "ckpts/dcunet_delay_aug.ckpt"
78
-
79
  inference_effects_ordering:
80
  - "RandomPedalboardDistortion"
81
  - "RandomPedalboardCompressor"
 
6
  sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
+
10
  accelerator: "gpu"
11
  log_audio: True
12
  # Effects
 
23
  - chorus
24
  - delay
25
  datamodule:
26
+ train_batch_size: 16
27
+ test_batch_size: 1
28
  num_workers: 8
29
 
30
  dcunet:
 
57
  n_mels: 128
58
  sample_rate: ${sample_rate}
59
  model_sample_rate: ${sample_rate}
60
+ specaugment: True
61
  classifier_ckpt: "ckpts/classifier.ckpt"
62
 
63
  ckpts:
 
76
  RandomPedalboardDelay:
77
  model: ${dcunet}
78
  ckpt_path: "ckpts/dcunet_delay_aug.ckpt"
 
79
  inference_effects_ordering:
80
  - "RandomPedalboardDistortion"
81
  - "RandomPedalboardCompressor"
cfg/exp/chain_inference_custom.yaml CHANGED
@@ -6,7 +6,7 @@ seed: 12345
6
  sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
- render_root: "/scratch/EffectSet"
10
  accelerator: "gpu"
11
  log_audio: True
12
  # Effects
@@ -23,7 +23,8 @@ effects_to_remove:
23
  - chorus
24
  - delay
25
  datamodule:
26
- batch_size: 1
 
27
  num_workers: 8
28
  train_dataset: None
29
  val_dataset: None
 
6
  sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
+
10
  accelerator: "gpu"
11
  log_audio: True
12
  # Effects
 
23
  - chorus
24
  - delay
25
  datamodule:
26
+ train_batch_size: 1
27
+ test_batch_size: 1
28
  num_workers: 8
29
  train_dataset: None
30
  val_dataset: None
cfg/exp/chorus.yaml CHANGED
@@ -1,28 +1,25 @@
1
  # @package _global_
2
  defaults:
3
- - override /model: demucs
4
  - override /effects: all
5
  seed: 12345
6
  sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
- render_root: "/scratch/EffectSet"
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
14
- num_kept_effects: [0,4] # [min, max]
15
  num_removed_effects: [1,1] # [min, max]
16
  shuffle_kept_effects: True
17
  shuffle_removed_effects: False
18
- num_classes: 5
19
  effects_to_keep:
20
- - compressor
21
- - distortion
22
- - delay
23
- - reverb
24
  effects_to_remove:
25
  - chorus
26
  datamodule:
27
- batch_size: 16
 
28
  num_workers: 8
 
1
  # @package _global_
2
  defaults:
3
+ - override /model: dcunet
4
  - override /effects: all
5
  seed: 12345
6
  sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
+
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
14
+ num_kept_effects: [0,0] # [min, max]
15
  num_removed_effects: [1,1] # [min, max]
16
  shuffle_kept_effects: True
17
  shuffle_removed_effects: False
18
+ num_classes: 1
19
  effects_to_keep:
 
 
 
 
20
  effects_to_remove:
21
  - chorus
22
  datamodule:
23
+ train_batch_size: 16
24
+ test_batch_size: 1
25
  num_workers: 8
cfg/exp/{reverb_only.yaml → chorus_aug.yaml} RENAMED
@@ -1,24 +1,29 @@
1
  # @package _global_
2
  defaults:
3
- - override /model: demucs
4
  - override /effects: all
5
  seed: 12345
6
  sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
- render_root: "/scratch/EffectSet"
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
14
- num_kept_effects: [0,0] # [min, max]
15
  num_removed_effects: [1,1] # [min, max]
16
  shuffle_kept_effects: True
17
  shuffle_removed_effects: False
18
- num_classes: 1
19
  effects_to_keep:
20
- effects_to_remove:
 
 
21
  - reverb
 
 
22
  datamodule:
23
- batch_size: 16
 
24
  num_workers: 8
 
1
  # @package _global_
2
  defaults:
3
+ - override /model: dcunet
4
  - override /effects: all
5
  seed: 12345
6
  sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
+
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
14
+ num_kept_effects: [0,4] # [min, max]
15
  num_removed_effects: [1,1] # [min, max]
16
  shuffle_kept_effects: True
17
  shuffle_removed_effects: False
18
+ num_classes: 5
19
  effects_to_keep:
20
+ - compressor
21
+ - distortion
22
+ - delay
23
  - reverb
24
+ effects_to_remove:
25
+ - chorus
26
  datamodule:
27
+ train_batch_size: 16
28
+ test_batch_size: 1
29
  num_workers: 8
cfg/exp/compression.yaml CHANGED
@@ -7,22 +7,19 @@ sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
- render_root: "/scratch/EffectSet"
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
14
- num_kept_effects: [0,4] # [min, max]
15
  num_removed_effects: [1,1] # [min, max]
16
  shuffle_kept_effects: True
17
  shuffle_removed_effects: False
18
- num_classes: 5
19
  effects_to_keep:
20
- - distortion
21
- - chorus
22
- - delay
23
- - reverb
24
  effects_to_remove:
25
  - compressor
26
  datamodule:
27
- batch_size: 16
 
28
  num_workers: 8
 
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
+
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
14
+ num_kept_effects: [0,0] # [min, max]
15
  num_removed_effects: [1,1] # [min, max]
16
  shuffle_kept_effects: True
17
  shuffle_removed_effects: False
18
+ num_classes: 1
19
  effects_to_keep:
 
 
 
 
20
  effects_to_remove:
21
  - compressor
22
  datamodule:
23
+ train_batch_size: 16
24
+ test_batch_size: 1
25
  num_workers: 8
cfg/exp/{distortion_only.yaml → compression_aug.yaml} RENAMED
@@ -7,18 +7,23 @@ sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
- render_root: "/scratch/EffectSet"
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
14
- num_kept_effects: [0,0] # [min, max]
15
  num_removed_effects: [1,1] # [min, max]
16
  shuffle_kept_effects: True
17
  shuffle_removed_effects: False
18
- num_classes: 1
19
  effects_to_keep:
20
- effects_to_remove:
21
  - distortion
 
 
 
 
 
22
  datamodule:
23
- batch_size: 16
 
24
  num_workers: 8
 
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
+
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
14
+ num_kept_effects: [0,4] # [min, max]
15
  num_removed_effects: [1,1] # [min, max]
16
  shuffle_kept_effects: True
17
  shuffle_removed_effects: False
18
+ num_classes: 5
19
  effects_to_keep:
 
20
  - distortion
21
+ - chorus
22
+ - delay
23
+ - reverb
24
+ effects_to_remove:
25
+ - compressor
26
  datamodule:
27
+ train_batch_size: 16
28
+ test_batch_size: 1
29
  num_workers: 8
cfg/exp/default.yaml CHANGED
@@ -24,5 +24,6 @@ effects_to_remove:
24
  - delay
25
  - distortion
26
  datamodule:
27
- batch_size: 16
 
28
  num_workers: 8
 
24
  - delay
25
  - distortion
26
  datamodule:
27
+ train_batch_size: 16
28
+ test_batch_size: 1
29
  num_workers: 8
cfg/exp/delay.yaml CHANGED
@@ -1,28 +1,25 @@
1
  # @package _global_
2
  defaults:
3
- - override /model: demucs
4
  - override /effects: all
5
  seed: 12345
6
  sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
- render_root: "/scratch/EffectSet"
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
14
- num_kept_effects: [0,4] # [min, max]
15
  num_removed_effects: [1,1] # [min, max]
16
  shuffle_kept_effects: True
17
  shuffle_removed_effects: False
18
- num_classes: 5
19
  effects_to_keep:
20
- - compressor
21
- - distortion
22
- - chorus
23
- - reverb
24
  effects_to_remove:
25
  - delay
26
  datamodule:
27
- batch_size: 16
 
28
  num_workers: 8
 
1
  # @package _global_
2
  defaults:
3
+ - override /model: dcunet
4
  - override /effects: all
5
  seed: 12345
6
  sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
+
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
14
+ num_kept_effects: [0,0] # [min, max]
15
  num_removed_effects: [1,1] # [min, max]
16
  shuffle_kept_effects: True
17
  shuffle_removed_effects: False
18
+ num_classes: 1
19
  effects_to_keep:
 
 
 
 
20
  effects_to_remove:
21
  - delay
22
  datamodule:
23
+ train_batch_size: 16
24
+ test_batch_size: 1
25
  num_workers: 8
cfg/exp/{chorus_only.yaml → delay_aug.yaml} RENAMED
@@ -1,24 +1,29 @@
1
  # @package _global_
2
  defaults:
3
- - override /model: demucs
4
  - override /effects: all
5
  seed: 12345
6
  sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
- render_root: "/scratch/EffectSet"
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
14
- num_kept_effects: [0,0] # [min, max]
15
  num_removed_effects: [1,1] # [min, max]
16
  shuffle_kept_effects: True
17
  shuffle_removed_effects: False
18
- num_classes: 1
19
  effects_to_keep:
20
- effects_to_remove:
 
21
  - chorus
 
 
 
22
  datamodule:
23
- batch_size: 16
 
24
  num_workers: 8
 
1
  # @package _global_
2
  defaults:
3
+ - override /model: dcunet
4
  - override /effects: all
5
  seed: 12345
6
  sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
+
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
14
+ num_kept_effects: [0,4] # [min, max]
15
  num_removed_effects: [1,1] # [min, max]
16
  shuffle_kept_effects: True
17
  shuffle_removed_effects: False
18
+ num_classes: 5
19
  effects_to_keep:
20
+ - compressor
21
+ - distortion
22
  - chorus
23
+ - reverb
24
+ effects_to_remove:
25
+ - delay
26
  datamodule:
27
+ train_batch_size: 16
28
+ test_batch_size: 1
29
  num_workers: 8
cfg/exp/delay_only.yaml DELETED
@@ -1,24 +0,0 @@
1
- # @package _global_
2
- defaults:
3
- - override /model: demucs
4
- - override /effects: all
5
- seed: 12345
6
- sample_rate: 48000
7
- chunk_size: 262144 # 5.5s
8
- logs_dir: "./logs"
9
- render_files: True
10
- render_root: "/scratch/EffectSet"
11
- accelerator: "gpu"
12
- log_audio: True
13
- # Effects
14
- num_kept_effects: [0,0] # [min, max]
15
- num_removed_effects: [1,1] # [min, max]
16
- shuffle_kept_effects: True
17
- shuffle_removed_effects: False
18
- num_classes: 1
19
- effects_to_keep:
20
- effects_to_remove:
21
- - delay
22
- datamodule:
23
- batch_size: 16
24
- num_workers: 8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cfg/exp/distortion.yaml CHANGED
@@ -7,22 +7,19 @@ sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
- render_root: "/scratch/EffectSet"
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
14
- num_kept_effects: [0,4] # [min, max]
15
  num_removed_effects: [1,1] # [min, max]
16
  shuffle_kept_effects: True
17
  shuffle_removed_effects: False
18
- num_classes: 5
19
  effects_to_keep:
20
- - compressor
21
- - reverb
22
- - chorus
23
- - delay
24
  effects_to_remove:
25
  - distortion
26
  datamodule:
27
- batch_size: 16
 
28
  num_workers: 8
 
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
+
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
14
+ num_kept_effects: [0,0] # [min, max]
15
  num_removed_effects: [1,1] # [min, max]
16
  shuffle_kept_effects: True
17
  shuffle_removed_effects: False
18
+ num_classes: 1
19
  effects_to_keep:
 
 
 
 
20
  effects_to_remove:
21
  - distortion
22
  datamodule:
23
+ train_batch_size: 16
24
+ test_batch_size: 1
25
  num_workers: 8
cfg/exp/{compression_only.yaml → distortion_aug.yaml} RENAMED
@@ -7,18 +7,23 @@ sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
- render_root: "/scratch/EffectSet"
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
14
- num_kept_effects: [0,0] # [min, max]
15
  num_removed_effects: [1,1] # [min, max]
16
  shuffle_kept_effects: True
17
  shuffle_removed_effects: False
18
- num_classes: 1
19
  effects_to_keep:
20
- effects_to_remove:
21
  - compressor
 
 
 
 
 
22
  datamodule:
23
- batch_size: 16
 
24
  num_workers: 8
 
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
+
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
14
+ num_kept_effects: [0,4] # [min, max]
15
  num_removed_effects: [1,1] # [min, max]
16
  shuffle_kept_effects: True
17
  shuffle_removed_effects: False
18
+ num_classes: 5
19
  effects_to_keep:
 
20
  - compressor
21
+ - reverb
22
+ - chorus
23
+ - delay
24
+ effects_to_remove:
25
+ - distortion
26
  datamodule:
27
+ train_batch_size: 16
28
+ test_batch_size: 1
29
  num_workers: 8
cfg/exp/remfx_all.yaml ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # @package _global_
2
+ defaults:
3
+ - override /model: demucs
4
+ - override /effects: all
5
+ seed: 12345
6
+ sample_rate: 48000
7
+ chunk_size: 262144 # 5.5s
8
+ logs_dir: "./logs"
9
+ accelerator: "gpu"
10
+ log_audio: True
11
+
12
+ # Effects
13
+ num_kept_effects: [0,0] # [min, max]
14
+ num_removed_effects: [0,5] # [min, max]
15
+ shuffle_kept_effects: True
16
+ shuffle_removed_effects: True
17
+ num_classes: 5
18
+ effects_to_keep:
19
+ effects_to_remove:
20
+ - distortion
21
+ - compressor
22
+ - reverb
23
+ - chorus
24
+ - delay
25
+ datamodule:
26
+ train_batch_size: 16
27
+ test_batch_size: 1
28
+ num_workers: 8
29
+
30
+ dcunet:
31
+ _target_: remfx.models.RemFX
32
+ lr: 1e-4
33
+ lr_beta1: 0.95
34
+ lr_beta2: 0.999
35
+ lr_eps: 1e-6
36
+ lr_weight_decay: 1e-3
37
+ sample_rate: ${sample_rate}
38
+ network:
39
+ _target_: remfx.models.DCUNetModel
40
+ architecture: "Large-DCUNet-20"
41
+ stft_kernel_size: 512
42
+ fix_length_mode: "pad"
43
+ sample_rate: ${sample_rate}
44
+ num_bins: 1025
45
+
46
+ classifier:
47
+ _target_: remfx.models.FXClassifier
48
+ lr: 3e-4
49
+ lr_weight_decay: 1e-3
50
+ sample_rate: ${sample_rate}
51
+ mixup: False
52
+ network:
53
+ _target_: remfx.classifier.Cnn14
54
+ num_classes: ${num_classes}
55
+ n_fft: 2048
56
+ hop_length: 512
57
+ n_mels: 128
58
+ sample_rate: ${sample_rate}
59
+ model_sample_rate: ${sample_rate}
60
+ specaugment: True
61
+ classifier_ckpt: "ckpts/classifier.ckpt"
62
+
63
+ ckpts:
64
+ RandomPedalboardDistortion:
65
+ model: ${model}
66
+ ckpt_path: "ckpts/demucs_distortion_aug.ckpt"
67
+ RandomPedalboardCompressor:
68
+ model: ${model}
69
+ ckpt_path: "ckpts/demucs_compressor_aug.ckpt"
70
+ RandomPedalboardReverb:
71
+ model: ${dcunet}
72
+ ckpt_path: "ckpts/dcunet_reverb_aug.ckpt"
73
+ RandomPedalboardChorus:
74
+ model: ${dcunet}
75
+ ckpt_path: "ckpts/dcunet_chorus_aug.ckpt"
76
+ RandomPedalboardDelay:
77
+ model: ${dcunet}
78
+ ckpt_path: "ckpts/dcunet_delay_aug.ckpt"
79
+
80
+ inference_effects_ordering:
81
+ - "RandomPedalboardDistortion"
82
+ - "RandomPedalboardCompressor"
83
+ - "RandomPedalboardReverb"
84
+ - "RandomPedalboardChorus"
85
+ - "RandomPedalboardDelay"
86
+ num_bins: 1025
87
+ inference_effects_shuffle: True
88
+ inference_use_all_effect_models: True
cfg/exp/remfx_detect.yaml ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # @package _global_
2
+ defaults:
3
+ - override /model: demucs
4
+ - override /effects: all
5
+ seed: 12345
6
+ sample_rate: 48000
7
+ chunk_size: 262144 # 5.5s
8
+ logs_dir: "./logs"
9
+ accelerator: "gpu"
10
+ log_audio: True
11
+
12
+ # Effects
13
+ num_kept_effects: [0,0] # [min, max]
14
+ num_removed_effects: [0,5] # [min, max]
15
+ shuffle_kept_effects: True
16
+ shuffle_removed_effects: True
17
+ num_classes: 5
18
+ effects_to_keep:
19
+ effects_to_remove:
20
+ - distortion
21
+ - compressor
22
+ - reverb
23
+ - chorus
24
+ - delay
25
+ datamodule:
26
+ train_batch_size: 16
27
+ test_batch_size: 1
28
+ num_workers: 8
29
+
30
+ dcunet:
31
+ _target_: remfx.models.RemFX
32
+ lr: 1e-4
33
+ lr_beta1: 0.95
34
+ lr_beta2: 0.999
35
+ lr_eps: 1e-6
36
+ lr_weight_decay: 1e-3
37
+ sample_rate: ${sample_rate}
38
+ network:
39
+ _target_: remfx.models.DCUNetModel
40
+ architecture: "Large-DCUNet-20"
41
+ stft_kernel_size: 512
42
+ fix_length_mode: "pad"
43
+ sample_rate: ${sample_rate}
44
+ num_bins: 1025
45
+
46
+ classifier:
47
+ _target_: remfx.models.FXClassifier
48
+ lr: 3e-4
49
+ lr_weight_decay: 1e-3
50
+ sample_rate: ${sample_rate}
51
+ mixup: False
52
+ network:
53
+ _target_: remfx.classifier.Cnn14
54
+ num_classes: ${num_classes}
55
+ n_fft: 2048
56
+ hop_length: 512
57
+ n_mels: 128
58
+ sample_rate: ${sample_rate}
59
+ model_sample_rate: ${sample_rate}
60
+ specaugment: True
61
+ classifier_ckpt: "ckpts/classifier.ckpt"
62
+
63
+ ckpts:
64
+ RandomPedalboardDistortion:
65
+ model: ${model}
66
+ ckpt_path: "ckpts/demucs_distortion_aug.ckpt"
67
+ RandomPedalboardCompressor:
68
+ model: ${model}
69
+ ckpt_path: "ckpts/demucs_compressor_aug.ckpt"
70
+ RandomPedalboardReverb:
71
+ model: ${dcunet}
72
+ ckpt_path: "ckpts/dcunet_reverb_aug.ckpt"
73
+ RandomPedalboardChorus:
74
+ model: ${dcunet}
75
+ ckpt_path: "ckpts/dcunet_chorus_aug.ckpt"
76
+ RandomPedalboardDelay:
77
+ model: ${dcunet}
78
+ ckpt_path: "ckpts/dcunet_delay_aug.ckpt"
79
+
80
+ inference_effects_ordering:
81
+ - "RandomPedalboardDistortion"
82
+ - "RandomPedalboardCompressor"
83
+ - "RandomPedalboardReverb"
84
+ - "RandomPedalboardChorus"
85
+ - "RandomPedalboardDelay"
86
+ num_bins: 1025
87
+ inference_effects_shuffle: True
88
+ inference_use_all_effect_models: False
cfg/exp/remfx_oracle.yaml ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # @package _global_
2
+ defaults:
3
+ - override /model: demucs
4
+ - override /effects: all
5
+ seed: 12345
6
+ sample_rate: 48000
7
+ chunk_size: 262144 # 5.5s
8
+ logs_dir: "./logs"
9
+ accelerator: "gpu"
10
+ log_audio: True
11
+
12
+ # Effects
13
+ num_kept_effects: [0,0] # [min, max]
14
+ num_removed_effects: [0,5] # [min, max]
15
+ shuffle_kept_effects: True
16
+ shuffle_removed_effects: True
17
+ num_classes: 5
18
+ effects_to_keep:
19
+ effects_to_remove:
20
+ - distortion
21
+ - compressor
22
+ - reverb
23
+ - chorus
24
+ - delay
25
+ datamodule:
26
+ train_batch_size: 16
27
+ test_batch_size: 1
28
+ num_workers: 8
29
+
30
+ dcunet:
31
+ _target_: remfx.models.RemFX
32
+ lr: 1e-4
33
+ lr_beta1: 0.95
34
+ lr_beta2: 0.999
35
+ lr_eps: 1e-6
36
+ lr_weight_decay: 1e-3
37
+ sample_rate: ${sample_rate}
38
+ network:
39
+ _target_: remfx.models.DCUNetModel
40
+ architecture: "Large-DCUNet-20"
41
+ stft_kernel_size: 512
42
+ fix_length_mode: "pad"
43
+ sample_rate: ${sample_rate}
44
+ num_bins: 1025
45
+
46
+
47
+ ckpts:
48
+ RandomPedalboardDistortion:
49
+ model: ${model}
50
+ ckpt_path: "ckpts/demucs_distortion_aug.ckpt"
51
+ RandomPedalboardCompressor:
52
+ model: ${model}
53
+ ckpt_path: "ckpts/demucs_compressor_aug.ckpt"
54
+ RandomPedalboardReverb:
55
+ model: ${dcunet}
56
+ ckpt_path: "ckpts/dcunet_reverb_aug.ckpt"
57
+ RandomPedalboardChorus:
58
+ model: ${dcunet}
59
+ ckpt_path: "ckpts/dcunet_chorus_aug.ckpt"
60
+ RandomPedalboardDelay:
61
+ model: ${dcunet}
62
+ ckpt_path: "ckpts/dcunet_delay_aug.ckpt"
63
+
64
+ inference_effects_ordering:
65
+ - "RandomPedalboardDistortion"
66
+ - "RandomPedalboardCompressor"
67
+ - "RandomPedalboardReverb"
68
+ - "RandomPedalboardChorus"
69
+ - "RandomPedalboardDelay"
70
+ num_bins: 1025
71
+ inference_effects_shuffle: True
72
+ inference_use_all_effect_models: False
cfg/exp/reverb.yaml CHANGED
@@ -1,28 +1,25 @@
1
  # @package _global_
2
  defaults:
3
- - override /model: demucs
4
  - override /effects: all
5
  seed: 12345
6
  sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
- render_root: "/scratch/EffectSet"
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
14
- num_kept_effects: [0,4] # [min, max]
15
  num_removed_effects: [1,1] # [min, max]
16
  shuffle_kept_effects: True
17
  shuffle_removed_effects: False
18
- num_classes: 5
19
  effects_to_keep:
20
- - compressor
21
- - distortion
22
- - chorus
23
- - delay
24
  effects_to_remove:
25
  - reverb
26
  datamodule:
27
- batch_size: 16
 
28
  num_workers: 8
 
1
  # @package _global_
2
  defaults:
3
+ - override /model: dcunet
4
  - override /effects: all
5
  seed: 12345
6
  sample_rate: 48000
7
  chunk_size: 262144 # 5.5s
8
  logs_dir: "./logs"
9
  render_files: True
10
+
11
  accelerator: "gpu"
12
  log_audio: True
13
  # Effects
14
+ num_kept_effects: [0,0] # [min, max]
15
  num_removed_effects: [1,1] # [min, max]
16
  shuffle_kept_effects: True
17
  shuffle_removed_effects: False
18
+ num_classes: 1
19
  effects_to_keep:
 
 
 
 
20
  effects_to_remove:
21
  - reverb
22
  datamodule:
23
+ train_batch_size: 16
24
+ test_batch_size: 1
25
  num_workers: 8
cfg/exp/reverb_aug.yaml ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # @package _global_
2
+ defaults:
3
+ - override /model: dcunet
4
+ - override /effects: all
5
+ seed: 12345
6
+ sample_rate: 48000
7
+ chunk_size: 262144 # 5.5s
8
+ logs_dir: "./logs"
9
+ render_files: True
10
+
11
+ accelerator: "gpu"
12
+ log_audio: True
13
+ # Effects
14
+ num_kept_effects: [0,4] # [min, max]
15
+ num_removed_effects: [1,1] # [min, max]
16
+ shuffle_kept_effects: True
17
+ shuffle_removed_effects: False
18
+ num_classes: 5
19
+ effects_to_keep:
20
+ - compressor
21
+ - distortion
22
+ - chorus
23
+ - delay
24
+ effects_to_remove:
25
+ - reverb
26
+ datamodule:
27
+ train_batch_size: 16
28
+ test_batch_size: 1
29
+ num_workers: 8
cfg/model/audio_diffusion.yaml DELETED
@@ -1,16 +0,0 @@
1
- # @package _global_
2
- model:
3
- _target_: remfx.models.RemFX
4
- lr: 1e-4
5
- lr_beta1: 0.95
6
- lr_beta2: 0.999
7
- lr_eps: 1e-6
8
- lr_weight_decay: 1e-3
9
- sample_rate: ${sample_rate}
10
- network:
11
- _target_: remfx.models.DiffusionGenerationModel
12
- n_channels: 1
13
- datamodule:
14
- dataset:
15
- effect_types: ["Clean"]
16
- batch_size: 2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
diffusion_test2.ipynb DELETED
@@ -1,188 +0,0 @@
1
- {
2
- "cells": [
3
- {
4
- "cell_type": "code",
5
- "execution_count": 27,
6
- "id": "4c52cc1c-91f1-4b79-924b-041d2929ef7b",
7
- "metadata": {},
8
- "outputs": [],
9
- "source": [
10
- "from audio_diffusion_pytorch import AudioDiffusionModel\n",
11
- "import torch\n",
12
- "from IPython.display import Audio\n",
13
- "import matplotlib.pyplot as plt\n",
14
- "from tqdm import tqdm\n",
15
- "import numpy as np"
16
- ]
17
- },
18
- {
19
- "cell_type": "code",
20
- "execution_count": 28,
21
- "id": "a005011f-3019-4d34-bdf2-9a00e5480282",
22
- "metadata": {},
23
- "outputs": [],
24
- "source": [
25
- "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")"
26
- ]
27
- },
28
- {
29
- "cell_type": "code",
30
- "execution_count": 29,
31
- "id": "1b689f18-375f-4b40-9ddc-a4ced6a5e5e4",
32
- "metadata": {},
33
- "outputs": [],
34
- "source": [
35
- "model = AudioDiffusionModel(in_channels=1, \n",
36
- " patch_size=1,\n",
37
- " multipliers=[1, 2, 4, 4, 4, 4, 4],\n",
38
- " factors=[2, 2, 2, 2, 2, 2],\n",
39
- " num_blocks=[2, 2, 2, 2, 2, 2],\n",
40
- " attentions=[0, 0, 0, 0, 0, 0]\n",
41
- " )\n",
42
- "model = model.to(device)"
43
- ]
44
- },
45
- {
46
- "cell_type": "code",
47
- "execution_count": 30,
48
- "id": "bd8a1cb4-42b5-43bc-9a12-f594ce069b33",
49
- "metadata": {},
50
- "outputs": [
51
- {
52
- "name": "stdout",
53
- "output_type": "stream",
54
- "text": [
55
- "torch.Size([1, 32768])\n"
56
- ]
57
- }
58
- ],
59
- "source": [
60
- "fs = 22050\n",
61
- "t = 32768\n",
62
- "fc_min = 220\n",
63
- "fc_max = 440\n",
64
- "batch_size = 8\n",
65
- "samples = torch.arange(t) / fs\n",
66
- "n_iters = 1000\n",
67
- "\n",
68
- "samples = samples.view(1, -1)\n",
69
- "print(samples.shape)\n",
70
- "\n",
71
- "lr = 1e-4\n",
72
- "optimizer = torch.optim.Adam(model.parameters(), lr, betas=(0.95, 0.999), eps=1e-6, weight_decay=1e-3)"
73
- ]
74
- },
75
- {
76
- "cell_type": "code",
77
- "execution_count": 31,
78
- "id": "01265072",
79
- "metadata": {
80
- "scrolled": true
81
- },
82
- "outputs": [
83
- {
84
- "name": "stderr",
85
- "output_type": "stream",
86
- "text": [
87
- "999 - loss step: 0.0457 loss mean: 0.1161: 100%|██████████████████████████████████████████████████████████████████████| 1000/1000 [09:38<00:00, 1.73it/s]\n"
88
- ]
89
- }
90
- ],
91
- "source": [
92
- "losses = []\n",
93
- "pbar = tqdm(range(n_iters))\n",
94
- "for i in pbar:\n",
95
- " \n",
96
- " optimizer.zero_grad()\n",
97
- " \n",
98
- " # create a batch of random sine waves\n",
99
- " f = torch.randint(fc_min, fc_max, [batch_size,1])\n",
100
- " signals = torch.sin(2 * torch.pi * f * samples)\n",
101
- " signals = signals.view(batch_size, 1, -1)\n",
102
- " signals = signals.to(device)\n",
103
- "\n",
104
- " loss = model(signals)\n",
105
- " loss.backward() \n",
106
- " optimizer.step()\n",
107
- " \n",
108
- " losses.append(loss.item())\n",
109
- " pbar.set_description(f\"{i} - loss step: {loss.item():0.4f} loss mean: {np.mean(losses):0.4f}\")"
110
- ]
111
- },
112
- {
113
- "cell_type": "code",
114
- "execution_count": 38,
115
- "id": "71d17c51-842c-40a1-81a1-a53bf358bc8a",
116
- "metadata": {},
117
- "outputs": [],
118
- "source": [
119
- "# Sample 2 sources given start noise\n",
120
- "noise = torch.randn(1, 1, t)\n",
121
- "noise = noise.to(device)\n",
122
- "sampled = model.sample(\n",
123
- " noise=noise,\n",
124
- " num_steps=50 # Suggested range: 2-50\n",
125
- ") # [2, 1, 2 ** 18]"
126
- ]
127
- },
128
- {
129
- "cell_type": "code",
130
- "execution_count": 39,
131
- "id": "59d71efa-05ac-4545-84da-8c09c033dfd7",
132
- "metadata": {},
133
- "outputs": [
134
- {
135
- "data": {
136
- "text/html": [
137
- "\n",
138
- " <audio controls=\"controls\" >\n",
139
- " <source src=\"data:audio/wav;base64,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\" type=\"audio/wav\" />\n",
140
- " Your browser does not support the audio element.\n",
141
- " </audio>\n",
142
- " "
143
- ],
144
- "text/plain": [
145
- "<IPython.lib.display.Audio object>"
146
- ]
147
- },
148
- "execution_count": 39,
149
- "metadata": {},
150
- "output_type": "execute_result"
151
- }
152
- ],
153
- "source": [
154
- "z = sampled[0]\n",
155
- "Audio(z.cpu(), rate=22050)"
156
- ]
157
- },
158
- {
159
- "cell_type": "code",
160
- "execution_count": null,
161
- "id": "81eddd71-bba7-4c62-8d50-900b295bb2f8",
162
- "metadata": {},
163
- "outputs": [],
164
- "source": []
165
- }
166
- ],
167
- "metadata": {
168
- "kernelspec": {
169
- "display_name": "Python 3 (ipykernel)",
170
- "language": "python",
171
- "name": "python3"
172
- },
173
- "language_info": {
174
- "codemirror_mode": {
175
- "name": "ipython",
176
- "version": 3
177
- },
178
- "file_extension": ".py",
179
- "mimetype": "text/x-python",
180
- "name": "python",
181
- "nbconvert_exporter": "python",
182
- "pygments_lexer": "ipython3",
183
- "version": "3.9.5"
184
- }
185
- },
186
- "nbformat": 4,
187
- "nbformat_minor": 5
188
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
download_ckpts.sh ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #! /bin/bash
2
+
3
+ # make ckpts directory if not exist
4
+ mkdir -p ckpts
5
+
6
+ # download ckpts and save to ckpts directory
7
+ wget https://zenodo.org/record/8179396/files/classifier.ckpt?download=1 -O ckpts/classifier.ckpt
8
+ wget https://zenodo.org/record/8179396/files/dcunet_chorus_aug.ckpt?download=1 -O ckpts/dcunet_chorus_aug.ckpt
9
+ wget https://zenodo.org/record/8179396/files/dcunet_delay_aug.ckpt?download=1 -O ckpts/dcunet_delay_aug.ckpt
10
+ wget https://zenodo.org/record/8179396/files/dcunet_reverb_aug.ckpt?download=1 -O ckpts/dcunet_reverb_aug.ckpt
11
+ wget https://zenodo.org/record/8179396/files/demucs_compressor_aug.ckpt?download=1 -O ckpts/demucs_compressor_aug.ckpt
12
+ wget https://zenodo.org/record/8179396/files/demucs_distortion_aug.ckpt?download=1 -O ckpts/demucs_distortion_aug.ckpt
download_eval_datasets.sh ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #! /bin/bash
2
+
3
+ mkdir -p RemFX_eval_datasets
4
+ cd RemFX_eval_datasets
5
+ mkdir -p processed
6
+ cd processed
7
+ wget https://zenodo.org/record/8187288/files/0-0.zip?download=1 -O 0-0.zip
8
+ wget https://zenodo.org/record/8187288/files/1-1.zip?download=1 -O 1-1.zip
9
+ wget https://zenodo.org/record/8187288/files/2-2.zip?download=1 -O 2-2.zip
10
+ wget https://zenodo.org/record/8187288/files/3-3.zip?download=1 -O 3-3.zip
11
+ wget https://zenodo.org/record/8187288/files/4-4.zip?download=1 -O 4-4.zip
12
+ wget https://zenodo.org/record/8187288/files/5-5.zip?download=1 -O 5-5.zip
13
+ unzip 0-0.zip
14
+ unzip 1-1.zip
15
+ unzip 2-2.zip
16
+ unzip 3-3.zip
17
+ unzip 4-4.zip
18
+ unzip 5-5.zip
19
+ rm 0-0.zip
20
+ rm 1-1.zip
21
+ rm 2-2.zip
22
+ rm 3-3.zip
23
+ rm 4-4.zip
24
+ rm 5-5.zip
25
+
eval.sh ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #! /bin/bash
2
+
3
+ # Example usage:
4
+ # ./eval.sh remfx_detect 0-0
5
+ # ./eval.sh distortion_aug 0-0 -ckpt logs/ckpts/2023-01-21-12-21-44
6
+ # First 2 arguments are required, third argument is optional
7
+
8
+ # Default value for the optional parameter
9
+ ckpt_path=""
10
+
11
+ # Function to display script usage
12
+ function display_usage {
13
+ echo "Usage: $0 <experiment> <dataset> [-ckpt {ckpt_path}]"
14
+ }
15
+
16
+ # Check if the number of arguments is less than 2 (minimum required)
17
+ if [ "$#" -lt 2 ]; then
18
+ display_usage
19
+ exit 1
20
+ fi
21
+
22
+ dataset_name=$2
23
+
24
+ # Parse optional parameter if provided
25
+ if [ "$3" == "-ckpt" ]; then
26
+ # Check if the ckpt_path is provided
27
+ if [ -z "$4" ]; then
28
+ echo "Error: -ckpt flag requires a path argument."
29
+ display_usage
30
+ exit 1
31
+ fi
32
+ ckpt_path="$4"
33
+ fi
34
+
35
+ # If ckpt_path is empty, run chain inference
36
+ if [ -z "$ckpt_path" ]; then
37
+ echo "Running chain inference"
38
+ python scripts/chain_inference.py +exp=$1 datamodule.train_dataset=None datamodule.val_dataset=None datamodule.test_dataset.render_root=./RemFX_eval_datasets/ render_files=False num_removed_effects=[${dataset_name:0:1},${dataset_name:2:1}]
39
+ exit 1
40
+ fi
41
+
42
+
43
+ # Otherwise run inference on the specified checkpoint
44
+ echo "Running monolithic inference on checkpoint $3"
45
+ python scripts/test.py +exp=$1 datamodule.train_dataset=None datamodule.val_dataset=None datamodule.test_dataset.render_root=./RemFX_eval_datasets/ datamodule.test_dataset.num_kept_effects="[0,0]" num_removed_effects=[${dataset_name:0:1},${dataset_name:2:1}] effects_to_keep=[] effects_to_remove="[distortion, compressor,reverb,chorus,delay]" render_files=False +ckpt_path=$ckpt_path
46
+
47
+
48
+
notebooks/Experiments.ipynb DELETED
The diff for this file is too large to render. See raw diff
 
notebooks/diffusion_test.ipynb DELETED
The diff for this file is too large to render. See raw diff
 
notebooks/egfx.ipynb DELETED
@@ -1,603 +0,0 @@
1
- {
2
- "cells": [
3
- {
4
- "cell_type": "code",
5
- "execution_count": 28,
6
- "metadata": {},
7
- "outputs": [],
8
- "source": [
9
- "import mirdata\n",
10
- "from torch.utils.data import Dataset, DataLoader\n",
11
- "import torchaudio\n",
12
- "import torchaudio.transforms as T\n",
13
- "import torch.nn.functional as F\n",
14
- "from pathlib import Path\n",
15
- "from typing import List\n",
16
- "import torch\n"
17
- ]
18
- },
19
- {
20
- "cell_type": "code",
21
- "execution_count": 24,
22
- "metadata": {},
23
- "outputs": [],
24
- "source": [
25
- "effect_type = [\"Phaser\"]\n",
26
- "root=Path(\"./data/egfx\")\n",
27
- "wet_files = []\n",
28
- "dry_files = []\n",
29
- "labels = []"
30
- ]
31
- },
32
- {
33
- "cell_type": "code",
34
- "execution_count": 18,
35
- "metadata": {},
36
- "outputs": [],
37
- "source": [
38
- "for i, effect in enumerate(effect_type):\n",
39
- " for pickup in Path(root / effect).iterdir():\n",
40
- " wet_files += list(pickup.glob(\"*.wav\"))\n",
41
- " dry_files += list(root.glob(f\"Clean/{pickup.name}/**/*.wav\"))\n",
42
- " \n",
43
- " labels += [i] * len(wet_files)\n"
44
- ]
45
- },
46
- {
47
- "cell_type": "code",
48
- "execution_count": 26,
49
- "metadata": {},
50
- "outputs": [],
51
- "source": [
52
- "LENGTH = 2**18 # 12 seconds\n",
53
- "ORIG_SR = 48000"
54
- ]
55
- },
56
- {
57
- "cell_type": "code",
58
- "execution_count": 27,
59
- "metadata": {},
60
- "outputs": [],
61
- "source": [
62
- "class GuitarFXDataset(Dataset):\n",
63
- " def __init__(\n",
64
- " self,\n",
65
- " root: str,\n",
66
- " sample_rate: int,\n",
67
- " length: int = LENGTH,\n",
68
- " effect_type: List[str] = None,\n",
69
- " ):\n",
70
- " self.length = length\n",
71
- " self.wet_files = []\n",
72
- " self.dry_files = []\n",
73
- " self.labels = []\n",
74
- " self.root = Path(root)\n",
75
- " if effect_type is None:\n",
76
- " effect_type = [\n",
77
- " d.name for d in self.root.iterdir() if d.is_dir() and d != \"Clean\"\n",
78
- " ]\n",
79
- " for i, effect in enumerate(effect_type):\n",
80
- " for pickup in Path(self.root / effect).iterdir():\n",
81
- " self.wet_files += sorted(list(pickup.glob(\"*.wav\")))\n",
82
- " self.dry_files += sorted(\n",
83
- " list(self.root.glob(f\"Clean/{pickup.name}/**/*.wav\"))\n",
84
- " )\n",
85
- " self.labels += [i] * len(self.wet_files)\n",
86
- " print(\n",
87
- " f\"Found {len(self.wet_files)} wet files and {len(self.dry_files)} dry files\"\n",
88
- " )\n",
89
- " self.resampler = T.Resample(ORIG_SR, sample_rate)\n",
90
- "\n",
91
- " def __len__(self):\n",
92
- " return len(self.dry_files)\n",
93
- "\n",
94
- " def __getitem__(self, idx):\n",
95
- " print(idx, self.wet_files[idx], self.dry_files[idx])\n",
96
- " x, sr = torchaudio.load(self.wet_files[idx])\n",
97
- " y, sr = torchaudio.load(self.dry_files[idx])\n",
98
- " effect_label = self.labels[idx]\n",
99
- "\n",
100
- " resampled_x = self.resampler(x)\n",
101
- " resampled_y = self.resampler(y)\n",
102
- " # Pad or crop to length\n",
103
- " if resampled_x.shape[-1] < self.length:\n",
104
- " resampled_x = F.pad(resampled_x, (0, self.length - resampled_x.shape[1]))\n",
105
- " elif resampled_x.shape[-1] > self.length:\n",
106
- " resampled_x = resampled_x[:, : self.length]\n",
107
- " if resampled_y.shape[-1] < self.length:\n",
108
- " resampled_y = F.pad(resampled_y, (0, self.length - resampled_y.shape[1]))\n",
109
- " elif resampled_y.shape[-1] > self.length:\n",
110
- " resampled_y = resampled_y[:, : self.length]\n",
111
- " return (resampled_x, resampled_y, effect_label)\n"
112
- ]
113
- },
114
- {
115
- "cell_type": "code",
116
- "execution_count": 29,
117
- "metadata": {},
118
- "outputs": [],
119
- "source": [
120
- "\n",
121
- "SAMPLE_RATE = 22050\n",
122
- "TRAIN_SPLIT = 0.8"
123
- ]
124
- },
125
- {
126
- "cell_type": "code",
127
- "execution_count": 32,
128
- "metadata": {},
129
- "outputs": [
130
- {
131
- "name": "stdout",
132
- "output_type": "stream",
133
- "text": [
134
- "Found 690 wet files and 690 dry files\n"
135
- ]
136
- }
137
- ],
138
- "source": [
139
- "guitfx = GuitarFXDataset(\n",
140
- " root=\"./data/egfx\",\n",
141
- " sample_rate=SAMPLE_RATE,\n",
142
- " effect_type=[\"Phaser\"],\n",
143
- ")"
144
- ]
145
- },
146
- {
147
- "cell_type": "code",
148
- "execution_count": 33,
149
- "metadata": {},
150
- "outputs": [],
151
- "source": [
152
- "train_size = int(TRAIN_SPLIT * len(guitfx))\n",
153
- "val_size = len(guitfx) - train_size\n",
154
- "train_dataset, val_dataset = torch.utils.data.random_split(\n",
155
- " guitfx, [train_size, val_size]\n",
156
- ")\n",
157
- "val = DataLoader(val_dataset, batch_size=2)\n"
158
- ]
159
- },
160
- {
161
- "cell_type": "markdown",
162
- "metadata": {},
163
- "source": []
164
- },
165
- {
166
- "cell_type": "code",
167
- "execution_count": 37,
168
- "metadata": {},
169
- "outputs": [
170
- {
171
- "name": "stdout",
172
- "output_type": "stream",
173
- "text": [
174
- "[560, 150, 218, 404, 292, 509, 10, 315, 554, 6, 169, 116, 601, 309, 280, 510, 559, 197, 613, 424, 500, 460, 273, 467, 190, 534, 642, 112, 635, 283, 217, 7, 679, 526, 73, 102, 134, 263, 449, 142, 215, 154, 181, 378, 425, 278, 208, 58, 323, 210, 388, 363, 249, 57, 479, 79, 508, 429, 237, 390, 435, 62, 254, 528, 614, 311, 680, 61, 374, 668, 373, 594, 9, 677, 188, 2, 91, 633, 549, 257, 170, 183, 465, 502, 244, 664, 632, 356, 581, 145, 81, 85, 232, 250, 571, 118, 319, 308, 536, 592, 607, 566, 609, 302, 576, 354, 35, 493, 593, 437, 636, 495, 506, 153, 638, 164, 229, 456, 34, 518, 381, 322, 304, 565, 52, 499, 66, 39, 220, 38, 111, 454, 267, 98, 563, 585, 121, 391]\n"
175
- ]
176
- }
177
- ],
178
- "source": [
179
- "print(val_dataset.indices)"
180
- ]
181
- },
182
- {
183
- "cell_type": "code",
184
- "execution_count": 38,
185
- "metadata": {},
186
- "outputs": [
187
- {
188
- "name": "stdout",
189
- "output_type": "stream",
190
- "text": [
191
- "[tensor([[[0.0482, 0.0772, 0.0682, ..., 0.0000, 0.0000, 0.0000]],\n",
192
- "\n",
193
- " [[0.0092, 0.0138, 0.0139, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[-0.0007, -0.0009, 0.0074, ..., 0.0000, 0.0000, 0.0000]],\n",
194
- "\n",
195
- " [[ 0.0007, 0.0036, 0.0064, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
196
- "[tensor([[[0.0027, 0.0050, 0.0063, ..., 0.0000, 0.0000, 0.0000]],\n",
197
- "\n",
198
- " [[0.0043, 0.0077, 0.0084, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0007, 0.0023, 0.0026, ..., 0.0000, 0.0000, 0.0000]],\n",
199
- "\n",
200
- " [[0.0005, 0.0023, 0.0034, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
201
- "[tensor([[[0.0008, 0.0017, 0.0056, ..., 0.0000, 0.0000, 0.0000]],\n",
202
- "\n",
203
- " [[0.0008, 0.0016, 0.0016, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0007, 0.0022, 0.0028, ..., 0.0000, 0.0000, 0.0000]],\n",
204
- "\n",
205
- " [[0.0003, 0.0009, 0.0011, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
206
- "[tensor([[[ 0.0071, 0.0107, 0.0078, ..., 0.0000, 0.0000, 0.0000]],\n",
207
- "\n",
208
- " [[ 0.0043, 0.0011, -0.0055, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[-0.0004, -0.0014, -0.0022, ..., 0.0000, 0.0000, 0.0000]],\n",
209
- "\n",
210
- " [[ 0.0013, 0.0045, 0.0072, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
211
- "[tensor([[[0.0022, 0.0036, 0.0059, ..., 0.0000, 0.0000, 0.0000]],\n",
212
- "\n",
213
- " [[0.0431, 0.0687, 0.0638, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[ 0.0009, 0.0030, 0.0047, ..., 0.0000, 0.0000, 0.0000]],\n",
214
- "\n",
215
- " [[-0.0001, -0.0012, -0.0022, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
216
- "[tensor([[[ 0.0053, 0.0082, 0.0058, ..., 0.0000, 0.0000, 0.0000]],\n",
217
- "\n",
218
- " [[-0.0035, -0.0036, -0.0021, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[ 0.0003, 0.0019, 0.0038, ..., 0.0000, 0.0000, 0.0000]],\n",
219
- "\n",
220
- " [[-0.0003, -0.0029, -0.0058, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
221
- "[tensor([[[ 0.0069, 0.0106, 0.0078, ..., 0.0000, 0.0000, 0.0000]],\n",
222
- "\n",
223
- " [[-0.0035, -0.0040, -0.0034, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[ 0.0003, 0.0010, 0.0034, ..., 0.0000, 0.0000, 0.0000]],\n",
224
- "\n",
225
- " [[-0.0020, -0.0076, -0.0117, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
226
- "[tensor([[[ 0.0044, 0.0086, 0.0079, ..., 0.0000, 0.0000, 0.0000]],\n",
227
- "\n",
228
- " [[-0.0016, -0.0022, -0.0014, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[-0.0006, -0.0020, -0.0020, ..., 0.0000, 0.0000, 0.0000]],\n",
229
- "\n",
230
- " [[-0.0002, -0.0009, -0.0017, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
231
- "[tensor([[[0.0027, 0.0027, 0.0002, ..., 0.0000, 0.0000, 0.0000]],\n",
232
- "\n",
233
- " [[0.0033, 0.0048, 0.0028, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0008, 0.0035, 0.0059, ..., 0.0000, 0.0000, 0.0000]],\n",
234
- "\n",
235
- " [[0.0002, 0.0006, 0.0011, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
236
- "[tensor([[[ 0.0056, 0.0341, 0.0562, ..., 0.0000, 0.0000, 0.0000]],\n",
237
- "\n",
238
- " [[-0.0009, -0.0013, -0.0002, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0021, 0.0092, 0.0056, ..., 0.0000, 0.0000, 0.0000]],\n",
239
- "\n",
240
- " [[0.0007, 0.0021, 0.0023, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
241
- "[tensor([[[ 0.0014, 0.0024, 0.0030, ..., 0.0000, 0.0000, 0.0000]],\n",
242
- "\n",
243
- " [[-0.1450, -0.1390, -0.0209, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[ 2.6921e-04, 1.6453e-03, 2.7682e-03, ..., 0.0000e+00,\n",
244
- " 0.0000e+00, 0.0000e+00]],\n",
245
- "\n",
246
- " [[-3.2024e-02, -1.9613e-01, -4.0412e-01, ..., 0.0000e+00,\n",
247
- " 0.0000e+00, 0.0000e+00]]]), tensor([0, 0])]\n",
248
- "[tensor([[[-0.0059, -0.0064, -0.0022, ..., 0.0000, 0.0000, 0.0000]],\n",
249
- "\n",
250
- " [[-0.0039, -0.0046, -0.0021, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[-0.0002, -0.0021, -0.0037, ..., 0.0000, 0.0000, 0.0000]],\n",
251
- "\n",
252
- " [[-0.0004, -0.0017, -0.0031, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
253
- "[tensor([[[ 0.0086, 0.0122, 0.0111, ..., 0.0000, 0.0000, 0.0000]],\n",
254
- "\n",
255
- " [[-0.0114, -0.0113, -0.0039, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[ 0.0004, 0.0043, 0.0085, ..., 0.0000, 0.0000, 0.0000]],\n",
256
- "\n",
257
- " [[-0.0010, -0.0059, -0.0108, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
258
- "[tensor([[[0.0069, 0.0105, 0.0097, ..., 0.0000, 0.0000, 0.0000]],\n",
259
- "\n",
260
- " [[0.0069, 0.0100, 0.0067, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[1.4215e-04, 2.1199e-03, 5.7695e-03, ..., 0.0000e+00,\n",
261
- " 0.0000e+00, 0.0000e+00]],\n",
262
- "\n",
263
- " [[9.1938e-05, 1.1531e-03, 2.8006e-03, ..., 0.0000e+00,\n",
264
- " 0.0000e+00, 0.0000e+00]]]), tensor([0, 0])]\n",
265
- "[tensor([[[0.0012, 0.0038, 0.0057, ..., 0.0000, 0.0000, 0.0000]],\n",
266
- "\n",
267
- " [[0.0035, 0.0058, 0.0088, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0004, 0.0013, 0.0014, ..., 0.0000, 0.0000, 0.0000]],\n",
268
- "\n",
269
- " [[0.0003, 0.0022, 0.0044, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
270
- "[tensor([[[ 0.0011, 0.0023, 0.0030, ..., 0.0000, 0.0000, 0.0000]],\n",
271
- "\n",
272
- " [[-0.0033, -0.0038, -0.0007, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0003, 0.0023, 0.0041, ..., 0.0000, 0.0000, 0.0000]],\n",
273
- "\n",
274
- " [[0.0005, 0.0038, 0.0079, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
275
- "[tensor([[[ 0.0020, -0.0012, -0.0042, ..., 0.0000, 0.0000, 0.0000]],\n",
276
- "\n",
277
- " [[ 0.0035, 0.0056, 0.0063, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0013, 0.0048, 0.0063, ..., 0.0000, 0.0000, 0.0000]],\n",
278
- "\n",
279
- " [[0.0005, 0.0026, 0.0049, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
280
- "[tensor([[[-0.0033, -0.0054, -0.0052, ..., 0.0000, 0.0000, 0.0000]],\n",
281
- "\n",
282
- " [[ 0.0031, 0.0057, 0.0069, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0021, 0.0064, 0.0081, ..., 0.0000, 0.0000, 0.0000]],\n",
283
- "\n",
284
- " [[0.0004, 0.0015, 0.0021, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
285
- "[tensor([[[-0.0023, -0.0059, -0.0074, ..., 0.0000, 0.0000, 0.0000]],\n",
286
- "\n",
287
- " [[ 0.0087, 0.0125, 0.0101, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[-0.0004, -0.0011, -0.0011, ..., 0.0000, 0.0000, 0.0000]],\n",
288
- "\n",
289
- " [[ 0.0019, 0.0071, 0.0113, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
290
- "[tensor([[[ 0.0046, 0.0039, -0.0007, ..., 0.0000, 0.0000, 0.0000]],\n",
291
- "\n",
292
- " [[ 0.0038, 0.0021, 0.0117, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0003, 0.0024, 0.0042, ..., 0.0000, 0.0000, 0.0000]],\n",
293
- "\n",
294
- " [[0.0048, 0.0240, 0.0323, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
295
- "[tensor([[[ 0.0064, 0.0104, 0.0116, ..., 0.0000, 0.0000, 0.0000]],\n",
296
- "\n",
297
- " [[-0.0028, -0.0033, -0.0007, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0010, 0.0047, 0.0074, ..., 0.0000, 0.0000, 0.0000]],\n",
298
- "\n",
299
- " [[0.0005, 0.0013, 0.0009, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
300
- "[tensor([[[0.0042, 0.0073, 0.0064, ..., 0.0000, 0.0000, 0.0000]],\n",
301
- "\n",
302
- " [[0.0015, 0.0029, 0.0041, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0007, 0.0026, 0.0033, ..., 0.0000, 0.0000, 0.0000]],\n",
303
- "\n",
304
- " [[0.0004, 0.0016, 0.0026, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
305
- "[tensor([[[-0.0016, -0.0054, -0.0048, ..., 0.0000, 0.0000, 0.0000]],\n",
306
- "\n",
307
- " [[ 0.0113, 0.0209, 0.0223, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[ 0.0014, 0.0034, 0.0026, ..., 0.0000, 0.0000, 0.0000]],\n",
308
- "\n",
309
- " [[-0.0004, -0.0024, -0.0011, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
310
- "[tensor([[[ 0.0064, 0.0108, 0.0107, ..., 0.0000, 0.0000, 0.0000]],\n",
311
- "\n",
312
- " [[-0.0007, -0.0040, -0.0083, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0005, 0.0018, 0.0035, ..., 0.0000, 0.0000, 0.0000]],\n",
313
- "\n",
314
- " [[0.0002, 0.0008, 0.0012, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
315
- "[tensor([[[ 0.0071, 0.0064, -0.0008, ..., 0.0000, 0.0000, 0.0000]],\n",
316
- "\n",
317
- " [[ 0.0024, 0.0039, 0.0042, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0018, 0.0064, 0.0094, ..., 0.0000, 0.0000, 0.0000]],\n",
318
- "\n",
319
- " [[0.0001, 0.0008, 0.0019, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
320
- "[tensor([[[0.0075, 0.0099, 0.0065, ..., 0.0000, 0.0000, 0.0000]],\n",
321
- "\n",
322
- " [[0.0008, 0.0010, 0.0005, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0007, 0.0032, 0.0058, ..., 0.0000, 0.0000, 0.0000]],\n",
323
- "\n",
324
- " [[0.0006, 0.0023, 0.0029, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
325
- "[tensor([[[-0.0024, -0.0027, -0.0021, ..., 0.0000, 0.0000, 0.0000]],\n",
326
- "\n",
327
- " [[ 0.0096, 0.0151, 0.0139, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[-0.0003, -0.0012, -0.0023, ..., 0.0000, 0.0000, 0.0000]],\n",
328
- "\n",
329
- " [[-0.0001, -0.0010, -0.0015, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
330
- "[tensor([[[0.0012, 0.0027, 0.0036, ..., 0.0000, 0.0000, 0.0000]],\n",
331
- "\n",
332
- " [[0.0030, 0.0039, 0.0039, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[ 0.0005, 0.0015, 0.0021, ..., 0.0000, 0.0000, 0.0000]],\n",
333
- "\n",
334
- " [[-0.0003, -0.0010, -0.0016, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
335
- "[tensor([[[ 0.0006, 0.0012, 0.0014, ..., 0.0000, 0.0000, 0.0000]],\n",
336
- "\n",
337
- " [[-0.0033, -0.0041, -0.0015, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[ 0.0001, 0.0003, 0.0002, ..., 0.0000, 0.0000, 0.0000]],\n",
338
- "\n",
339
- " [[-0.0005, -0.0021, -0.0035, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
340
- "[tensor([[[0.0041, 0.0051, 0.0031, ..., 0.0000, 0.0000, 0.0000]],\n",
341
- "\n",
342
- " [[0.0005, 0.0005, 0.0005, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0006, 0.0025, 0.0042, ..., 0.0000, 0.0000, 0.0000]],\n",
343
- "\n",
344
- " [[0.0006, 0.0015, 0.0015, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
345
- "[tensor([[[0.0111, 0.0142, 0.0113, ..., 0.0000, 0.0000, 0.0000]],\n",
346
- "\n",
347
- " [[0.0015, 0.0030, 0.0035, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[ 4.1647e-04, 3.4729e-03, 9.2547e-03, ..., 0.0000e+00,\n",
348
- " 0.0000e+00, 0.0000e+00]],\n",
349
- "\n",
350
- " [[-6.6249e-05, -7.6026e-04, -1.4447e-03, ..., 0.0000e+00,\n",
351
- " 0.0000e+00, 0.0000e+00]]]), tensor([0, 0])]\n",
352
- "[tensor([[[-0.0004, 0.0005, 0.0029, ..., 0.0000, 0.0000, 0.0000]],\n",
353
- "\n",
354
- " [[ 0.0025, 0.0042, 0.0035, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0004, 0.0015, 0.0015, ..., 0.0000, 0.0000, 0.0000]],\n",
355
- "\n",
356
- " [[0.0005, 0.0011, 0.0017, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
357
- "[tensor([[[ 0.0009, 0.0009, 0.0006, ..., 0.0000, 0.0000, 0.0000]],\n",
358
- "\n",
359
- " [[ 0.0147, 0.0051, -0.0118, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0008, 0.0028, 0.0037, ..., 0.0000, 0.0000, 0.0000]],\n",
360
- "\n",
361
- " [[0.0010, 0.0134, 0.0304, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
362
- "[tensor([[[0.0015, 0.0026, 0.0049, ..., 0.0000, 0.0000, 0.0000]],\n",
363
- "\n",
364
- " [[0.0030, 0.0060, 0.0081, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0003, 0.0015, 0.0035, ..., 0.0000, 0.0000, 0.0000]],\n",
365
- "\n",
366
- " [[0.0002, 0.0010, 0.0015, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
367
- "[tensor([[[ 0.0019, 0.0052, 0.0092, ..., 0.0000, 0.0000, 0.0000]],\n",
368
- "\n",
369
- " [[-0.0031, -0.0043, -0.0041, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[ 0.0002, 0.0005, 0.0007, ..., 0.0000, 0.0000, 0.0000]],\n",
370
- "\n",
371
- " [[-0.0010, -0.0047, -0.0077, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
372
- "[tensor([[[ 0.0014, 0.0019, 0.0014, ..., 0.0000, 0.0000, 0.0000]],\n",
373
- "\n",
374
- " [[ 0.0005, -0.0015, -0.0017, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0002, 0.0011, 0.0020, ..., 0.0000, 0.0000, 0.0000]],\n",
375
- "\n",
376
- " [[0.0008, 0.0032, 0.0038, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
377
- "[tensor([[[0.0097, 0.0098, 0.0010, ..., 0.0000, 0.0000, 0.0000]],\n",
378
- "\n",
379
- " [[0.0106, 0.0109, 0.0012, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[-0.0003, -0.0013, -0.0023, ..., 0.0000, 0.0000, 0.0000]],\n",
380
- "\n",
381
- " [[ 0.0002, 0.0021, 0.0052, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
382
- "[tensor([[[ 0.0030, 0.0057, 0.0084, ..., 0.0000, 0.0000, 0.0000]],\n",
383
- "\n",
384
- " [[-0.0037, -0.0044, -0.0016, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0013, 0.0051, 0.0077, ..., 0.0000, 0.0000, 0.0000]],\n",
385
- "\n",
386
- " [[0.0002, 0.0006, 0.0007, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
387
- "[tensor([[[ 0.0050, 0.0078, 0.0072, ..., 0.0000, 0.0000, 0.0000]],\n",
388
- "\n",
389
- " [[-0.0022, -0.0033, -0.0034, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[ 0.0003, 0.0014, 0.0022, ..., 0.0000, 0.0000, 0.0000]],\n",
390
- "\n",
391
- " [[-0.0006, -0.0028, -0.0046, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
392
- "[tensor([[[-0.0014, -0.0020, -0.0014, ..., 0.0000, 0.0000, 0.0000]],\n",
393
- "\n",
394
- " [[ 0.0069, 0.0159, 0.0219, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[ 0.0002, 0.0004, -0.0001, ..., 0.0000, 0.0000, 0.0000]],\n",
395
- "\n",
396
- " [[ 0.0008, 0.0033, 0.0045, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
397
- "[tensor([[[-0.0027, -0.0035, -0.0092, ..., 0.0000, 0.0000, 0.0000]],\n",
398
- "\n",
399
- " [[-0.0004, 0.0005, 0.0015, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[-0.0029, -0.0107, -0.0177, ..., 0.0000, 0.0000, 0.0000]],\n",
400
- "\n",
401
- " [[ 0.0006, 0.0013, 0.0007, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
402
- "[tensor([[[ 0.0286, 0.0299, 0.0081, ..., 0.0000, 0.0000, 0.0000]],\n",
403
- "\n",
404
- " [[-0.0002, 0.0009, 0.0020, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[-2.5037e-03, -1.1195e-03, 1.1923e-02, ..., 0.0000e+00,\n",
405
- " 0.0000e+00, 0.0000e+00]],\n",
406
- "\n",
407
- " [[ 1.5308e-04, -3.6808e-05, -5.5343e-04, ..., 0.0000e+00,\n",
408
- " 0.0000e+00, 0.0000e+00]]]), tensor([0, 0])]\n",
409
- "[tensor([[[0.0018, 0.0027, 0.0019, ..., 0.0000, 0.0000, 0.0000]],\n",
410
- "\n",
411
- " [[0.0055, 0.0096, 0.0124, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0002, 0.0022, 0.0032, ..., 0.0000, 0.0000, 0.0000]],\n",
412
- "\n",
413
- " [[0.0002, 0.0017, 0.0032, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
414
- "[tensor([[[ 3.7041e-03, 5.7321e-03, 5.1036e-03, ..., 0.0000e+00,\n",
415
- " 0.0000e+00, 0.0000e+00]],\n",
416
- "\n",
417
- " [[ 2.1164e-03, 1.5563e-03, -7.2010e-05, ..., 0.0000e+00,\n",
418
- " 0.0000e+00, 0.0000e+00]]]), tensor([[[0.0013, 0.0040, 0.0052, ..., 0.0000, 0.0000, 0.0000]],\n",
419
- "\n",
420
- " [[0.0002, 0.0009, 0.0017, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
421
- "[tensor([[[-0.0020, -0.0022, -0.0008, ..., 0.0000, 0.0000, 0.0000]],\n",
422
- "\n",
423
- " [[ 0.0088, 0.0130, 0.0157, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[-4.7201e-05, -2.4349e-04, -5.1608e-04, ..., 0.0000e+00,\n",
424
- " 0.0000e+00, 0.0000e+00]],\n",
425
- "\n",
426
- " [[ 1.2934e-03, 4.1513e-03, 3.6547e-03, ..., 0.0000e+00,\n",
427
- " 0.0000e+00, 0.0000e+00]]]), tensor([0, 0])]\n",
428
- "[tensor([[[0.0018, 0.0069, 0.0096, ..., 0.0000, 0.0000, 0.0000]],\n",
429
- "\n",
430
- " [[0.0026, 0.0024, 0.0006, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[ 3.0634e-04, 1.1319e-03, 1.7446e-03, ..., 0.0000e+00,\n",
431
- " 0.0000e+00, 0.0000e+00]],\n",
432
- "\n",
433
- " [[-8.3813e-05, -7.7285e-04, -1.7113e-03, ..., 0.0000e+00,\n",
434
- " 0.0000e+00, 0.0000e+00]]]), tensor([0, 0])]\n",
435
- "[tensor([[[0.0009, 0.0013, 0.0017, ..., 0.0000, 0.0000, 0.0000]],\n",
436
- "\n",
437
- " [[0.0070, 0.0122, 0.0151, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0001, 0.0013, 0.0024, ..., 0.0000, 0.0000, 0.0000]],\n",
438
- "\n",
439
- " [[0.0008, 0.0034, 0.0060, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
440
- "[tensor([[[0.0075, 0.0141, 0.0187, ..., 0.0000, 0.0000, 0.0000]],\n",
441
- "\n",
442
- " [[0.0023, 0.0025, 0.0019, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0002, 0.0012, 0.0024, ..., 0.0000, 0.0000, 0.0000]],\n",
443
- "\n",
444
- " [[0.0007, 0.0028, 0.0046, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
445
- "[tensor([[[ 0.0115, -0.0051, -0.0278, ..., 0.0000, 0.0000, 0.0000]],\n",
446
- "\n",
447
- " [[ 0.0212, 0.0099, -0.0170, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0042, 0.0199, 0.0318, ..., 0.0000, 0.0000, 0.0000]],\n",
448
- "\n",
449
- " [[0.0018, 0.0141, 0.0247, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
450
- "[tensor([[[ 0.0010, -0.0022, -0.0045, ..., 0.0000, 0.0000, 0.0000]],\n",
451
- "\n",
452
- " [[ 0.0068, 0.0116, 0.0121, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0005, 0.0037, 0.0072, ..., 0.0000, 0.0000, 0.0000]],\n",
453
- "\n",
454
- " [[0.0002, 0.0015, 0.0030, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
455
- "[tensor([[[ 0.0081, 0.0120, 0.0105, ..., 0.0000, 0.0000, 0.0000]],\n",
456
- "\n",
457
- " [[-0.0209, -0.0408, -0.0275, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0007, 0.0027, 0.0050, ..., 0.0000, 0.0000, 0.0000]],\n",
458
- "\n",
459
- " [[0.0037, 0.0249, 0.0292, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
460
- "[tensor([[[0.0067, 0.0102, 0.0098, ..., 0.0000, 0.0000, 0.0000]],\n",
461
- "\n",
462
- " [[0.0144, 0.0246, 0.0242, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[2.0850e-04, 2.0092e-03, 4.8804e-03, ..., 0.0000e+00,\n",
463
- " 0.0000e+00, 0.0000e+00]],\n",
464
- "\n",
465
- " [[5.1832e-05, 1.2148e-03, 4.0634e-03, ..., 0.0000e+00,\n",
466
- " 0.0000e+00, 0.0000e+00]]]), tensor([0, 0])]\n",
467
- "[tensor([[[-0.0024, -0.0024, -0.0013, ..., 0.0000, 0.0000, 0.0000]],\n",
468
- "\n",
469
- " [[ 0.0046, 0.0079, 0.0074, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[-0.0005, -0.0025, -0.0036, ..., 0.0000, 0.0000, 0.0000]],\n",
470
- "\n",
471
- " [[ 0.0003, 0.0010, 0.0017, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
472
- "[tensor([[[-0.0109, -0.0121, -0.0033, ..., 0.0000, 0.0000, 0.0000]],\n",
473
- "\n",
474
- " [[ 0.0011, 0.0015, 0.0020, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0001, 0.0005, 0.0006, ..., 0.0000, 0.0000, 0.0000]],\n",
475
- "\n",
476
- " [[0.0002, 0.0008, 0.0010, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
477
- "[tensor([[[-0.0015, -0.0018, -0.0014, ..., 0.0000, 0.0000, 0.0000]],\n",
478
- "\n",
479
- " [[-0.0083, -0.0828, -0.1668, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[-0.0006, -0.0017, -0.0014, ..., 0.0000, 0.0000, 0.0000]],\n",
480
- "\n",
481
- " [[-0.0118, -0.0768, -0.1046, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
482
- "[tensor([[[ 0.0106, -0.0040, -0.0246, ..., 0.0000, 0.0000, 0.0000]],\n",
483
- "\n",
484
- " [[ 0.0028, 0.0043, 0.0036, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0040, 0.0172, 0.0272, ..., 0.0000, 0.0000, 0.0000]],\n",
485
- "\n",
486
- " [[0.0002, 0.0016, 0.0027, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
487
- "[tensor([[[ 0.0020, 0.0005, -0.0163, ..., 0.0000, 0.0000, 0.0000]],\n",
488
- "\n",
489
- " [[ 0.0065, 0.0113, 0.0133, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[-0.0019, -0.0107, -0.0205, ..., 0.0000, 0.0000, 0.0000]],\n",
490
- "\n",
491
- " [[ 0.0007, 0.0026, 0.0040, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
492
- "[tensor([[[0.0010, 0.0020, 0.0023, ..., 0.0000, 0.0000, 0.0000]],\n",
493
- "\n",
494
- " [[0.0112, 0.0147, 0.0106, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0005, 0.0010, 0.0009, ..., 0.0000, 0.0000, 0.0000]],\n",
495
- "\n",
496
- " [[0.0017, 0.0062, 0.0095, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
497
- "[tensor([[[-0.0007, -0.0016, -0.0019, ..., 0.0000, 0.0000, 0.0000]],\n",
498
- "\n",
499
- " [[ 0.0028, 0.0051, 0.0083, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[-0.0003, -0.0010, -0.0008, ..., 0.0000, 0.0000, 0.0000]],\n",
500
- "\n",
501
- " [[ 0.0011, 0.0045, 0.0069, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
502
- "[tensor([[[0.0078, 0.0125, 0.0115, ..., 0.0000, 0.0000, 0.0000]],\n",
503
- "\n",
504
- " [[0.0046, 0.0071, 0.0058, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[-7.1681e-05, -8.8706e-04, -1.7330e-03, ..., 0.0000e+00,\n",
505
- " 0.0000e+00, 0.0000e+00]],\n",
506
- "\n",
507
- " [[ 1.1175e-03, 2.9858e-03, 4.5334e-03, ..., 0.0000e+00,\n",
508
- " 0.0000e+00, 0.0000e+00]]]), tensor([0, 0])]\n",
509
- "[tensor([[[-0.0027, -0.0049, -0.0051, ..., 0.0000, 0.0000, 0.0000]],\n",
510
- "\n",
511
- " [[-0.0013, -0.0019, -0.0017, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[-0.0005, -0.0015, -0.0020, ..., 0.0000, 0.0000, 0.0000]],\n",
512
- "\n",
513
- " [[-0.0003, -0.0022, -0.0038, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
514
- "[tensor([[[0.0008, 0.0011, 0.0007, ..., 0.0000, 0.0000, 0.0000]],\n",
515
- "\n",
516
- " [[0.0004, 0.0012, 0.0014, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0007, 0.0024, 0.0034, ..., 0.0000, 0.0000, 0.0000]],\n",
517
- "\n",
518
- " [[0.0006, 0.0020, 0.0029, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
519
- "[tensor([[[-1.2539e-03, -6.1979e-04, 1.0325e-03, ..., 0.0000e+00,\n",
520
- " 0.0000e+00, 0.0000e+00]],\n",
521
- "\n",
522
- " [[ 6.1576e-05, 2.2814e-04, 9.5116e-04, ..., 0.0000e+00,\n",
523
- " 0.0000e+00, 0.0000e+00]]]), tensor([[[8.0004e-05, 1.0549e-03, 2.6432e-03, ..., 0.0000e+00,\n",
524
- " 0.0000e+00, 0.0000e+00]],\n",
525
- "\n",
526
- " [[7.4739e-05, 1.3412e-04, 1.7083e-04, ..., 0.0000e+00,\n",
527
- " 0.0000e+00, 0.0000e+00]]]), tensor([0, 0])]\n",
528
- "[tensor([[[ 0.0151, 0.0170, 0.0124, ..., 0.0000, 0.0000, 0.0000]],\n",
529
- "\n",
530
- " [[-0.0022, -0.0067, -0.0094, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[ 0.0005, 0.0016, 0.0019, ..., 0.0000, 0.0000, 0.0000]],\n",
531
- "\n",
532
- " [[-0.0001, -0.0019, -0.0042, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
533
- "[tensor([[[ 0.0006, 0.0013, 0.0020, ..., 0.0000, 0.0000, 0.0000]],\n",
534
- "\n",
535
- " [[-0.0153, -0.0197, -0.0135, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[7.0598e-04, 3.5944e-03, 4.8469e-03, ..., 0.0000e+00,\n",
536
- " 0.0000e+00, 0.0000e+00]],\n",
537
- "\n",
538
- " [[5.7171e-05, 3.5541e-04, 3.9973e-04, ..., 0.0000e+00,\n",
539
- " 0.0000e+00, 0.0000e+00]]]), tensor([0, 0])]\n",
540
- "[tensor([[[0.0013, 0.0020, 0.0025, ..., 0.0000, 0.0000, 0.0000]],\n",
541
- "\n",
542
- " [[0.0120, 0.0202, 0.0220, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0006, 0.0025, 0.0037, ..., 0.0000, 0.0000, 0.0000]],\n",
543
- "\n",
544
- " [[0.0004, 0.0027, 0.0058, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
545
- "[tensor([[[0.0029, 0.0039, 0.0064, ..., 0.0000, 0.0000, 0.0000]],\n",
546
- "\n",
547
- " [[0.0015, 0.0025, 0.0030, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0004, 0.0048, 0.0087, ..., 0.0000, 0.0000, 0.0000]],\n",
548
- "\n",
549
- " [[0.0003, 0.0012, 0.0022, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
550
- "[tensor([[[0.0034, 0.0093, 0.0100, ..., 0.0000, 0.0000, 0.0000]],\n",
551
- "\n",
552
- " [[0.0007, 0.0014, 0.0018, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[-0.0008, -0.0035, -0.0042, ..., 0.0000, 0.0000, 0.0000]],\n",
553
- "\n",
554
- " [[ 0.0003, 0.0016, 0.0028, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n",
555
- "[tensor([[[0.0022, 0.0047, 0.0062, ..., 0.0000, 0.0000, 0.0000]],\n",
556
- "\n",
557
- " [[0.0082, 0.0121, 0.0115, ..., 0.0000, 0.0000, 0.0000]]]), tensor([[[0.0013, 0.0045, 0.0062, ..., 0.0000, 0.0000, 0.0000]],\n",
558
- "\n",
559
- " [[0.0015, 0.0091, 0.0154, ..., 0.0000, 0.0000, 0.0000]]]), tensor([0, 0])]\n"
560
- ]
561
- }
562
- ],
563
- "source": [
564
- "for v in val:\n",
565
- " print(v)"
566
- ]
567
- },
568
- {
569
- "cell_type": "code",
570
- "execution_count": null,
571
- "metadata": {},
572
- "outputs": [],
573
- "source": []
574
- }
575
- ],
576
- "metadata": {
577
- "kernelspec": {
578
- "display_name": "env",
579
- "language": "python",
580
- "name": "python3"
581
- },
582
- "language_info": {
583
- "codemirror_mode": {
584
- "name": "ipython",
585
- "version": 3
586
- },
587
- "file_extension": ".py",
588
- "mimetype": "text/x-python",
589
- "name": "python",
590
- "nbconvert_exporter": "python",
591
- "pygments_lexer": "ipython3",
592
- "version": "3.9.13"
593
- },
594
- "orig_nbformat": 4,
595
- "vscode": {
596
- "interpreter": {
597
- "hash": "94173bdbcc3a07290a92586f1f41e17e9573695669854c49e68cc83ee6746035"
598
- }
599
- }
600
- },
601
- "nbformat": 4,
602
- "nbformat_minor": 2
603
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
notebooks/guitar_generation_test.ipynb DELETED
The diff for this file is too large to render. See raw diff
 
remfx/callbacks.py CHANGED
@@ -42,9 +42,7 @@ class AudioCallback(Callback):
42
  )
43
  self.log_train_audio = False
44
 
45
- def on_validation_batch_start(
46
- self, trainer, pl_module, batch, batch_idx, dataloader_idx
47
- ):
48
  x, target, _, rem_fx_labels = batch
49
  # Only run on first batch
50
  if batch_idx == 0 and self.log_audio:
@@ -92,6 +90,8 @@ def log_wandb_audio_batch(
92
  caption: str = "",
93
  max_items: int = 10,
94
  ):
 
 
95
  num_items = samples.shape[0]
96
  samples = rearrange(samples, "b c t -> b t c")
97
  for idx in range(num_items):
 
42
  )
43
  self.log_train_audio = False
44
 
45
+ def on_validation_batch_start(self, trainer, pl_module, batch, batch_idx):
 
 
46
  x, target, _, rem_fx_labels = batch
47
  # Only run on first batch
48
  if batch_idx == 0 and self.log_audio:
 
90
  caption: str = "",
91
  max_items: int = 10,
92
  ):
93
+ if type(logger) != pl.loggers.WandbLogger:
94
+ return
95
  num_items = samples.shape[0]
96
  samples = rearrange(samples, "b c t -> b t c")
97
  for idx in range(num_items):
remfx/classifier.py CHANGED
@@ -173,10 +173,10 @@ class Cnn14(nn.Module):
173
 
174
  self.fc1 = nn.Linear(2048, 2048, bias=True)
175
 
176
- # self.fc_audioset = nn.Linear(2048, num_classes, bias=True)
177
- self.heads = torch.nn.ModuleList()
178
- for _ in range(num_classes):
179
- self.heads.append(nn.Linear(2048, 1, bias=True))
180
 
181
  self.init_weight()
182
 
@@ -192,7 +192,7 @@ class Cnn14(nn.Module):
192
  def init_weight(self):
193
  init_bn(self.bn0)
194
  init_layer(self.fc1)
195
- # init_layer(self.fc_audioset)
196
 
197
  def forward(self, x: torch.Tensor, train: bool = False):
198
  """
@@ -212,12 +212,12 @@ class Cnn14(nn.Module):
212
  # axs[1].imshow(x[0, :, :, :].detach().squeeze().cpu().numpy())
213
  # plt.savefig("spec_augment.png", dpi=300)
214
 
215
- # x = x.permute(0, 2, 1, 3)
216
- # x = self.bn0(x)
217
- # x = x.permute(0, 2, 1, 3)
218
 
219
  # apply standardization
220
- x = (x - x.mean(dim=0, keepdim=True)) / x.std(dim=0, keepdim=True)
221
 
222
  x = self.conv_block1(x, pool_size=(2, 2), pool_type="avg")
223
  x = F.dropout(x, p=0.2, training=train)
@@ -239,13 +239,13 @@ class Cnn14(nn.Module):
239
  x = F.dropout(x, p=0.5, training=train)
240
  x = F.relu_(self.fc1(x))
241
 
242
- outputs = []
243
- for head in self.heads:
244
- outputs.append(torch.sigmoid(head(x)))
245
 
246
- # clipwise_output = self.fc_audioset(x)
247
-
248
- return outputs
249
 
250
 
251
  class ConvBlock(nn.Module):
 
173
 
174
  self.fc1 = nn.Linear(2048, 2048, bias=True)
175
 
176
+ self.fc_audioset = nn.Linear(2048, num_classes, bias=True)
177
+ # self.heads = torch.nn.ModuleList()
178
+ # for _ in range(num_classes):
179
+ # self.heads.append(nn.Linear(2048, 1, bias=True))
180
 
181
  self.init_weight()
182
 
 
192
  def init_weight(self):
193
  init_bn(self.bn0)
194
  init_layer(self.fc1)
195
+ init_layer(self.fc_audioset)
196
 
197
  def forward(self, x: torch.Tensor, train: bool = False):
198
  """
 
212
  # axs[1].imshow(x[0, :, :, :].detach().squeeze().cpu().numpy())
213
  # plt.savefig("spec_augment.png", dpi=300)
214
 
215
+ x = x.permute(0, 2, 1, 3)
216
+ x = self.bn0(x)
217
+ x = x.permute(0, 2, 1, 3)
218
 
219
  # apply standardization
220
+ # x = (x - x.mean(dim=0, keepdim=True)) / x.std(dim=0, keepdim=True)
221
 
222
  x = self.conv_block1(x, pool_size=(2, 2), pool_type="avg")
223
  x = F.dropout(x, p=0.2, training=train)
 
239
  x = F.dropout(x, p=0.5, training=train)
240
  x = F.relu_(self.fc1(x))
241
 
242
+ # outputs = []
243
+ # for head in self.heads:
244
+ # outputs.append(torch.sigmoid(head(x)))
245
 
246
+ clipwise_output = self.fc_audioset(x)
247
+ return clipwise_output
248
+ # return outputs
249
 
250
 
251
  class ConvBlock(nn.Module):
remfx/datasets.py CHANGED
@@ -18,7 +18,6 @@ from auraloss.freq import MultiResolutionSTFTLoss
18
 
19
  STFT_THRESH = 1e-3
20
  ALL_EFFECTS = effect_lib.Pedalboard_Effects
21
- # print(ALL_EFFECTS)
22
 
23
 
24
  vocalset_splits = {
@@ -45,16 +44,6 @@ vocalset_splits = {
45
  }
46
 
47
  guitarset_splits = {"train": ["00", "01", "02", "03"], "val": ["04"], "test": ["05"]}
48
- idmt_guitar_splits = {
49
- "train": ["classical", "country_folk", "jazz", "latin", "metal", "pop"],
50
- "val": ["reggae", "ska"],
51
- "test": ["rock", "blues"],
52
- }
53
- idmt_bass_splits = {
54
- "train": ["BE", "BEQ"],
55
- "val": ["VIF"],
56
- "test": ["VIS"],
57
- }
58
  dsd_100_splits = {
59
  "train": ["train"],
60
  "val": ["val"],
@@ -93,38 +82,8 @@ def locate_files(root: str, mode: str):
93
  ]
94
  print(f"Found {len(files)} files in GuitarSet {mode}.")
95
  file_list.append(sorted(files))
96
- # # ------------------------- IDMT-SMT-GUITAR -------------------------
97
- # idmt_smt_guitar_dir = os.path.join(root, "IDMT-SMT-GUITAR_V2")
98
- # if os.path.isdir(idmt_smt_guitar_dir):
99
- # files = glob.glob(
100
- # os.path.join(
101
- # idmt_smt_guitar_dir, "IDMT-SMT-GUITAR_V2", "dataset4", "**", "*.wav"
102
- # ),
103
- # recursive=True,
104
- # )
105
- # files = [
106
- # f
107
- # for f in files
108
- # if os.path.basename(f).split("_")[0] in idmt_guitar_splits[mode]
109
- # ]
110
- # file_list.append(sorted(files))
111
- # print(f"Found {len(files)} files in IDMT-SMT-Guitar {mode}.")
112
- # ------------------------- IDMT-SMT-BASS -------------------------
113
- # idmt_smt_bass_dir = os.path.join(root, "IDMT-SMT-BASS")
114
- # if os.path.isdir(idmt_smt_bass_dir):
115
- # files = glob.glob(
116
- # os.path.join(idmt_smt_bass_dir, "**", "*.wav"),
117
- # recursive=True,
118
- # )
119
- # files = [
120
- # f
121
- # for f in files
122
- # if os.path.basename(os.path.dirname(f)) in idmt_bass_splits[mode]
123
- # ]
124
- # file_list.append(sorted(files))
125
- # print(f"Found {len(files)} files in IDMT-SMT-Bass {mode}.")
126
  # ------------------------- DSD100 ---------------------------------
127
- dsd_100_dir = os.path.join(root, "DSD100")
128
  if os.path.isdir(dsd_100_dir):
129
  files = glob.glob(
130
  os.path.join(dsd_100_dir, mode, "**", "*.wav"),
@@ -468,7 +427,13 @@ class EffectDataset(Dataset):
468
  chunk = None
469
  random_dataset_choice = random.choice(self.files)
470
  while chunk is None:
471
- random_file_choice = random.choice(random_dataset_choice)
 
 
 
 
 
 
472
  chunk = select_random_chunk(
473
  random_file_choice, self.chunk_size, self.sample_rate
474
  )
@@ -613,7 +578,10 @@ class EffectDataset(Dataset):
613
  normalized_wet = self.normalize(wet)
614
 
615
  # Check STFT, pick different effects if necessary
616
- stft = self.mrstft(normalized_wet, normalized_dry)
 
 
 
617
  return normalized_dry, normalized_wet, dry_labels_tensor, wet_labels_tensor
618
 
619
 
 
18
 
19
  STFT_THRESH = 1e-3
20
  ALL_EFFECTS = effect_lib.Pedalboard_Effects
 
21
 
22
 
23
  vocalset_splits = {
 
44
  }
45
 
46
  guitarset_splits = {"train": ["00", "01", "02", "03"], "val": ["04"], "test": ["05"]}
 
 
 
 
 
 
 
 
 
 
47
  dsd_100_splits = {
48
  "train": ["train"],
49
  "val": ["val"],
 
82
  ]
83
  print(f"Found {len(files)} files in GuitarSet {mode}.")
84
  file_list.append(sorted(files))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  # ------------------------- DSD100 ---------------------------------
86
+ dsd_100_dir = os.path.join(root, "DSD100/DSD100")
87
  if os.path.isdir(dsd_100_dir):
88
  files = glob.glob(
89
  os.path.join(dsd_100_dir, mode, "**", "*.wav"),
 
427
  chunk = None
428
  random_dataset_choice = random.choice(self.files)
429
  while chunk is None:
430
+ try:
431
+ random_file_choice = random.choice(random_dataset_choice)
432
+ except IndexError:
433
+ print("IndexError")
434
+ print(random_dataset_choice)
435
+ print(random_file_choice)
436
+ raise IndexError
437
  chunk = select_random_chunk(
438
  random_file_choice, self.chunk_size, self.sample_rate
439
  )
 
578
  normalized_wet = self.normalize(wet)
579
 
580
  # Check STFT, pick different effects if necessary
581
+ if num_removed_effects == 0:
582
+ # No need to check if no effects removed
583
+ break
584
+ stft = self.mrstft(normalized_wet.unsqueeze(0), normalized_dry.unsqueeze(0))
585
  return normalized_dry, normalized_wet, dry_labels_tensor, wet_labels_tensor
586
 
587
 
remfx/models.py CHANGED
@@ -4,16 +4,13 @@ import torchmetrics
4
  import pytorch_lightning as pl
5
  from torch import Tensor, nn
6
  from torchaudio.models import HDemucs
7
- from audio_diffusion_pytorch import DiffusionModel
8
  from auraloss.time import SISDRLoss
9
  from auraloss.freq import MultiResolutionSTFTLoss
10
  from umx.openunmix.model import OpenUnmix, Separator
11
 
12
- from remfx.utils import FADLoss, spectrogram
13
  from remfx.tcn import TCN
14
  from remfx.utils import causal_crop
15
- from remfx.callbacks import log_wandb_audio_batch
16
- from einops import rearrange
17
  from remfx import effects
18
  import asteroid
19
  import random
@@ -51,7 +48,7 @@ class RemFXChainInference(pl.LightningModule):
51
  self.output_str = "IN_SISDR,OUT_SISDR,IN_STFT,OUT_STFT\n"
52
  self.use_all_effect_models = use_all_effect_models
53
 
54
- def forward(self, batch, batch_idx, order=None):
55
  x, y, _, rem_fx_labels = batch
56
  # Use chain of effects defined in config
57
  if order:
@@ -79,25 +76,19 @@ class RemFXChainInference(pl.LightningModule):
79
  ]
80
  for effect_label in rem_fx_labels
81
  ]
 
 
 
 
 
 
 
 
 
 
 
82
 
83
  output = []
84
- # input_samples = rearrange(x, "b c t -> c (b t)").unsqueeze(0)
85
- # target_samples = rearrange(y, "b c t -> c (b t)").unsqueeze(0)
86
-
87
- # log_wandb_audio_batch(
88
- # logger=self.logger,
89
- # id="input_effected_audio",
90
- # samples=input_samples.cpu(),
91
- # sampling_rate=self.sample_rate,
92
- # caption="Input Data",
93
- # )
94
- # log_wandb_audio_batch(
95
- # logger=self.logger,
96
- # id="target_audio",
97
- # samples=target_samples.cpu(),
98
- # sampling_rate=self.sample_rate,
99
- # caption="Target Data",
100
- # )
101
  with torch.no_grad():
102
  for i, (elem, effects_list) in enumerate(zip(x, effects_present)):
103
  elem = elem.unsqueeze(0) # Add batch dim
@@ -107,40 +98,12 @@ class RemFXChainInference(pl.LightningModule):
107
  effect for effect in effects_order if effect in effect_list_names
108
  ]
109
 
110
- # log_wandb_audio_batch(
111
- # logger=self.logger,
112
- # id=f"{i}_Before",
113
- # samples=elem.cpu(),
114
- # sampling_rate=self.sample_rate,
115
- # caption=effects,
116
- # )
117
  for effect in effects:
118
  # Sample the model
119
  elem = self.model[effect].model.sample(elem)
120
- # log_wandb_audio_batch(
121
- # logger=self.logger,
122
- # id=f"{i}_{effect}",
123
- # samples=elem.cpu(),
124
- # sampling_rate=self.sample_rate,
125
- # caption=effects,
126
- # )
127
- # log_wandb_audio_batch(
128
- # logger=self.logger,
129
- # id=f"{i}_After",
130
- # samples=elem.cpu(),
131
- # sampling_rate=self.sample_rate,
132
- # caption=effects,
133
- # )
134
  output.append(elem.squeeze(0))
135
  output = torch.stack(output)
136
 
137
- # log_wandb_audio_batch(
138
- # logger=self.logger,
139
- # id="output_audio",
140
- # samples=output_samples.cpu(),
141
- # sampling_rate=self.sample_rate,
142
- # caption="Output Data",
143
- # )
144
  loss = self.mrstftloss(output, y) + self.l1loss(output, y) * 100
145
  return loss, output
146
 
@@ -182,13 +145,14 @@ class RemFXChainInference(pl.LightningModule):
182
  )
183
  # print(f"Input_{metric}", negate * self.metrics[metric](x, y))
184
  # print(f"test_{metric}", negate * self.metrics[metric](output, y))
185
- self.output_str += f"{negate * self.metrics[metric](x, y).item():.4f},{negate * self.metrics[metric](output, y).item():.4f},"
186
- self.output_str += "\n"
187
  return loss
188
 
189
  def on_test_end(self) -> None:
190
- with open("output.csv", "w") as f:
191
- f.write(self.output_str)
 
192
 
193
  def sample(self, batch):
194
  return self.forward(batch, 0)[1]
@@ -300,13 +264,14 @@ class RemFX(pl.LightningModule):
300
  )
301
  # print(f"Input_{metric}", negate * self.metrics[metric](x, y))
302
  # print(f"test_{metric}", negate * self.metrics[metric](output, y))
303
- self.output_str += f"{negate * self.metrics[metric](x, y).item():.4f},{negate * self.metrics[metric](output, y).item():.4f},"
304
- self.output_str += "\n"
305
  return loss
306
 
307
  def on_test_end(self) -> None:
308
- with open("output.csv", "w") as f:
309
- f.write(self.output_str)
 
310
 
311
 
312
  class OpenUnmixModel(nn.Module):
@@ -377,21 +342,6 @@ class DemucsModel(nn.Module):
377
  return self.model(x).squeeze(1)
378
 
379
 
380
- class DiffusionGenerationModel(nn.Module):
381
- def __init__(self, n_channels: int = 1):
382
- super().__init__()
383
- self.model = DiffusionModel(in_channels=n_channels)
384
-
385
- def forward(self, batch):
386
- x, target = batch
387
- sampled_out = self.model.sample(x)
388
- return self.model(x), sampled_out
389
-
390
- def sample(self, x: Tensor, num_steps: int = 10) -> Tensor:
391
- noise = torch.randn(x.shape).to(x)
392
- return self.model.sample(noise, num_steps=num_steps)
393
-
394
-
395
  class DPTNetModel(nn.Module):
396
  def __init__(self, sample_rate, num_bins, **kwargs):
397
  super().__init__()
 
4
  import pytorch_lightning as pl
5
  from torch import Tensor, nn
6
  from torchaudio.models import HDemucs
 
7
  from auraloss.time import SISDRLoss
8
  from auraloss.freq import MultiResolutionSTFTLoss
9
  from umx.openunmix.model import OpenUnmix, Separator
10
 
11
+ from remfx.utils import spectrogram
12
  from remfx.tcn import TCN
13
  from remfx.utils import causal_crop
 
 
14
  from remfx import effects
15
  import asteroid
16
  import random
 
48
  self.output_str = "IN_SISDR,OUT_SISDR,IN_STFT,OUT_STFT\n"
49
  self.use_all_effect_models = use_all_effect_models
50
 
51
+ def forward(self, batch, batch_idx, order=None, verbose=False):
52
  x, y, _, rem_fx_labels = batch
53
  # Use chain of effects defined in config
54
  if order:
 
76
  ]
77
  for effect_label in rem_fx_labels
78
  ]
79
+ effects_present_name = [
80
+ [
81
+ ALL_EFFECTS[i].__name__
82
+ for i, effect in enumerate(effect_label)
83
+ if effect == 1.0
84
+ ]
85
+ for effect_label in rem_fx_labels
86
+ ]
87
+ if verbose:
88
+ print("Detected effects:", effects_present_name[0])
89
+ print("Removing effects...")
90
 
91
  output = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  with torch.no_grad():
93
  for i, (elem, effects_list) in enumerate(zip(x, effects_present)):
94
  elem = elem.unsqueeze(0) # Add batch dim
 
98
  effect for effect in effects_order if effect in effect_list_names
99
  ]
100
 
 
 
 
 
 
 
 
101
  for effect in effects:
102
  # Sample the model
103
  elem = self.model[effect].model.sample(elem)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  output.append(elem.squeeze(0))
105
  output = torch.stack(output)
106
 
 
 
 
 
 
 
 
107
  loss = self.mrstftloss(output, y) + self.l1loss(output, y) * 100
108
  return loss, output
109
 
 
145
  )
146
  # print(f"Input_{metric}", negate * self.metrics[metric](x, y))
147
  # print(f"test_{metric}", negate * self.metrics[metric](output, y))
148
+ # self.output_str += f"{negate * self.metrics[metric](x, y).item():.4f},{negate * self.metrics[metric](output, y).item():.4f},"
149
+ # self.output_str += "\n"
150
  return loss
151
 
152
  def on_test_end(self) -> None:
153
+ pass
154
+ # with open("output.csv", "w") as f:
155
+ # f.write(self.output_str)
156
 
157
  def sample(self, batch):
158
  return self.forward(batch, 0)[1]
 
264
  )
265
  # print(f"Input_{metric}", negate * self.metrics[metric](x, y))
266
  # print(f"test_{metric}", negate * self.metrics[metric](output, y))
267
+ # self.output_str += f"{negate * self.metrics[metric](x, y).item():.4f},{negate * self.metrics[metric](output, y).item():.4f},"
268
+ # self.output_str += "\n"
269
  return loss
270
 
271
  def on_test_end(self) -> None:
272
+ pass
273
+ # with open("output.csv", "w") as f:
274
+ # f.write(self.output_str)
275
 
276
 
277
  class OpenUnmixModel(nn.Module):
 
342
  return self.model(x).squeeze(1)
343
 
344
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
345
  class DPTNetModel(nn.Module):
346
  def __init__(self, sample_rate, num_bins, **kwargs):
347
  super().__init__()
remfx/tcn.py CHANGED
@@ -125,7 +125,6 @@ class TCN(nn.Module):
125
  self.buffer = torch.zeros(2, self.receptive_field + self.block_size - 1)
126
 
127
  def forward(self, x: Tensor) -> Tensor:
128
- x_in = x
129
  for _, block in enumerate(self.process_blocks):
130
  x = block(x)
131
  y_hat = torch.tanh(self.output(x))
 
125
  self.buffer = torch.zeros(2, self.receptive_field + self.block_size - 1)
126
 
127
  def forward(self, x: Tensor) -> Tensor:
 
128
  for _, block in enumerate(self.process_blocks):
129
  x = block(x)
130
  y_hat = torch.tanh(self.output(x))
remfx/utils.py CHANGED
@@ -3,8 +3,6 @@ from typing import List, Tuple
3
  import pytorch_lightning as pl
4
  from omegaconf import DictConfig
5
  from pytorch_lightning.utilities import rank_zero_only
6
- from frechet_audio_distance import FrechetAudioDistance
7
- import numpy as np
8
  import torch
9
  import torchaudio
10
  from torch import nn
@@ -74,38 +72,10 @@ def log_hyperparameters(
74
  if "callbacks" in config:
75
  hparams["callbacks"] = config["callbacks"]
76
 
77
- logger.experiment.config.update(hparams)
78
-
79
-
80
- class FADLoss(torch.nn.Module):
81
- def __init__(self, sample_rate: float):
82
- super().__init__()
83
- self.fad = FrechetAudioDistance(
84
- use_pca=False, use_activation=False, verbose=False
85
- )
86
- self.fad.model = self.fad.model.to("cpu")
87
- self.sr = sample_rate
88
-
89
- def forward(self, audio_background, audio_eval):
90
- embds_background = []
91
- embds_eval = []
92
- for sample in audio_background:
93
- embd = self.fad.model.forward(sample.T.cpu().detach().numpy(), self.sr)
94
- embds_background.append(embd.cpu().detach().numpy())
95
- for sample in audio_eval:
96
- embd = self.fad.model.forward(sample.T.cpu().detach().numpy(), self.sr)
97
- embds_eval.append(embd.cpu().detach().numpy())
98
- embds_background = np.concatenate(embds_background, axis=0)
99
- embds_eval = np.concatenate(embds_eval, axis=0)
100
- mu_background, sigma_background = self.fad.calculate_embd_statistics(
101
- embds_background
102
- )
103
- mu_eval, sigma_eval = self.fad.calculate_embd_statistics(embds_eval)
104
-
105
- fad_score = self.fad.calculate_frechet_distance(
106
- mu_background, sigma_background, mu_eval, sigma_eval
107
- )
108
- return fad_score
109
 
110
 
111
  def create_random_chunks(
 
3
  import pytorch_lightning as pl
4
  from omegaconf import DictConfig
5
  from pytorch_lightning.utilities import rank_zero_only
 
 
6
  import torch
7
  import torchaudio
8
  from torch import nn
 
72
  if "callbacks" in config:
73
  hparams["callbacks"] = config["callbacks"]
74
 
75
+ if type(trainer.logger) == pl.loggers.CSVLogger:
76
+ logger.log_hyperparams(hparams)
77
+ else:
78
+ logger.experiment.config.update(hparams)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
 
80
 
81
  def create_random_chunks(
remfx_detect.sh ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #! /bin/bash
2
+
3
+ # Example usage:
4
+ # ./remfx_detect.sh wet.wav -o examples/output.wav
5
+ # first argument is required, second argument is optional
6
+
7
+ # Check if first argument is empty
8
+ if [ -z "$1" ]
9
+ then
10
+ echo "No audio input path supplied"
11
+ exit 1
12
+ fi
13
+
14
+ audio_input=$1
15
+ # Shift first argument away
16
+ shift
17
+ output_path=""
18
+
19
+ while getopts ":o:" opt; do
20
+ case $opt in
21
+ o)
22
+ output_path=$OPTARG
23
+ ;;
24
+ \?)
25
+ echo "Invalid option: -$OPTARG" >&2
26
+ ;;
27
+ esac
28
+ done
29
+
30
+
31
+ # Run script
32
+ # If output path is blank, leave it blank
33
+
34
+ if [ -z "$output_path" ]
35
+ then
36
+ python scripts/remfx_detect.py +exp=remfx_detect +audio_input=$audio_input
37
+ exit 0
38
+ fi
39
+ python scripts/remfx_detect.py +exp=remfx_detect +audio_input=$audio_input +output_path=$output_path
scripts/download.py CHANGED
@@ -6,56 +6,62 @@ import shutil
6
  def download_zip_dataset(dataset_url: str, output_dir: str):
7
  zip_filename = os.path.basename(dataset_url)
8
  zip_name = zip_filename.replace(".zip", "")
9
- os.system(f"wget -P {output_dir} {dataset_url}")
10
- os.system(
11
- f"""unzip {os.path.join(output_dir, zip_filename)} -d {os.path.join(output_dir, zip_name)}"""
12
- )
13
- os.system(f"rm {os.path.join(output_dir, zip_filename)}")
 
 
 
 
 
14
 
15
 
16
  def process_dataset(dataset_dir: str, output_dir: str):
17
- if dataset_dir == "VocalSet1-2":
18
- pass
19
- elif dataset_dir == "audio_mono-mic":
20
  pass
21
- elif dataset_dir == "IDMT-SMT-GUITAR_V2":
22
  pass
23
- elif dataset_dir == "IDMT-SMT-BASS":
24
  pass
25
- elif dataset_dir == "IDMT-SMT-DRUMS-V2":
26
- pass
27
- elif dataset_dir == "DSD100":
28
- shutil.rmtree(os.path.join(output_dir, dataset_dir, "Mixtures"))
29
- for dir in os.listdir(os.path.join(output_dir, dataset_dir, "Sources", "Dev")):
30
- source = os.path.join(output_dir, dataset_dir, "Sources", "Dev", dir)
31
- shutil.move(source, os.path.join(output_dir, dataset_dir))
32
- shutil.rmtree(os.path.join(output_dir, dataset_dir, "Sources", "Dev"))
33
- for dir in os.listdir(os.path.join(output_dir, dataset_dir, "Sources", "Test")):
34
- source = os.path.join(output_dir, dataset_dir, "Sources", "Test", dir)
35
- shutil.move(source, os.path.join(output_dir, dataset_dir))
36
- shutil.rmtree(os.path.join(output_dir, dataset_dir, "Sources", "Test"))
37
- shutil.rmtree(os.path.join(output_dir, dataset_dir, "Sources"))
38
 
39
- os.mkdir(os.path.join(output_dir, dataset_dir, "train"))
40
- os.mkdir(os.path.join(output_dir, dataset_dir, "val"))
41
- os.mkdir(os.path.join(output_dir, dataset_dir, "test"))
42
- files = os.listdir(os.path.join(output_dir, dataset_dir))
 
 
 
 
 
 
 
 
 
 
43
 
 
 
 
 
44
  num = 0
45
  for dir in files:
46
- if not os.path.isdir(os.path.join(output_dir, dataset_dir, dir)):
47
  continue
48
  if dir == "train" or dir == "val" or dir == "test":
49
  continue
50
- source = os.path.join(output_dir, dataset_dir, dir, "bass.wav")
51
  if num < 80:
52
- dest = os.path.join(output_dir, dataset_dir, "train", f"{num}.wav")
53
  elif num < 90:
54
- dest = os.path.join(output_dir, dataset_dir, "val", f"{num}.wav")
55
  else:
56
- dest = os.path.join(output_dir, dataset_dir, "test", f"{num}.wav")
57
  shutil.move(source, dest)
58
- shutil.rmtree(os.path.join(output_dir, dataset_dir, dir))
59
  num += 1
60
 
61
  else:
@@ -69,23 +75,26 @@ if __name__ == "__main__":
69
  choices=[
70
  "vocalset",
71
  "guitarset",
72
- "idmt-smt-guitar",
73
  "dsd100",
74
  "idmt-smt-drums",
75
  ],
76
  nargs="+",
77
  )
 
78
  args = parser.parse_args()
79
 
 
 
 
80
  dataset_urls = {
81
  "vocalset": "https://zenodo.org/record/1442513/files/VocalSet1-2.zip",
82
  "guitarset": "https://zenodo.org/record/3371780/files/audio_mono-mic.zip",
83
- "IDMT-SMT-GUITAR_V2": "https://zenodo.org/record/7544110/files/IDMT-SMT-GUITAR_V2.zip",
84
- "DSD100": "http://liutkus.net/DSD100.zip",
85
- "IDMT-SMT-DRUMS-V2": "https://zenodo.org/record/7544164/files/IDMT-SMT-DRUMS-V2.zip",
86
  }
87
 
88
  for dataset_name, dataset_url in dataset_urls.items():
89
  if dataset_name in args.dataset_names:
90
- download_zip_dataset(dataset_url, "~/data/remfx-data")
91
- process_dataset(dataset_name, "~/data/remfx-data")
 
 
6
  def download_zip_dataset(dataset_url: str, output_dir: str):
7
  zip_filename = os.path.basename(dataset_url)
8
  zip_name = zip_filename.replace(".zip", "")
9
+ if not os.path.exists(os.path.join(output_dir, zip_name)):
10
+ os.system(f"wget -P {output_dir} {dataset_url}")
11
+ os.system(
12
+ f"""unzip {os.path.join(output_dir, zip_filename)} -d {os.path.join(output_dir, zip_name)}"""
13
+ )
14
+ os.system(f"rm {os.path.join(output_dir, zip_filename)}")
15
+ else:
16
+ print(
17
+ f"Dataset {zip_name} already downloaded at {output_dir}, skipping download."
18
+ )
19
 
20
 
21
  def process_dataset(dataset_dir: str, output_dir: str):
22
+ if dataset_dir == "vocalset":
 
 
23
  pass
24
+ elif dataset_dir == "guitarset":
25
  pass
26
+ elif dataset_dir == "idmt-smt-drums":
27
  pass
28
+ elif dataset_dir == "dsd100":
29
+ dataset_root_dir = "DSD100/DSD100"
 
 
 
 
 
 
 
 
 
 
 
30
 
31
+ shutil.rmtree(os.path.join(output_dir, dataset_root_dir, "Mixtures"))
32
+ for dir in os.listdir(
33
+ os.path.join(output_dir, dataset_root_dir, "Sources", "Dev")
34
+ ):
35
+ source = os.path.join(output_dir, dataset_root_dir, "Sources", "Dev", dir)
36
+ shutil.move(source, os.path.join(output_dir, dataset_root_dir))
37
+ shutil.rmtree(os.path.join(output_dir, dataset_root_dir, "Sources", "Dev"))
38
+ for dir in os.listdir(
39
+ os.path.join(output_dir, dataset_root_dir, "Sources", "Test")
40
+ ):
41
+ source = os.path.join(output_dir, dataset_root_dir, "Sources", "Test", dir)
42
+ shutil.move(source, os.path.join(output_dir, dataset_root_dir))
43
+ shutil.rmtree(os.path.join(output_dir, dataset_root_dir, "Sources", "Test"))
44
+ shutil.rmtree(os.path.join(output_dir, dataset_root_dir, "Sources"))
45
 
46
+ os.mkdir(os.path.join(output_dir, dataset_root_dir, "train"))
47
+ os.mkdir(os.path.join(output_dir, dataset_root_dir, "val"))
48
+ os.mkdir(os.path.join(output_dir, dataset_root_dir, "test"))
49
+ files = os.listdir(os.path.join(output_dir, dataset_root_dir))
50
  num = 0
51
  for dir in files:
52
+ if not os.path.isdir(os.path.join(output_dir, dataset_root_dir, dir)):
53
  continue
54
  if dir == "train" or dir == "val" or dir == "test":
55
  continue
56
+ source = os.path.join(output_dir, dataset_root_dir, dir, "bass.wav")
57
  if num < 80:
58
+ dest = os.path.join(output_dir, dataset_root_dir, "train", f"{num}.wav")
59
  elif num < 90:
60
+ dest = os.path.join(output_dir, dataset_root_dir, "val", f"{num}.wav")
61
  else:
62
+ dest = os.path.join(output_dir, dataset_root_dir, "test", f"{num}.wav")
63
  shutil.move(source, dest)
64
+ shutil.rmtree(os.path.join(output_dir, dataset_root_dir, dir))
65
  num += 1
66
 
67
  else:
 
75
  choices=[
76
  "vocalset",
77
  "guitarset",
 
78
  "dsd100",
79
  "idmt-smt-drums",
80
  ],
81
  nargs="+",
82
  )
83
+ parser.add_argument("--output_dir", default="./data/remfx-data")
84
  args = parser.parse_args()
85
 
86
+ if not os.path.exists(args.output_dir):
87
+ os.makedirs(args.output_dir)
88
+
89
  dataset_urls = {
90
  "vocalset": "https://zenodo.org/record/1442513/files/VocalSet1-2.zip",
91
  "guitarset": "https://zenodo.org/record/3371780/files/audio_mono-mic.zip",
92
+ "dsd100": "http://liutkus.net/DSD100.zip",
93
+ "idmt-smt-drums": "https://zenodo.org/record/7544164/files/IDMT-SMT-DRUMS-V2.zip",
 
94
  }
95
 
96
  for dataset_name, dataset_url in dataset_urls.items():
97
  if dataset_name in args.dataset_names:
98
+ print("Downloading dataset: ", dataset_name)
99
+ download_zip_dataset(dataset_url, args.output_dir)
100
+ process_dataset(dataset_name, args.output_dir)
scripts/download_egfx.sh DELETED
@@ -1,22 +0,0 @@
1
- #/bin/bash
2
- mkdir -p data
3
- cd data
4
- mkdir -p egfx
5
- cd egfx
6
- wget https://zenodo.org/record/7044411/files/BluesDriver.zip?download=1 -O BluesDriver.zip
7
- wget https://zenodo.org/record/7044411/files/Chorus.zip?download=1 -O Chorus.zip
8
- wget https://zenodo.org/record/7044411/files/Clean.zip?download=1 -O Clean.zip
9
- wget https://zenodo.org/record/7044411/files/Digital-Delay.zip?download=1 -O Digital-Delay.zip
10
- wget https://zenodo.org/record/7044411/files/Flanger.zip?download=1 -O Flanger.zip
11
- wget https://zenodo.org/record/7044411/files/Hall-Reverb.zip?download=1 -O Hall-Reverb.zip
12
- wget https://zenodo.org/record/7044411/files/Phaser.zip?download=1 -O Phaser.zip
13
- wget https://zenodo.org/record/7044411/files/Plate-Reverb.zip?download=1 -O Plate-Reverb.zip
14
- wget https://zenodo.org/record/7044411/files/RAT.zip?download=1 -O RAT.zip
15
- wget https://zenodo.org/record/7044411/files/Spring-Reverb.zip?download=1 -O Spring-Reverb.zip
16
- wget https://zenodo.org/record/7044411/files/Sweep-Echo.zip?download=1 -O Sweep-Echo.zip
17
- wget https://zenodo.org/record/7044411/files/TapeEcho.zip?download=1 -O TapeEcho.zip
18
- wget https://zenodo.org/record/7044411/files/TubeScreamer.zip?download=1 -O TubeScreamer.zip
19
- unzip -n \*.zip
20
- rm -rf *.zip
21
-
22
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
scripts/generate_dataset.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pytorch_lightning as pl
2
+ import hydra
3
+ from omegaconf import DictConfig
4
+
5
+
6
+ @hydra.main(version_base=None, config_path="../cfg", config_name="config.yaml")
7
+ def main(cfg: DictConfig):
8
+ # Apply seed for reproducibility
9
+ if cfg.seed:
10
+ pl.seed_everything(cfg.seed)
11
+ datamodule = hydra.utils.instantiate(cfg.datamodule, _convert_="partial")
12
+
13
+
14
+ if __name__ == "__main__":
15
+ main()