Buckets:
| from pathlib import Path | |
| from random import shuffle | |
| from miditok import REMI, TokenizerConfig | |
| from miditok.utils import split_files_for_training | |
| from miditok.data_augmentation import augment_dataset | |
| from miditok.pytorch_data import DatasetMIDI | |
| TOKENIZER_PARAMS = { | |
| "pitch_range": (21, 109), | |
| "beat_res": {(0, 4): 8, (4, 12): 4}, | |
| "num_velocities": 32, | |
| "special_tokens": ["PAD", "BOS", "EOS", "MASK"], | |
| "use_chords": True, | |
| "use_rests": False, | |
| "use_tempos": True, | |
| "use_time_signatures": False, | |
| "use_programs": False, | |
| "num_tempos": 32, # number of tempo bins | |
| "tempo_range": (40, 250), # (min, max) | |
| } | |
| config = TokenizerConfig(**TOKENIZER_PARAMS) | |
| def get_maestro_dataset(data_dir: str, block_size: int, augment: bool = False): | |
| midi_paths = list(Path(data_dir).resolve().glob("20[0-9][0-9]/*.midi")) | |
| num_total_files = len(midi_paths) | |
| num_valid_files = round(num_total_files * 0.05) | |
| num_test_files = round(num_total_files * 0.05) | |
| shuffle(midi_paths) | |
| midi_paths_valid = midi_paths[:num_valid_files] | |
| midi_paths_test = midi_paths[num_valid_files:num_valid_files + num_test_files] | |
| midi_paths_train = midi_paths[num_valid_files + num_test_files:] | |
| tokenizer = REMI(config) | |
| ds = [] | |
| # Process each subset | |
| for files_paths, subset_name in ((midi_paths_train, "train"), | |
| (midi_paths_valid, "valid"), | |
| (midi_paths_test, "test")): | |
| subset_chunks_dir = Path(data_dir, f"dataset_{subset_name}") | |
| if augment and subset_name == "train": | |
| subset_chunks_dir = subset_chunks_dir.parent / (subset_chunks_dir.name + "_augmented") | |
| subset_chunks_dir.mkdir(parents=True, exist_ok=True) | |
| midi_paths_subset = process_subset( | |
| files_paths=files_paths, | |
| subset_name=subset_name, | |
| subset_chunks_dir=subset_chunks_dir, | |
| tokenizer=tokenizer, | |
| block_size=block_size, | |
| augment=augment | |
| ) | |
| ds.append(DatasetMIDI(files_paths=midi_paths_subset, tokenizer=tokenizer, max_seq_len=block_size)) | |
| train_ds, val_ds, test_ds = ds | |
| print(f"Number of training files: {len(train_ds)}") | |
| print(f"Number of validation files: {len(val_ds)}") | |
| print(f"Number of test files: {len(test_ds)}") | |
| return train_ds, val_ds, test_ds, tokenizer | |
| def process_subset(files_paths, subset_name, subset_chunks_dir, tokenizer, block_size, augment): | |
| chunks_exist = any(subset_chunks_dir.iterdir()) | |
| if not chunks_exist: | |
| create_chunks(files_paths, subset_name, subset_chunks_dir, tokenizer, block_size, augment) | |
| return list(subset_chunks_dir.resolve().glob("**/*.midi")) | |
| def create_chunks(files_paths, subset_name, subset_chunks_dir, tokenizer, block_size, augment): | |
| print(f"Splitting files for {subset_name} subset into chunks of {block_size}...") | |
| split_files_for_training( | |
| files_paths=files_paths, | |
| tokenizer=tokenizer, | |
| save_dir=subset_chunks_dir, | |
| max_seq_len=block_size, | |
| num_overlap_bars=2, | |
| ) | |
| # Apply data augmentation on train split if requested | |
| if augment and subset_name == "train": | |
| print("Performing data augmentation on the training set...") | |
| augment_dataset( | |
| subset_chunks_dir, | |
| pitch_offsets=[-3, -2, -1, 0, 1, 2, 3], | |
| velocity_offsets=[0,], | |
| duration_offsets=[0,], | |
| out_path=subset_chunks_dir | |
| ) |
Xet Storage Details
- Size:
- 3.51 kB
- Xet hash:
- a9c8e67d08c37de3b8a26acc54fb8ff290c91f55db64e9c6209691b0c1ffdf80
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.