Komponist mit langem Kurzzeitgedächtnis

Musik automatisch komponieren



Fast unmittelbar nachdem ich Programmieren gelernt hatte, wollte ich eine Software erstellen, die Musik komponieren kann.

Einige Jahre lang habe ich primitive Versuche unternommen, automatisch Musik für Visions of Chaos zu komponieren. Grundsätzlich wurden einfache mathematische Formeln oder genetische Mutationen zufälliger Notenfolgen verwendet. Nachdem ich kürzlich bescheidene Erfolge bei der Untersuchung und Anwendung von TensorFlow und neuronalen Netzen zur Suche nach zellularen Automaten erzielt hatte, beschloss ich, neuronale Netze zum Erstellen von Musik zu verwenden.

Wie funktioniert es?


Der Komponist unterrichtet ein neuronales Netzwerk mit langem Kurzzeitgedächtnis (LSTM). LSTM-Netzwerke eignen sich gut zur Vorhersage der nächsten Datensequenzen. Lesen Sie hier mehr über LSTM.


Ein LSTM-Netzwerk empfängt verschiedene Notenfolgen (in diesem Fall handelt es sich um einkanalige MIDI-Dateien). Nach einer ausreichenden Ausbildung erhält sie die Möglichkeit, Musik zu erstellen, die den Unterrichtsmaterialien ähnelt.


LSTM-Interna mögen einschüchternd wirken, aber die Verwendung von TensorFlow und / oder Keras vereinfacht die Erstellung und das Experimentieren von LSTM erheblich.

Quellmusik für das Modelltraining


Für solch einfache LSTM-Netzwerke reicht es für uns aus, dass die Quellkompositionen ein einzelner Midi-Kanal sind. Hervorragend geeignet sind Midi-Dateien von Solo bis Klavier. Ich fand Midi-Dateien mit Klaviersoli auf der Classical Piano Midi-Seite und in den Dateien und trainierte damit meine Modelle.

Ich habe die Musik verschiedener Komponisten in separate Ordner gelegt. Dank dessen kann der Benutzer Bach auswählen, auf die Schaltfläche Komponieren klicken und ein Lied erhalten, das (hoffentlich) wie Bach sein wird.

LSTM-Modell


Das Modell, auf dessen Grundlage ich den Code geschrieben habe, hat dieses Beispiel des Autors Sigurður Skúli Sigurgeirsson ausgewählt , über den er hier ausführlicher schreibt.

Ich habe das Skript lstm.py ausgeführt und nach 15 Stunden das Training abgeschlossen. Als ich Predict.py ausführte, um die MIDI-Dateien zu generieren, war ich enttäuscht, weil sie aus einer sich wiederholenden Notiz bestanden. Wenn ich das Training zweimal wiederholte, bekam ich die gleichen Ergebnisse.

Quellmodell

model = Sequential() model.add(CuDNNLSTM(512,input_shape=(network_input.shape[1], network_input.shape[2]),return_sequences=True)) model.add(Dropout(0.3)) model.add(CuDNNLSTM(512, return_sequences=True)) model.add(Dropout(0.3)) model.add(CuDNNLSTM(512)) model.add(Dense(256)) model.add(Dropout(0.3)) model.add(Dense(n_vocab)) model.add(Activation('softmax')) model.compile(loss='categorical_crossentropy', optimizer='rmsprop',metrics=["accuracy"]) 

Nachdem ich dem Skript eine Grafikausgabe hinzugefügt hatte, sah ich, warum mein Modell nicht funktionierte. Die Genauigkeit ist im Laufe der Zeit nicht so gewachsen, wie es sollte. Unten im Beitrag finden Sie gute Grafiken, die zeigen, wie das Arbeitsmodell aussehen soll.


Ich hatte keine Ahnung, warum es passiert ist. aber dieses Modell aufgegeben und begann, die Einstellungen anzupassen.

 model = Sequential() model.add(CuDNNLSTM(512, input_shape=(network_input.shape[1], network_input.shape[2]), return_sequences=True)) model.add(Dropout(0.2)) model.add(BatchNormalization()) model.add(CuDNNLSTM(256)) model.add(Dropout(0.2)) model.add(BatchNormalization()) model.add(Dense(128, activation="relu")) model.add(Dropout(0.2)) model.add(BatchNormalization()) model.add(Dense(n_vocab)) model.add(Activation('softmax')) model.compile(loss='categorical_crossentropy', optimizer='adam',metrics=["accuracy"]) 

