Merge branch 'seq2seq_model' of s444337/praca-magisterska into master
This commit is contained in:
commit
9fc30b6e17
@ -54,7 +54,7 @@ def extract_from_folder(model_workflow):
|
||||
instrument=instrument,
|
||||
bar_in_seq=BARS_IN_SEQ)
|
||||
|
||||
pickle.dump((x_train, y_train, program), open(save_path,'wb'))
|
||||
pickle.dump((x_train, y_train, program, BARS_IN_SEQ), open(save_path,'wb'))
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = parse_argv()
|
||||
|
@ -9,21 +9,21 @@ parser = argparse.ArgumentParser()
|
||||
parser.add_argument('n', help='name for experiment', type=str)
|
||||
parser.add_argument('s', help='session name', type=str)
|
||||
parser.add_argument('--i', help='number of midis to generate', type=int)
|
||||
parser.add_argument('--l', help='latent_dim_of_model', type=int)
|
||||
# parser.add_argument('--l', help='latent_dim_of_model', type=int)
|
||||
parser.add_argument('--m', help="mode {'from_seq', 'from_state}'", type=str)
|
||||
args = parser.parse_args()
|
||||
|
||||
EXPERIMENT_NAME = args.n
|
||||
SESSION_NAME = args.s
|
||||
GENERETIONS_COUNT = args.i
|
||||
LATENT_DIM = args.l
|
||||
# LATENT_DIM = args.l
|
||||
MODE = args.m
|
||||
|
||||
if not GENERETIONS_COUNT:
|
||||
GENERETIONS_COUNT = 1
|
||||
|
||||
if not LATENT_DIM:
|
||||
LATENT_DIM = 256
|
||||
# if not LATENT_DIM:
|
||||
# LATENT_DIM = 256
|
||||
|
||||
if not MODE:
|
||||
MODE = 'from_seq'
|
||||
@ -42,17 +42,19 @@ for key, value in model_workflow.items():
|
||||
band[instrument] = [None, None, generator]
|
||||
|
||||
'''LOAD MODELS'''
|
||||
print('Loading models...')
|
||||
for instrument in tqdm(band):
|
||||
|
||||
data_path = os.path.join('training_sets', EXPERIMENT_NAME, instrument.lower() + '_data.pkl')
|
||||
model_path = os.path.join('models', EXPERIMENT_NAME, instrument.lower() + '_model.h5')
|
||||
|
||||
x_train, y_train, program = pickle.load(open(data_path,'rb'))
|
||||
model = Seq2SeqModel(LATENT_DIM, x_train, y_train)
|
||||
x_train, y_train, program, bars_in_seq = pickle.load(open(data_path,'rb'))
|
||||
model = Seq2SeqModel(x_train, y_train, bars_in_seq=bars_in_seq)
|
||||
model.load(model_path)
|
||||
band[instrument][0] = model
|
||||
band[instrument][1] = program
|
||||
|
||||
print('Generating music...')
|
||||
for midi_counter in tqdm(range(GENERETIONS_COUNT)):
|
||||
''' MAKE MULTIINSTRUMENTAL MUSIC !!!'''
|
||||
notes = dict()
|
||||
@ -89,6 +91,6 @@ for midi_counter in tqdm(range(GENERETIONS_COUNT)):
|
||||
except:
|
||||
pass
|
||||
|
||||
save_path = os.path.join('generated_music', EXPERIMENT_NAME, SESSION_NAME, f'{EXPERIMENT_NAME}_{midi_counter}_{MODE}_{LATENT_DIM}.mid')
|
||||
save_path = os.path.join('generated_music', EXPERIMENT_NAME, SESSION_NAME, f'{EXPERIMENT_NAME}_{midi_counter}_{MODE}.mid')
|
||||
generated_midi.save(save_path)
|
||||
# print(f'Generated succefuly to {save_path}')
|
||||
|
@ -519,7 +519,7 @@ def parse_pretty_midi_instrument(instrument, resolution, time_to_tick, key_offse
|
||||
if instrument.is_drum:
|
||||
notes[tick][0].add(note.pitch)
|
||||
else:
|
||||
notes[tick][0].add(note.pitch+key_offset)
|
||||
notes[tick][0].add(note.pitch + key_offset)
|
||||
|
||||
notes[tick][1].add(note_lenth)
|
||||
|
||||
|
@ -85,6 +85,8 @@ class Seq2SeqTransformer():
|
||||
decoder_target_data[i, t - 1, self.y_transform_dict[char]] = 1.
|
||||
|
||||
return encoder_input_data, decoder_input_data, decoder_target_data
|
||||
|
||||
|
||||
|
||||
|
||||
class Seq2SeqModel():
|
||||
@ -92,11 +94,12 @@ class Seq2SeqModel():
|
||||
The network is created based on training data
|
||||
'''
|
||||
|
||||
def __init__(self, latent_dim, x_train, y_train):
|
||||
def __init__(self, x_train, y_train, latent_dim=256, enc_dropout=0, dec_dropout=0, bars_in_seq=4):
|
||||
self.has_predict_model = False
|
||||
self.has_train_model = False
|
||||
self.x_train = x_train
|
||||
self.y_train = y_train
|
||||
self.bars_in_seq = bars_in_seq
|
||||
self.latent_dim = latent_dim
|
||||
self.transformer = Seq2SeqTransformer()
|
||||
self.encoder_input_data, self.decoder_input_data, self.decoder_target_data = self.transformer.transform(self.x_train, self.y_train)
|
||||
@ -115,7 +118,7 @@ class Seq2SeqModel():
|
||||
self.encoder_inputs = Input(shape=(None, self.transformer.x_vocab_size ))
|
||||
|
||||
# 2 layer - LSTM_1, LSTM
|
||||
self.encoder = LSTM(latent_dim, return_state=True)
|
||||
self.encoder = LSTM(latent_dim, return_state=True, dropout=enc_dropout)
|
||||
#self.encoder = LSTM(latent_dim, return_state=True)
|
||||
|
||||
# 2 layer - LSTM_1 : outputs
|
||||
@ -130,7 +133,7 @@ class Seq2SeqModel():
|
||||
self.decoder_inputs = Input(shape=(None, self.transformer.y_vocab_size))
|
||||
|
||||
# 2 layer - LSTM_1, LSTM
|
||||
self.decoder_lstm = LSTM(latent_dim, return_sequences=True, return_state=True)
|
||||
self.decoder_lstm = LSTM(latent_dim, return_sequences=True, return_state=True, dropout=dec_dropout)
|
||||
#self.decoder_lstm = LSTM(latent_dim, return_sequences=True, return_state=True)
|
||||
|
||||
# 2 layer - LSTM_2 : outputs, full sequance as lstm layer
|
||||
@ -221,7 +224,6 @@ class Seq2SeqModel():
|
||||
# 3 layer: Dense output: one-hot-encoded representation of element of sequance
|
||||
self.decoder_outputs = self.decoder_dense(self.decoder_outputs)
|
||||
|
||||
|
||||
self.decoder_model = Model(
|
||||
[self.decoder_inputs] + self.decoder_states_inputs,
|
||||
[self.decoder_outputs] + self.decoder_states)
|
||||
@ -286,7 +288,8 @@ class Seq2SeqModel():
|
||||
def develop(self, mode='from_seq'):
|
||||
|
||||
# music generation for seq2seq for melody
|
||||
input_seq_start = random_seed_generator(16,
|
||||
# TODO: Hardcoded 16 ??
|
||||
input_seq_start = random_seed_generator(self.bars_in_seq * 4,
|
||||
self.transformer.x_max_seq_length,
|
||||
self.transformer.x_vocab_size,
|
||||
self.transformer.x_transform_dict,
|
||||
@ -300,7 +303,7 @@ class Seq2SeqModel():
|
||||
# generate sequnce iterativly for melody
|
||||
input_seq = input_seq_start.copy()
|
||||
melody = []
|
||||
for i in range(4):
|
||||
for i in range(self.bars_in_seq):
|
||||
if mode == 'from_seq':
|
||||
decoded_sentence = self.predict(input_data)[:-1]
|
||||
elif mode == 'from_state':
|
||||
@ -309,8 +312,8 @@ class Seq2SeqModel():
|
||||
raise ValueError('mode must be in {from_seq, from_state}')
|
||||
melody.append(decoded_sentence)
|
||||
input_seq.extend(decoded_sentence)
|
||||
input_bars = stream_to_bars(input_seq, 4)
|
||||
input_bars = input_bars[1:5]
|
||||
input_bars = stream_to_bars(input_seq, self.bars_in_seq)
|
||||
input_bars = input_bars[1:self.bars_in_seq+1]
|
||||
input_seq = [note for bar in input_bars for note in bar]
|
||||
input_data = seq_to_numpy(input_seq,
|
||||
self.transformer.x_max_seq_length,
|
||||
@ -348,7 +351,6 @@ def random_seed_generator(time_of_seq, max_encoder_seq_length, num_encoder_token
|
||||
random_seq = []
|
||||
items = 0
|
||||
stop_sign = False
|
||||
|
||||
|
||||
return random_seq
|
||||
|
||||
|
@ -16,6 +16,8 @@ def parse_argv():
|
||||
parser.add_argument('--b', help='batch_size', type=int)
|
||||
parser.add_argument('--l', help='latent_dim', type=int)
|
||||
parser.add_argument('--e', help='epochs', type=int)
|
||||
parser.add_argument('--ed', help='encoder dropout', type=float)
|
||||
parser.add_argument('--dd', help='decoder dropout', type=float)
|
||||
parser.add_argument('--i', help='refrance to instrument to train, if you want to train only one instument')
|
||||
parser.add_argument('-r', help='reset, use when you want to reset waights and train from scratch', action='store_true')
|
||||
args = parser.parse_args()
|
||||
@ -37,17 +39,21 @@ def train_models(model_workflow):
|
||||
found = False
|
||||
for instrument in instruments:
|
||||
|
||||
if INSTRUMENT == None or INSTRUMENT == instrument:
|
||||
if not INSTRUMENT or INSTRUMENT == instrument:
|
||||
data_path = os.path.join('training_sets', EXPERIMENT_NAME, instrument.lower() + '_data.pkl')
|
||||
model_path = os.path.join('models', EXPERIMENT_NAME, f'{instrument.lower()}_model.h5')
|
||||
|
||||
x_train, y_train, _ = pickle.load(open(data_path,'rb'))
|
||||
model = Seq2SeqModel(LATENT_DIM, x_train, y_train)
|
||||
x_train, y_train, _, bars_in_seq = pickle.load(open(data_path,'rb'))
|
||||
|
||||
if os.path.isfile(model_path) and not RESET:
|
||||
model = Seq2SeqModel(x_train, y_train)
|
||||
model.load(model_path)
|
||||
else:
|
||||
model = Seq2SeqModel(x_train, y_train, LATENT_DIM, ENCODER_DROPOUT, DECODER_DROPOUT, bars_in_seq)
|
||||
|
||||
print(f'Training: {instrument}')
|
||||
model.fit(BATCH_SIZE, EPOCHS, callbacks=[])
|
||||
make_folder_if_not_exist(os.path.join('models', EXPERIMENT_NAME))
|
||||
model.save(model_path)
|
||||
found = True
|
||||
|
||||
@ -65,6 +71,8 @@ if __name__ == '__main__':
|
||||
EPOCHS = args.e
|
||||
RESET = args.r
|
||||
INSTRUMENT = args.i
|
||||
ENCODER_DROPOUT = args.ed
|
||||
DECODER_DROPOUT = args.dd
|
||||
|
||||
# default settings if not args passed
|
||||
if not BATCH_SIZE:
|
||||
@ -75,5 +83,9 @@ if __name__ == '__main__':
|
||||
EPOCHS = 1
|
||||
if not RESET:
|
||||
RESET = False
|
||||
if not ENCODER_DROPOUT:
|
||||
ENCODER_DROPOUT = 0.0
|
||||
if not DECODER_DROPOUT:
|
||||
DECODER_DROPOUT = 0.0
|
||||
|
||||
train_models(load_workflow())
|
Loading…
Reference in New Issue
Block a user