def main(note_embedding_dim, meta_embedding_dim, num_layers, lstm_hidden_size, dropout_lstm, linear_hidden_size, batch_size, num_epochs, train, num_iterations, sequence_length_ticks): dataset_manager = DatasetManager() metadatas = [ FermataMetadata(), TickMetadata(subdivision=4), KeyMetadata() ] chorale_dataset_kwargs = { 'voice_ids': [0, 1, 2, 3], 'metadatas': metadatas, 'sequences_size': 8, 'subdivision': 4 } bach_chorales_dataset = dataset_manager.get_dataset( name='bach_chorales', **chorale_dataset_kwargs ) dataset = bach_chorales_dataset deepbach = DeepBach( dataset=dataset, note_embedding_dim=note_embedding_dim, meta_embedding_dim=meta_embedding_dim, num_layers=num_layers, lstm_hidden_size=lstm_hidden_size, dropout_lstm=dropout_lstm, linear_hidden_size=linear_hidden_size ) if train: deepbach.train(batch_size=batch_size, num_epochs=num_epochs) else: deepbach.load() deepbach.cuda() print('Generation') score, tensor_chorale, tensor_metadata = deepbach.generation( num_iterations=num_iterations, length=sequence_length_ticks, ) score.write('midi', fp = 'test.mid')
def main(note_embedding_dim, meta_embedding_dim, num_layers, lstm_hidden_size, dropout_lstm, linear_hidden_size, batch_size, num_epochs, train, update, num_iterations, sequence_length_ticks, model_id, include_transpositions, update_iterations, generations_per_iteration, num_generations, score_chorales, write_scores): print('step 1/3: prepare dataset') dataset_manager = DatasetManager() metadatas = [FermataMetadata(), TickMetadata(subdivision=4), KeyMetadata()] chorale_dataset_kwargs = { 'voice_ids': [0, 1, 2, 3], 'metadatas': metadatas, 'sequences_size': 8, 'subdivision': 4, 'include_transpositions': include_transpositions, } bach_chorales_dataset: ChoraleDataset = dataset_manager.get_dataset( name='bach_chorales', **chorale_dataset_kwargs) dataset = bach_chorales_dataset load_or_pickle_distributions(dataset) print('step 2/3: prepare model') print(f'Model ID: {model_id}') deepbach = DeepBach( dataset=dataset, note_embedding_dim=note_embedding_dim, meta_embedding_dim=meta_embedding_dim, num_layers=num_layers, lstm_hidden_size=lstm_hidden_size, dropout_lstm=dropout_lstm, linear_hidden_size=linear_hidden_size, model_id=model_id, ) if train: print('step 2a/3: train base model') deepbach.train(batch_size=batch_size, num_epochs=num_epochs, split=[0.85, 0.15]) else: print('step 2a/3: load model') deepbach.load() deepbach.cuda() if update: print( f'step 2b/3: update base model over {update_iterations} iterations' ) thres = get_threshold('data/chorale_scores.csv', col=-1) print(f'Threshold for selection: {thres}') update_file = open('data/update_scores.csv', 'w') reader = csv.writer(update_file) reader.writerow(['iteration', 'chorale ID', 'score']) for i in range(update_iterations): print(f'----------- Iteration {i} -----------') picked_chorales = [] num_picked_chorales = 0 ensure_dir(f'generations/{model_id}/{i}') for j in tqdm(range(generations_per_iteration)): chorale, tensor_chorale, tensor_metadata = deepbach.generation( num_iterations=num_iterations, sequence_length_ticks=sequence_length_ticks, ) score = score_chorale(chorale, dataset) # write data to csv file reader.writerow([i, j, score]) # iteration, generation #, score # worst Bach chorale score rounded up to nearest .01 if score > thres: print(f'Picked chorale {j} with score {score}') picked_chorales.append(chorale) num_picked_chorales += 1 chorale.write('midi', f'generations/{model_id}/{i}/c{j}.mid') print( f'Number of picked chorales for iteration {i}: {num_picked_chorales}' ) if num_picked_chorales == 0: continue all_datasets.update({ f'generated_chorales_{i}': { 'dataset_class_name': ChoraleDataset, 'corpus_it_gen': GeneratedChoraleIteratorGen(picked_chorales) } }) generated_dataset: ChoraleDataset = dataset_manager.get_dataset( name=f'generated_chorales_{i}', index2note_dicts=dataset.index2note_dicts, note2index_dicts=dataset.note2index_dicts, voice_ranges=dataset.voice_ranges, **chorale_dataset_kwargs) deepbach.dataset = generated_dataset deepbach.train( batch_size=batch_size, num_epochs=2, split=[1, 0], # use all selected chorales for training early_stopping=False) # generate chorales if score_chorales: chorale_scores = {} print('Scoring real chorales') for chorale_id, chorale in tqdm(enumerate(dataset.iterator_gen()), total=num_generations): score = score_chorale(chorale, dataset) chorale_scores[chorale_id] = score if chorale_id == num_generations: break # write scores to file if write_scores: with open('data/chorale_scores.csv', 'w') as chorale_file: reader = csv.writer(chorale_file) reader.writerow(['', 'score'] + list(weights.keys())) for id, value in chorale_scores.items(): reader.writerow([id, value]) if num_generations != 0: generation_scores = {} print('Generating and scoring generated chorales') ensure_dir(f'generations/{model_id}') for i in range(num_generations): chorale, tensor_chorale, tensor_metadata = deepbach.generation( num_iterations=num_iterations, sequence_length_ticks=sequence_length_ticks, ) chorale.write('midi', f'generations/{model_id}/c{i}.mid') score = score_chorale(chorale, dataset) generation_scores[i] = score # write scores to file if write_scores: with open(f'data/model{model_id}_scores.csv', 'w') as generation_file: reader = csv.writer(generation_file) reader.writerow(['', 'score'] + list(weights.keys())) for id, value in generation_scores.items(): reader.writerow([id, value])
class Predictor(cog.Predictor): def setup(self): """Load the model""" # music21.environment.set("musicxmlPath", "/bin/true") note_embedding_dim = 20 meta_embedding_dim = 20 num_layers = 2 lstm_hidden_size = 256 dropout_lstm = 0.5 linear_hidden_size = 256 batch_size = 256 num_epochs = 5 train = False num_iterations = 500 sequence_length_ticks = 64 dataset_manager = DatasetManager() metadatas = [FermataMetadata(), TickMetadata(subdivision=4), KeyMetadata()] chorale_dataset_kwargs = { "voice_ids": [0, 1, 2, 3], "metadatas": metadatas, "sequences_size": 8, "subdivision": 4, } bach_chorales_dataset: ChoraleDataset = dataset_manager.get_dataset( name="bach_chorales", **chorale_dataset_kwargs ) dataset = bach_chorales_dataset self.deepbach = DeepBach( dataset=dataset, note_embedding_dim=note_embedding_dim, meta_embedding_dim=meta_embedding_dim, num_layers=num_layers, lstm_hidden_size=lstm_hidden_size, dropout_lstm=dropout_lstm, linear_hidden_size=linear_hidden_size, ) self.deepbach.load() # load fluidsynth fo rmidi 2 audio conversion self.fs = FluidSynth() # self.converter = music21.converter.parse('path_to_musicxml.xml') @cog.input( "num_iterations", type=int, help="Number of parallel pseudo-Gibbs sampling iterations", default=500, ) @cog.input( "sequence_length_ticks", type=int, min=16, help="Length of the generated chorale (in ticks)", default=64, ) @cog.input( "output_type", type=str, help="Output representation type: can be audio or midi", default="audio", options=["midi", "audio"], ) @cog.input("seed", type=int, default=-1, help="Random seed, -1 for random") def predict(self, num_iterations, sequence_length_ticks, output_type, seed): """Score Generation""" if seed >= 0: random.seed(seed) np.random.seed(seed) torch.use_deterministic_algorithms(True) torch.manual_seed(seed) score, tensor_chorale, tensor_metadata = self.deepbach.generation( num_iterations=num_iterations, sequence_length_ticks=sequence_length_ticks, ) if output_type == "audio": output_path_wav = Path(tempfile.mkdtemp()) / "output.wav" output_path_mp3 = Path(tempfile.mkdtemp()) / "output.mp3" midi_score = score.write("midi") self.fs.midi_to_audio(midi_score, str(output_path_wav)) subprocess.check_output( [ "ffmpeg", "-i", str(output_path_wav), "-af", "silenceremove=1:0:-50dB,aformat=dblp,areverse,silenceremove=1:0:-50dB,aformat=dblp,areverse", # strip silence str(output_path_mp3), ], ) return output_path_mp3 elif output_type == "midi": output_path_midi = Path(tempfile.mkdtemp()) / "output.mid" score.write("midi", fp=output_path_midi) return output_path_midi