Es ist kompakter und hat weniger LSTM-Schichten. Ich habe auch BatchNormalization hinzugefügt und es im sentdex-Video gesehen . Höchstwahrscheinlich gibt es bessere Modelle, aber dieses hat in all meinen Trainingseinheiten ziemlich gut funktioniert.

Beachten Sie, dass ich in beiden Modellen LSTM durch CuDNNLSTM ersetzt habe. So habe ich dank der Verwendung von Cuda ein viel schnelleres LSTM-Training erreicht. Wenn Sie keine GPU mit Cuda-Unterstützung haben , müssen Sie LSTM verwenden. Vielen Dank an sendtex für diesen Tipp. Das Erlernen neuer Modelle und das Erstellen von Midi-Dateien mit CuDNNLSTM ist etwa fünfmal schneller.

Wie lange sollte das Modell trainiert werden?


Die Ähnlichkeit der Ergebnisse mit der Originalmusik hängt von der Dauer des Trainings des Modells (der Anzahl der Epochen) ab. Wenn es zu wenige Epochen gibt, enthält das resultierende Ergebnis zu viele sich wiederholende Noten. Wenn es zu viele Epochen gibt, wird das Modell umgeschult und einfach die Originalmusik kopiert.

Aber woher weißt du, wie viele Epochen zu stoppen sind?

Eine einfache Lösung besteht darin, einen Rückruf hinzuzufügen, in dem das Modell und das Genauigkeits- / Verlustdiagramm alle 50 Epochen eines Trainingslaufs in 500 Epochen gespeichert werden. Dank dessen erhalten Sie nach Abschluss des Trainings Modelle und Grafiken in Schritten von 50 Epochen, die zeigen, wie das Training verläuft.

Hier sind die Ergebnisse der Grafiken eines Laufs mit Speichern alle 50 Epochen, kombiniert in einem animierten GIF.


Dies sind die Grafiken, die wir sehen möchten. Die Verluste sollten sinken und niedrig bleiben. Die Genauigkeit sollte steigen und nahe bei 100% bleiben.

Es ist erforderlich, ein Modell mit der Anzahl der Epochen zu verwenden, die dem Zeitpunkt entspricht, an dem die Graphen zum ersten Mal an ihre Grenzen stießen. Für die oben gezeigte Grafik sind es 150 Epochen. Wenn Sie ältere Modelle verwenden, werden diese umgeschult und führen höchstwahrscheinlich zu einem einfachen Kopieren des Quellmaterials.

Das diesen Spalten entsprechende Modell wurde auf Midi-Dateien der Kategorie Anthems trainiert, die von hier stammen .



MIDI-Daten in einem Modell mit 150 Epochen ausgeben.



Midi-Ausgabe in einem 100-Epochen-Modell.

Selbst ein Modell mit 100 Epochen kann die Quelle zu genau kopieren. Dies kann auf eine relativ kleine Auswahl von MIDI-Dateien für das Training zurückzuführen sein. Mit mehr Notizen ist das Lernen besser.

Wenn das Lernen schlecht wird



Das Bild oben zeigt ein Beispiel dafür, was während des Trainings passieren kann und was passiert. Die Verluste werden reduziert und die Genauigkeit wie üblich erhöht, aber plötzlich werden sie verrückt. In diesem Stadium kann es sich auch lohnen, anzuhalten. Das Modell wird (zumindest nach meiner Erfahrung) nicht mehr richtig lernen. In diesem Fall ist das gespeicherte Modell mit 100 Epochen immer noch zu zufällig, und mit 150 Epochen ist der Moment des Modellfehlers bereits vergangen. Jetzt bin ich alle 25 Epochen gerettet, um genau den idealen Moment des Modells mit dem besten Training zu finden, noch bevor sie umschult und abstürzt.


Ein weiteres Beispiel für Lernfehler. Dieses Modell wurde auf Midi-Dateien trainiert, die von hier stammen . In diesem Fall hielt sie sich etwas länger als 200 Epochen. Bei Verwendung eines Modells mit 200 Epochen wird in Midi das folgende Ergebnis erzielt.



Ohne die Erstellung von Diagrammen würden wir nie wissen, ob das Modell Probleme hat und wann sie auftreten, und könnten auch kein gutes Modell erhalten, ohne von vorne zu beginnen.

