Changes between Version 1 and Version 2 of AGMFM - 5.4. Имплементација


Ignore:
Timestamp:
11/06/18 16:47:21 (6 years ago)
Author:
Monika Rizova
Comment:

Legend:

Unmodified
Added
Removed
Modified
  • AGMFM - 5.4. Имплементација

    v1 v2  
    22
    33Системот за автоматско генерериње на македонска народна мелодија наречен MacedonMelody се состои од две python скрипти.  Првата скрипта се користи за креирање и  тренирање на моделот врз базата на податоци, додека во втората се генерира македонска народна мелодија врз база на тренираниот модел.
    4 
    5 Скрипта 1 – macedon_melody_train.py
     4**
     5Скрипта 1 – macedon_melody_train.py**
    66
    77import glob # За да можеме да пристапиме локално во системот
    88import pickle # За да ги зачуваме нотите во документ
    99import numpy # За менување на формата на влезот на невронската мрежа
     10from time import time
    1011from keras.models import Sequential
    1112from keras.layers import CuDNNLSTM
     
    2021   
    2122    macedonian_notes = [] # Листа за зачувување  на сите ноти од МИДИ документите
    22     for file in glob.glob("mac_midi/*.mid"):
    23        
     23    for file in glob.glob("mac_midi/*.mid"):       
    2424        macedonian_midi = converter.parse(file) #Парсирање на нотен запис од фајл
    2525        print("The song parsed is: %s " %file)
    26         # macedonian_midi.show('text') – За прикажување на содржините на миди документите       
    27        
     26
     27        # macedonian_midi.show('text') # За прикажување на содржините на миди документите               
    2828       
    2929        mac_notes_to_be_parsed = None       
     
    9393   
    9494    callbacks_list = [checkpoint]
    95 
    96     model.fit(i_neural_sequence, o_neural_sequence, epochs=50, batch_size=10, callbacks=callbacks_list)
    97    
    98    
     95    tensorboard = TensorBoard(log_dirr=”logs/{}”.format(time()))   
     96    model.fit(i_neural_sequence, o_neural_sequence, epochs=50, batch_size=50, callbacks=callbacks_list)
     97       
    9998if __name__ == '__main__':
    10099    macedonian_notes = mac_notes() # Ја повикуваме функцијата за креирање вокабулар од  мак. ноти
     
    106105    model = model_neural_netrowk(i_neural_sequence, mac_notes_vocabulary) # Ja повикуваме функцијата за креирање на моделот
    107106    train_neural_network(model, i_neural_sequence, o_neural_sequence) # Ја повикуваме функцијата за тренирање на модел на невронска мрежа
     107
     108**Скрипта 2 – macedon_melody_predict.py**
     109
     110import pickle
     111import numpy
     112from music21 import instrument, note, stream, chord, meter
     113from keras.models import Sequential
     114from keras.layers import Dense
     115from keras.layers import Dropout
     116from keras.layers import CuDNNLSTM
     117from keras.layers import Activation
     118
     119def io_neural_sequences(macedonian_notes,mac_notes_vocabulary): # Функција за дефинирање на влезната и излезната секвенца на моделот на невронската мрежа.     
     120    input_sequence = None
     121    output_sequence = None
     122    n_i_neural_sequence = None
     123    sequence_size = 150
     124    n_patterns = 0
     125    pitch_names = sorted(set(elem for elem in macedonian_notes))
     126    mac_notes_to_int = dict((note, number) for number, note in enumerate(pitch_names))
     127    i_neural_sequence = []
     128    o_neural_sequence = []
     129    for m in range(0, len(macedonian_notes)-sequence_size,1):
     130        input_sequence = macedonian_notes[m:m + sequence_size]
     131        output_sequence = macedonian_notes[m + sequence_size]
     132        i_neural_sequence.append([mac_notes_to_int[char] for char in input_sequence])
     133        o_neural_sequence.append(mac_notes_to_int[output_sequence])
     134    n_patterns = len(i_neural_sequence)
     135    n_i_neural_sequence = numpy.reshape(i_neural_sequence, (n_patterns,sequence_size,1))
     136    n_i_neural_sequence = n_i_neural_sequence / float(mac_notes_vocabulary)   
     137    return (i_neural_sequence, n_i_neural_sequence)
     138
     139def model_neural_netrowk(i_neural_sequence, mac_notes_vocabulary): # Функција за креирање на артитектура на секвенционен модел на невронска мрежа (го има истиот модел на невронска мрежа за тренирање, но на излез не враќа модел туку ги вчитуваме тежините од веќе тренираниот модел
     140    model = Sequential()
     141    model.add(CuDNNLSTM(256,input_shape=(i_neural_sequence.shape[1],neural_sequence.shape[2]),
     142    return_sequences=True))
     143    model.add(Dropout(0.3))
     144    model.add(CuDNNLSTM(512, return_sequences=True))
     145    model.add(Dropout(0.3))
     146    model.add(CuDNNLSTM(256))
     147    model.add(Dropout(0.3))
     148    model.add(Dense(256))
     149    model.add(Dense(mac_notes_vocabulary))
     150    model.add(Activation('softmax'))
     151    model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
     152    model.load_weights('weights.hdf5')
     153    return model
     154def mac_notes_generation(model, i_neural_sequence, pitch_names,mac_notes_vocabulary): # Функција за декодирање на излезот од тренираниот модел на мрежа
     155    start = numpy.random.randint(0, len(i_neural_sequence)-1) # Бираме случаен почеток за нота за     
     156    секвенцата на новата мелодија
     157    int_to_mac_notes = dict((number, note) for number, note in enumerate(pitch_names)) # Мапирање на висината на нотите од цели броеви во речник од ноти     
     158    pattern =  i_neural_sequence[start]
     159    prediction_output = []
     160    for note_index in range(400): # Генерирање на ноти за музичко дело со должина од приближно минута и 30 секунди
     161        prediction_input = numpy.reshape(pattern, (1, len(pattern), 1))
     162        n_prediction_input = prediction_input / float(mac_notes_vocabulary)
     163        prediction = model.predict(n_prediction_input, verbose=0)
     164        index = numpy.argmax(prediction)
     165        result = int_to_mac_notes[index]
     166        prediction_output.append(result)
     167        pattern.append(index)
     168        pattern = pattern[1:len(pattern)]
     169    return prediction_output # На излез се добива низа со 400 генерирани ноти
     170
     171def generate_macedon_melody(prediction_output): # Функција за декодирање на предвидените ноти во објекти Note и Chord, претставени во music21 за да можеме после да ја запишеме мелодијата во формат кој може да се слушне   
     172    offset = 0
     173    mac_output_notes = []
     174    #
     175    for pattern in prediction_output:
     176        # Доколку запишаната вредност е акорд
     177        if ('.' in pattern) or pattern.isdigit():
     178            notes_in_chord = pattern.split('.')
     179            notes = []
     180            for current_note in notes_in_chord:
     181                new_note = note.Note(int(current_note))
     182                new_note.storedInstrument = instrument.Piano()
     183                notes.append(new_note)
     184            new_chord = chord.Chord(notes)
     185            new_chord.offset = offset
     186            mac_output_notes.append(new_chord)
     187        # Доколку запишаната вредност е нота
     188        else:
     189            new_note = note.Note(pattern)
     190            new_note.offset = offset
     191            new_note.storedInstrument = instrument.Piano()
     192            mac_output_notes.append(new_note)
     193           
     194        # Растојание на нотите, за да не се случи нивно повторување (Вредноста е добиена со истражување на растојанието помеѓу нотите во песните за тренирање со помош на функцијата .show() на потокот на податоци).
     195        offset += 0.5
     196    mac_midi_stream = stream.Stream(mac_output_notes)       
     197    mac_midi_stream.write('midi', fp='ai_mac_melody.mid') # Запишување на предвидената мелодија во .mid формат
     198if __name__ == '__main__':
     199    #Вчитување на нотите врз кои беше трениран моделот
     200    with (open('data/macedonian_notes', 'rb')) as filepath:
     201        macedonian_notes = pickle.load(filepath)
     202    # Вокабулар на висина на ноти
     203    pitch_names = sorted(set(elem for elem in macedonian_notes))
     204    # Бројот на различни висини на ноти во песните за тренирање
     205    mac_notes_vocabulary = len(set(macedonian_notes))   
     206    i_neural_sequence, n_i_neural_sequence = io_neural_sequences(macedonian_notes, mac_notes_vocabulary)
     207    model = model_neural_netrowk(n_i_neural_sequence, mac_notes_vocabulary) 
     208    prediction_output = mac_notes_generation(model, i_neural_sequence, pitch_names,mac_notes_vocabulary)
     209    generate_macedon_melody(prediction_output) # Оваа функција генерира мак. народна мелодија и ја запишува во документ: ai_mac_melody.mid