| 1 | **5.4. Имплементација** |
| 2 | |
| 3 | Системот за автоматско генерериње на македонска народна мелодија наречен MacedonMelody се состои од две python скрипти. Првата скрипта се користи за креирање и тренирање на моделот врз базата на податоци, додека во втората се генерира македонска народна мелодија врз база на тренираниот модел. |
| 4 | |
| 5 | Скрипта 1 – macedon_melody_train.py |
| 6 | |
| 7 | import glob # За да можеме да пристапиме локално во системот |
| 8 | import pickle # За да ги зачуваме нотите во документ |
| 9 | import numpy # За менување на формата на влезот на невронската мрежа |
| 10 | from keras.models import Sequential |
| 11 | from keras.layers import CuDNNLSTM |
| 12 | from keras.layers import Dropout |
| 13 | from keras.layers import Dense |
| 14 | from keras.layers import Activation |
| 15 | from keras.utils import np_utils |
| 16 | from keras.callbacks import ModelCheckpoint |
| 17 | from music21 import converter, instrument, note, chord, stream |
| 18 | |
| 19 | def mac_notes(): # Функција за креирање вокабулар од ноти од сите муз. документи во базата на податоци за тренирање |
| 20 | |
| 21 | macedonian_notes = [] # Листа за зачувување на сите ноти од МИДИ документите |
| 22 | for file in glob.glob("mac_midi/*.mid"): |
| 23 | |
| 24 | macedonian_midi = converter.parse(file) #Парсирање на нотен запис од фајл |
| 25 | print("The song parsed is: %s " %file) |
| 26 | # macedonian_midi.show('text') – За прикажување на содржините на миди документите |
| 27 | |
| 28 | |
| 29 | mac_notes_to_be_parsed = None |
| 30 | offsets = None |
| 31 | try: |
| 32 | mac_notes_to_be_parsed = macedonian_midi.flat.notes |
| 33 | except: |
| 34 | mac_instruments = instrument.partitionByInstrument(macedonian_midi) |
| 35 | mac_notes_to_be_parsed = mac_instruments.parts[0].recurse() |
| 36 | |
| 37 | for element in mac_notes_to_be_parsed: |
| 38 | if isinstance(element, note.Note): |
| 39 | macedonian_notes.append(str(element.pitch)) |
| 40 | elif isinstance(element, chord.Chord): |
| 41 | macedonian_notes.append('.'.join(str(m) for m in element.normalOrder)) |
| 42 | |
| 43 | with open('data/macedonian_notes','wb') as filepath: |
| 44 | pickle.dump(macedonian_notes, filepath) |
| 45 | return macedonian_notes # На излез дава листа со ноти |
| 46 | |
| 47 | def io_neural_sequences(macedonian_notes,mac_notes_vocabulary): # Функција за дефинирање на влезната и излезната секвенца на моделот на невронската мрежа. |
| 48 | |
| 49 | input_sequence = None |
| 50 | output_sequence = None |
| 51 | sequence_size = 150 |
| 52 | n_patterns = 0 |
| 53 | pitch_names = sorted(set(elem for elem in macedonian_notes)) |
| 54 | mac_notes_to_int = dict((note, number) for number, note in enumerate(pitch_names)) |
| 55 | i_neural_sequence = [] |
| 56 | o_neural_sequence = [] |
| 57 | for m in range(0, len(macedonian_notes)-sequence_size,1): |
| 58 | input_sequence = macedonian_notes[m:m + sequence_size] |
| 59 | output_sequence = macedonian_notes[m + sequence_size] |
| 60 | i_neural_sequence.append([mac_notes_to_int[char] for char in input_sequence]) |
| 61 | o_neural_sequence.append(mac_notes_to_int[output_sequence]) |
| 62 | n_patterns = len(i_neural_sequence) |
| 63 | i_neural_sequence = numpy.reshape(i_neural_sequence, (n_patterns,sequence_size,1)) |
| 64 | i_neural_sequence = i_neural_sequence / float(mac_notes_vocabulary) |
| 65 | o_neural_sequence = np_utils.to_categorical(o_neural_sequence) |
| 66 | |
| 67 | return (i_neural_sequence, o_neural_sequence) # На излез ни ги дава дефинираните внезна и излезна секвенца за невронската мрежа |
| 68 | |
| 69 | def model_neural_netrowk(i_neural_sequence, mac_notes_vocabulary): # Функција за креирање на артитектура на секвенционен модел на невронска мрежа, кој се состои од 3 CuDNNLSTM слоја, 3 Dropout слоја, 2 Dense слоја и слој за активација. |
| 70 | |
| 71 | model = Sequential() |
| 72 | model.add(CuDNNLSTM(256,input_shape=(i_neural_sequence.shape[1], i_neural_sequence.shape[2]),return_sequences=True)) |
| 73 | model.add(Dropout(0.3)) |
| 74 | model.add(CuDNNLSTM(512, return_sequences=True)) |
| 75 | model.add(Dropout(0.3)) |
| 76 | model.add(CuDNNLSTM(256)) |
| 77 | model.add(Dropout(0.3)) |
| 78 | model.add(Dense(256)) |
| 79 | model.add(Dense(mac_notes_vocabulary)) |
| 80 | model.add(Activation('softmax')) |
| 81 | model.compile(loss='categorical_crossentropy', optimizer='rmsprop') |
| 82 | return model # На излез дава моделиран модел на LSTM невронска мрежа |
| 83 | |
| 84 | def train_neural_network(model, i_neural_sequence, o_neural_sequence): # Функција за тренирање на невронската мрежа |
| 85 | filepath = "weights-{epoch:02d}-{loss:.4f}-bigger.hdf5" |
| 86 | checkpoint = ModelCheckpoint( |
| 87 | filepath, |
| 88 | monitor='loss', |
| 89 | verbose=0, |
| 90 | save_best_only=True, |
| 91 | mode='min' |
| 92 | ) |
| 93 | |
| 94 | callbacks_list = [checkpoint] |
| 95 | |
| 96 | model.fit(i_neural_sequence, o_neural_sequence, epochs=50, batch_size=10, callbacks=callbacks_list) |
| 97 | |
| 98 | |
| 99 | if __name__ == '__main__': |
| 100 | macedonian_notes = mac_notes() # Ја повикуваме функцијата за креирање вокабулар од мак. ноти |
| 101 | mac_notes_vocabulary = len(set(macedonian_notes)) |
| 102 | mac_notes_vocabulary2 = len(macedonian_notes) |
| 103 | print("Num vocab is: %s " % mac_notes_vocabulary) |
| 104 | print("Size is: %s " % mac_notes_vocabulary2) |
| 105 | i_neural_sequence, o_neural_sequence = io_neural_sequences(macedonian_notes,mac_notes_vocabulary) # Ја повикуваме функцијата која ни ги дава влезната и излезната секвенца за н. мрежа |
| 106 | model = model_neural_netrowk(i_neural_sequence, mac_notes_vocabulary) # Ja повикуваме функцијата за креирање на моделот |
| 107 | train_neural_network(model, i_neural_sequence, o_neural_sequence) # Ја повикуваме функцијата за тренирање на модел на невронска мрежа |