Andere Beispiele




Ein Modell mit 75 Epochen, das auf den Kompositionen von Chopin basiert.



Ein Modell aus der 50er-Ära, das auf Midi-Dateien für Weihnachtskompositionen basiert.



Ein 100-Epochen-Modell basierend auf Midi-Dateien für Weihnachtskompositionen . Aber sind sie wirklich "Weihnachten"?



Ein Modell aus 300 Epochen, das auf Bach-Midi-Dateien basiert, die von hier und von hier stammen .



Ein Modell aus 200 Epochen, das auf Balakirevs einziger Midi-Datei basiert.



Modell mit 200 Epochen, basierend auf Debussy- Kompositionen.



Ein Modell aus 175 Jahren, das auf Mozarts Kompositionen basiert.



Ein Modell mit 100 Epochen basierend auf Schubert- Kompositionen.



Ein Modell aus der 200er-Ära, das auf Schumann- Kompositionen basiert.



Ein Modell aus der 200er-Ära, das auf Tschaikowskys Kompositionen basiert.



Ein Modell mit 175 Epochen basierend auf Volksliedern.



Modell mit 100 Epochen basierend auf Schlafliedern.



Ein 100-Ära-Modell basierend auf Hochzeitsmusik.



Ein Modell aus 200 Epochen, das auf meinen eigenen Midi-Dateien basiert, die aus meinen YouTube-Video- Soundtracks stammen. Es kann ein bisschen umgeschult werden, weil es im Grunde Kopien meiner kurzen Ein- und Zweitakt-Midi-Dateien generiert.

Scores


Sobald Sie Ihre Midi-Dateien erhalten haben, können Sie sie mit Online-Tools wie SolMiRe in Partituren konvertieren. Unten ist die Punktzahl der oben dargestellten Midi-Softology-Datei mit 200 Epochen aufgeführt.



Wo kann ich den Komponisten testen?


LSTM Composer ist jetzt in Visions of Chaos enthalten .


Wählen Sie einen Stil aus der Dropdown-Liste aus und klicken Sie auf Verfassen. Wenn Sie das erforderliche Minimum an Python und TensorFlow installiert haben (siehe Anweisungen hier ), erhalten Sie in wenigen Sekunden (wenn Sie eine schnelle GPU haben) eine neue maschinengeschriebene MIDI-Datei, die Sie anhören und für andere Zwecke verwenden können. Kein Urheberrecht, keine Lizenzgebühren. Wenn Ihnen die Ergebnisse nicht gefallen, können Sie erneut auf "Verfassen" klicken. Nach einigen Sekunden ist eine neue Komposition fertig.

Die Ergebnisse können noch nicht als vollwertige Kompositionen betrachtet werden, aber sie enthalten interessante kleine Notenfolgen, mit denen ich in Zukunft Musik machen werde. In dieser Hinsicht kann der LSTM-Komponist eine gute Inspirationsquelle für neue Kompositionen sein.

Python-Quelle


Unten finden Sie den Python-Skriptcode, den ich für das LSTM-Training und die Prognose verwendet habe. Damit diese Skripte funktionieren, muss Visions of Chaos nicht installiert werden, und das Lernen und Generieren von MIDI funktioniert über die Befehlszeile.

Hier ist das Trainingsskript lstm_music_train.py

lstm_music_train.py
 # based on code from https://github.com/Skuldur/Classical-Piano-Composer # to use this script pass in; # 1. the directory with midi files # 2. the directory you want your models to be saved to # 3. the model filename prefix # 4. how many total epochs you want to train for # eg python -W ignore "C:\\LSTM Composer\\lstm_music_train.py" "C:\\LSTM Composer\\Bach\\" "C:\\LSTM Composer\\" "Bach" 500 import os import tensorflow as tf # ignore all info and warning messages os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' tf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.ERROR) import glob import pickle import numpy import sys import keras import matplotlib.pyplot as plt from music21 import converter, instrument, note, chord from datetime import datetime from keras.models import Sequential from keras.layers.normalization import BatchNormalization from keras.layers import Dense from keras.layers import Dropout from keras.layers import CuDNNLSTM from keras.layers import Activation from keras.utils import np_utils from keras.callbacks import TensorBoard from shutil import copyfile # name of midi file directory, model directory, model file prefix, and epochs mididirectory = str(sys.argv[1]) modeldirectory = str(sys.argv[2]) modelfileprefix = str(sys.argv[3]) modelepochs = int(sys.argv[4]) notesfile = modeldirectory + modelfileprefix + '.notes' # callback to save model and plot stats every 25 epochs class CustomSaver(keras.callbacks.Callback): def __init__(self): self.epoch = 0 # This function is called when the training begins def on_train_begin(self, logs={}): # Initialize the lists for holding the logs, losses and accuracies self.losses = [] self.acc = [] self.logs = [] def on_epoch_end(self, epoch, logs={}): # Append the logs, losses and accuracies to the lists self.logs.append(logs) self.losses.append(logs.get('loss')) self.acc.append(logs.get('acc')*100) # save model and plt every 50 epochs if (epoch+1) % 25 == 0: sys.stdout.write("\nAuto-saving model and plot after {} epochs to ".format(epoch+1)+"\n"+modeldirectory + modelfileprefix + "_" + str(epoch+1).zfill(3) + ".model\n"+modeldirectory + modelfileprefix + "_" + str(epoch+1).zfill(3) + ".png\n\n") sys.stdout.flush() self.model.save(modeldirectory + modelfileprefix + '_' + str(epoch+1).zfill(3) + '.model') copyfile(notesfile,modeldirectory + modelfileprefix + '_' + str(epoch+1).zfill(3) + '.notes'); N = numpy.arange(0, len(self.losses)) # Plot train loss, train acc, val loss and val acc against epochs passed plt.figure() plt.subplots_adjust(hspace=0.7) plt.subplot(2, 1, 1) # plot loss values plt.plot(N, self.losses, label = "train_loss") plt.title("Loss [Epoch {}]".format(epoch+1)) plt.xlabel('Epoch') plt.ylabel('Loss') plt.subplot(2, 1, 2) # plot accuracy values plt.plot(N, self.acc, label = "train_acc") plt.title("Accuracy % [Epoch {}]".format(epoch+1)) plt.xlabel("Epoch") plt.ylabel("Accuracy %") plt.savefig(modeldirectory + modelfileprefix + '_' + str(epoch+1).zfill(3) + '.png') plt.close() # train the neural network def train_network(): sys.stdout.write("Reading midi files...\n\n") sys.stdout.flush() notes = get_notes() # get amount of pitch names n_vocab = len(set(notes)) sys.stdout.write("\nPreparing note sequences...\n") sys.stdout.flush() network_input, network_output = prepare_sequences(notes, n_vocab) sys.stdout.write("\nCreating CuDNNLSTM neural network model...\n") sys.stdout.flush() model = create_network(network_input, n_vocab) sys.stdout.write("\nTraining CuDNNLSTM neural network model...\n\n") sys.stdout.flush() train(model, network_input, network_output) # get all the notes and chords from the midi files def get_notes(): # remove existing data file if it exists if os.path.isfile(notesfile): os.remove(notesfile) notes = [] for file in glob.glob("{}/*.mid".format(mididirectory)): midi = converter.parse(file) sys.stdout.write("Parsing %s ...\n" % file) sys.stdout.flush() notes_to_parse = None try: # file has instrument parts s2 = instrument.partitionByInstrument(midi) notes_to_parse = s2.parts[0].recurse() except: # file has notes in a flat structure notes_to_parse = midi.flat.notes for element in notes_to_parse: if isinstance(element, note.Note): notes.append(str(element.pitch)) elif isinstance(element, chord.Chord): notes.append('.'.join(str(n) for n in element.normalOrder)) with open(notesfile,'wb') as filepath: pickle.dump(notes, filepath) return notes # prepare the sequences used by the neural network def prepare_sequences(notes, n_vocab): sequence_length = 100 # get all pitch names pitchnames = sorted(set(item for item in notes)) # create a dictionary to map pitches to integers note_to_int = dict((note, number) for number, note in enumerate(pitchnames)) network_input = [] network_output = [] # create input sequences and the corresponding outputs for i in range(0, len(notes) - sequence_length, 1): sequence_in = notes[i:i + sequence_length] # needs to take into account if notes in midi file are less than required 100 ( mod ? ) sequence_out = notes[i + sequence_length] # needs to take into account if notes in midi file are less than required 100 ( mod ? ) network_input.append([note_to_int[char] for char in sequence_in]) network_output.append(note_to_int[sequence_out]) n_patterns = len(network_input) # reshape the input into a format compatible with CuDNNLSTM layers network_input = numpy.reshape(network_input, (n_patterns, sequence_length, 1)) # normalize input network_input = network_input / float(n_vocab) network_output = np_utils.to_categorical(network_output) return (network_input, network_output) # create the structure of the neural network def create_network(network_input, n_vocab): ''' """ create the structure of the neural network """ model = Sequential() model.add(CuDNNLSTM(512, input_shape=(network_input.shape[1], network_input.shape[2]), return_sequences=True)) model.add(Dropout(0.3)) model.add(CuDNNLSTM(512, return_sequences=True)) model.add(Dropout(0.3)) model.add(CuDNNLSTM(512)) model.add(Dense(256)) model.add(Dropout(0.3)) model.add(Dense(n_vocab)) model.add(Activation('softmax')) model.compile(loss='categorical_crossentropy', optimizer='rmsprop',metrics=["accuracy"]) ''' model = Sequential() model.add(CuDNNLSTM(512, input_shape=(network_input.shape[1], network_input.shape[2]), return_sequences=True)) model.add(Dropout(0.2)) model.add(BatchNormalization()) model.add(CuDNNLSTM(256)) model.add(Dropout(0.2)) model.add(BatchNormalization()) model.add(Dense(128, activation="relu")) model.add(Dropout(0.2)) model.add(BatchNormalization()) model.add(Dense(n_vocab)) model.add(Activation('softmax')) model.compile(loss='categorical_crossentropy', optimizer='adam',metrics=["accuracy"]) return model # train the neural network def train(model, network_input, network_output): # saver = CustomSaver() # history = model.fit(network_input, network_output, epochs=modelepochs, batch_size=50, callbacks=[tensorboard]) history = model.fit(network_input, network_output, epochs=modelepochs, batch_size=50, callbacks=[CustomSaver()]) # evaluate the model print("\nModel evaluation at the end of training") train_acc = model.evaluate(network_input, network_output, verbose=0) print(model.metrics_names) print(train_acc) # save trained model model.save(modeldirectory + modelfileprefix + '_' + str(modelepochs) + '.model') # delete temp notes file os.remove(notesfile) if __name__ == '__main__': train_network() 

Und hier ist das Generierungsskript midi lstm_music_predict.py :

lstm_music_predict.py
 # based on code from https://github.com/Skuldur/Classical-Piano-Composer # to use this script pass in; # 1. path to notes file # 2. path to model # 3. path to midi output # eg python -W ignore "C:\\LSTM Composer\\lstm_music_predict.py" "C:\\LSTM Composer\\Bach.notes" "C:\\LSTM Composer\\Bach.model" "C:\\LSTM Composer\\Bach.mid" # ignore all info and warning messages import os os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' import tensorflow as tf tf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.ERROR) import pickle import numpy import sys import keras.models from music21 import instrument, note, stream, chord from keras.models import Sequential from keras.layers import Dense from keras.layers import Dropout from keras.layers import Activation # name of weights filename notesfile = str(sys.argv[1]) modelfile = str(sys.argv[2]) midifile = str(sys.argv[3]) # generates a piano midi file def generate(): sys.stdout.write("Loading notes data file...\n\n") sys.stdout.flush() #load the notes used to train the model with open(notesfile, 'rb') as filepath: notes = pickle.load(filepath) sys.stdout.write("Getting pitch names...\n\n") sys.stdout.flush() # Get all pitch names pitchnames = sorted(set(item for item in notes)) # Get all pitch names n_vocab = len(set(notes)) sys.stdout.write("Preparing sequences...\n\n") sys.stdout.flush() network_input, normalized_input = prepare_sequences(notes, pitchnames, n_vocab) sys.stdout.write("Loading LSTM neural network model...\n\n") sys.stdout.flush() model = create_network(normalized_input, n_vocab) sys.stdout.write("Generating note sequence...\n\n") sys.stdout.flush() prediction_output = generate_notes(model, network_input, pitchnames, n_vocab) sys.stdout.write("\nCreating MIDI file...\n\n") sys.stdout.flush() create_midi(prediction_output) # prepare the sequences used by the neural network def prepare_sequences(notes, pitchnames, n_vocab): # map between notes and integers and back note_to_int = dict((note, number) for number, note in enumerate(pitchnames)) sequence_length = 100 network_input = [] output = [] for i in range(0, len(notes) - sequence_length, 1): sequence_in = notes[i:i + sequence_length] sequence_out = notes[i + sequence_length] network_input.append([note_to_int[char] for char in sequence_in]) output.append(note_to_int[sequence_out]) n_patterns = len(network_input) # reshape the input into a format compatible with LSTM layers normalized_input = numpy.reshape(network_input, (n_patterns, sequence_length, 1)) # normalize input normalized_input = normalized_input / float(n_vocab) return (network_input, normalized_input) # create the structure of the neural network def create_network(network_input, n_vocab): model = keras.models.load_model(modelfile) return model # generate notes from the neural network based on a sequence of notes def generate_notes(model, network_input, pitchnames, n_vocab): # pick a random sequence from the input as a starting point for the prediction start = numpy.random.randint(0, len(network_input)-1) int_to_note = dict((number, note) for number, note in enumerate(pitchnames)) pattern = network_input[start] prediction_output = [] # generate 500 notes for note_index in range(500): prediction_input = numpy.reshape(pattern, (1, len(pattern), 1)) prediction_input = prediction_input / float(n_vocab) prediction = model.predict(prediction_input, verbose=0) index = numpy.argmax(prediction) result = int_to_note[index] prediction_output.append(result) pattern.append(index) pattern = pattern[1:len(pattern)] if (note_index + 1) % 50 == 0: sys.stdout.write("{} out of 500 notes generated\n".format(note_index+1)) sys.stdout.flush() return prediction_output # convert the output from the prediction to notes and create a midi file from the notes def create_midi(prediction_output): offset = 0 output_notes = [] # create note and chord objects based on the values generated by the model for pattern in prediction_output: # pattern is a chord if ('.' in pattern) or pattern.isdigit(): notes_in_chord = pattern.split('.') notes = [] for current_note in notes_in_chord: new_note = note.Note(int(current_note)) new_note.storedInstrument = instrument.Piano() notes.append(new_note) new_chord = chord.Chord(notes) new_chord.offset = offset output_notes.append(new_chord) # pattern is a note else: new_note = note.Note(pattern) new_note.offset = offset new_note.storedInstrument = instrument.Piano() output_notes.append(new_note) # increase offset each iteration so that notes do not stack offset += 0.5 midi_stream = stream.Stream(output_notes) midi_stream.write('midi', fp=midifile) if __name__ == '__main__': generate() 

Modelldateigrößen


Der Nachteil der Einbeziehung neuronaler Netze in Visions of Chaos ist die Größe der Dateien. Wenn die Generierung des Modells schneller wäre, würde ich einfach eine Schaltfläche hinzufügen, damit der Endbenutzer die Modelle selbst trainieren kann. Da einige der Schulungen für viele Modelle mehrere Tage dauern können, ist dies nicht besonders praktisch. Es schien mir, dass es besser ist, das gesamte Training und Testen selbst durchzuführen und nur die besten Arbeitsmodelle hinzuzufügen. Dies bedeutet auch, dass der Endbenutzer nur einen Knopf drücken muss und trainierte Modelle musikalische Kompositionen erstellen.

Jedes der Modelle hat eine Größe von 22 Megabyte. Unter den Bedingungen des modernen Internets ist dies nicht so sehr, aber im Laufe der Jahre der Entwicklung hat Visions of Chaos allmählich an Größe zugenommen und ist erst kürzlich plötzlich von 70 auf 91 MB gestiegen (aufgrund des Suchmodells für zellulare Automaten). Daher habe ich bisher nur ein Modell zum Hauptinstallationsprogramm von Visions of Chaos hinzugefügt. Für Benutzer, die mehr wollen, habe ich einen Link zu weiteren 1 GB Modellen gepostet. Sie können auch das obige Skript verwenden, um ihre eigenen Modelle basierend auf ihren MIDI-Dateien zu erstellen.

Was weiter?


In dieser Phase ist der LSTM-Komponist das einfachste Beispiel für die Verwendung neuronaler Netze zum Komponieren von Musik.

Ich habe bereits andere Musikkomponisten in neuronalen Netzen gefunden, mit denen ich in Zukunft experimentieren werde. Sie können also erwarten, dass es in Visions of Chaos neue Möglichkeiten gibt, automatisch Musik zu komponieren.

Source: https://habr.com/ru/post/de470127/


All Articles