ملحن مع ذاكرة طويلة الأجل

يؤلف الموسيقى تلقائيًا



بعد أن تعلمت البرمجة تقريبًا ، أردت إنشاء برنامج قادر على تأليف الموسيقى.

لعدة سنوات قمت بمحاولات بدائية لتكوين الموسيقى تلقائيًا لـ Visions of Chaos . في الأساس ، تم استخدام الصيغ الرياضية البسيطة أو الطفرات الجينية للتتابعات العشوائية من الملاحظات. بعد أن حققت مؤخرًا نجاحًا متواضعًا في دراسة وتطبيق TensorFlow والشبكات العصبية للبحث عن automata الخلوية ، قررت أن أحاول استخدام الشبكات العصبية لإنشاء موسيقى.

كيف يعمل؟


الملحن يعلم شبكة عصبية مع ذاكرة طويلة الأجل (LSTM). شبكات LSTM مناسبة تمامًا للتنبؤ بما يأتي بعد ذلك في تسلسل البيانات. قراءة المزيد عن LSTM هنا .


تتلقى شبكة LSTM تسلسلات مختلفة من الملاحظات (في هذه الحالة ، هذه هي ملفات midi أحادية القناة). بعد التدريب الكافي ، تتاح لها الفرصة لإنشاء موسيقى مماثلة للمواد التعليمية.


قد تبدو LSTM الداخلية مخيفة ، لكن استخدام TensorFlow و / أو Keras يبسط بشكل كبير إنشاء LSTM وتجريبه.

موسيقى المصدر للتدريب النموذجي


بالنسبة إلى شبكات LSTM البسيطة ، يكفي أن تكون التراكيب المصدر قناة ميدي واحدة. كبيرة لهذا هي ملفات ميدي منفردا إلى البيانو. لقد وجدت ملفات midi مع البيانو المعزوفات المنفردة على صفحة البيانو الكلاسيكية Midi و mfiles ، واستخدمتها لتدريب نماذجي .

أضع موسيقى الملحنين المختلفين في مجلدات منفصلة. بفضل هذا ، يمكن للمستخدم تحديد Bach ، انقر فوق الزر "إنشاء" والحصول على أغنية (نأمل) أن تكون مثل Bach.

نموذج LSTM


حدد النموذج الذي قمت على أساسه الرمز هذا المثال للمؤلف Sigurður Skúli Sigurgeirsson ، الذي يكتب عنه بمزيد من التفاصيل هنا .

قمت بتشغيل البرنامج النصي lstm.py وبعد 15 ساعة أكملت التدريب. عندما كنت أقوم بتوقّع التنبؤ. py لإنشاء ملفات midi ، شعرت بخيبة أمل لأنها كانت تتكون من ملاحظة متكررة واحدة. تكرار التدريب مرتين ، حصلت على نفس النتائج.

نموذج المصدر

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"]) 

إنه أكثر إحكاما ولديه طبقات LSTM أقل. أضفت أيضا BatchNormalization ، رؤيته في الفيديو sentdex . على الأرجح ، هناك نماذج أفضل ، لكن هذا النموذج نجح جيدًا في جميع دوراتي التدريبية.

لاحظ أنه في كلا النموذجين قمت باستبدال LSTM بـ CuDNNLSTM. لذا فقد حصلت على تدريب أسرع بكثير في LSTM بفضل استخدام Cuda. إذا لم يكن لديك GPU مع دعم Cuda ، فعليك استخدام LSTM. شكرا ل sendtex لهذه النصيحة. تعلم نماذج جديدة وتكوين ملفات midi باستخدام CuDNNLSTM أسرع بنحو خمس مرات.

كم من الوقت يجب تدريب النموذج


يعتمد تشابه النتائج مع الموسيقى الأصلية على مدة التدريب النموذجي (عدد العصور). إذا كان هناك عدد قليل جدًا من العصور ، فستكون للنتيجة الناتجة الكثير من الملاحظات المتكررة. إذا كان هناك الكثير من العصور ، فسيتم إعادة تدريب النموذج وببساطة نسخ الموسيقى الأصلية.

ولكن كيف يمكنك أن تعرف كم من العصور لوقف؟

يتمثل الحل البسيط في إضافة رد اتصال يقوم بتخزين النموذج ودقة / خسارة الرسم البياني كل 50 عصور في دورة تدريبية في 500 عصر. بفضل هذا ، بعد الانتهاء من التدريب ، ستحصل على نماذج ورسوم بيانية بزيادة قدرها 50 عصور ، توضح كيفية سير التدريب.

فيما يلي نتائج الرسوم البيانية لتشغيل واحد مع توفير كل 50 عصر ، مدمجة في صورة GIF متحركة واحدة.


هذه هي الرسوم البيانية التي نريد أن نرى. يجب أن تسقط الخسائر وتبقى منخفضة. يجب زيادة الدقة وتبقى قريبة من 100 ٪.

من الضروري استخدام نموذج مع عدد من الحقائب المقابلة للحظة التي وصلت فيها الرسوم البيانية لأول مرة إلى حدودها. بالنسبة للرسم البياني الموضح أعلاه ، سيكون 150 عصرًا. إذا كنت تستخدم الموديلات القديمة ، فسيتم إعادة تدريبها وعلى الأرجح ستؤدي إلى نسخ بسيطة للمواد المصدر.

تم تدريب النموذج المقابل لهذه الأعمدة على ملفات midi من فئة الأناشيد المأخوذة من هنا .



إخراج البيانات ميدي في نموذج مع 150 عصور.



ميدي الإخراج في نموذج 100 عصر.

حتى النموذج الذي يحتوي على 100 عصر يمكنه نسخ المصدر بدقة شديدة. قد يكون هذا بسبب عينة صغيرة نسبيا من ملفات midi للتدريب. مع مزيد من الملاحظات ، والتعلم هو أفضل.

عندما يسير التعلم



توضح الصورة أعلاه مثالًا لما يمكن أن يحدث وما يحدث أثناء التدريب. يتم تقليل الخسائر ، وزيادة الدقة ، كالمعتاد ، ولكن فجأة تبدأ بالجنون. في هذه المرحلة ، قد يكون من المفيد أيضًا التوقف. لن يتعلم النموذج مرة أخرى (على الأقل في تجربتي) بشكل صحيح. في هذه الحالة ، لا يزال النموذج المحفوظ الذي يحتوي على 100 عصور عشوائيًا للغاية ، ومع 150 عصرًا انتهت لحظة فشل النموذج بالفعل. الآن ، يتم حفظي في كل 25 عصرًا للعثور على اللحظة المثالية للنموذج تمامًا مع أفضل تدريب ، حتى قبل إعادة تدريبها وتعطلها.


مثال آخر على خطأ التعلم. تم تدريب هذا النموذج على ملفات midi مأخوذة من هنا . في هذه الحالة ، حافظت على صحتها لفترة أطول بقليل من 200 عصر. عند استخدام نموذج يحتوي على 200 عصر ، يتم الحصول على النتيجة التالية في Midi.



بدون إنشاء الرسوم البيانية ، لن نعرف أبدًا ما إذا كان النموذج يواجه مشاكل ومتى نشأت ، وكذلك لا يمكن الحصول على نموذج جيد دون البدء من نقطة الصفر.

أمثلة أخرى




نموذج مع 75 عصور ، تم إنشاؤه على أساس تكوينات شوبان .



نموذج من خمسين عصرًا يستند إلى ملفات Midi لتركيبات عيد الميلاد .



نموذج 100 عصر يعتمد على ملفات Midi لتركيبات عيد الميلاد . ولكن هل هم حقا "عيد الميلاد"؟



نموذج 300 عصر يعتمد على ملفات Bach Midi مأخوذة من هنا ومن هنا .



نموذج 200 عصر يعتمد على ملف Midi الوحيد بالاكيرف الذي تم التقاطه هنا .



نموذج مع 200 عصور ، استنادا إلى التراكيب ديبوسي .



نموذج من عصر 175 يستند إلى مؤلفات موزارت.



نموذج مع 100 عصور على أساس مؤلفات شوبرت .



نموذج من 200 عصر قائم على مؤلفات شومان .



نموذج من 200 عصر قائم على مؤلفات تشايكوفسكي .



نموذج مع 175 عصور على أساس الأغاني الشعبية.



نموذج مع 100 عصور على أساس التهويدات.



نموذج من 100 عصر يعتمد على موسيقى الزفاف.



نموذج 200 عصر يعتمد على ملفات ميدي الخاصة بي المأخوذة من مقاطع الفيديو الخاصة بي على YouTube . قد يتم إعادة تدريبه بعض الشيء لأنه يقوم بشكل أساسي بإنشاء نسخ من ملفات midi القصيرة ذات السكتين الواحدة والثانية.

عشرات


بمجرد الحصول على ملفات midi الخاصة بك ، يمكنك استخدام أدوات عبر الإنترنت مثل SolMiRe لتحويلها إلى نتائج. في ما يلي نتيجة ملف midi Softology 200-epoch الوارد أعلاه.



أين يمكنني اختبار الملحن


يتم تضمين LSTM الملحن الآن في رؤى الفوضى .


حدد نمطًا من القائمة المنسدلة وانقر فوق "إنشاء". إذا قمت بتثبيت الحد الأدنى الضروري من Python و TensorFlow (انظر التعليمات هنا ) ، فستتلقى في غضون ثوانٍ قليلة (إذا كان لديك وحدة معالجة الرسومات السريعة) ملفًا جديدًا يتكون من آلة ، ويمكنك الاستماع إليه واستخدامه لأي غرض آخر. لا حقوق الطبع والنشر ، لا حقوق الملكية. إذا لم تعجبك النتائج ، فيمكنك النقر فوق "إنشاء" مرة أخرى وبعد بضع ثوانٍ ، ستكون التركيبة الجديدة جاهزة.

لا يمكن اعتبار النتائج بعد مقطوعات كاملة ، ولكن لديها تسلسلات صغيرة ومثيرة للاهتمام من الملاحظات التي سأستخدمها لإنشاء موسيقى في المستقبل. في هذا الصدد ، يمكن أن يكون ملحن LSTM مصدرًا جيدًا للإلهام للمكونات الجديدة.

مصدر بايثون


يوجد أدناه رمز البرنامج النصي Python الذي استخدمته للتدريب والتنبؤ في LSTM. لكي تعمل هذه البرامج النصية ، ليس من الضروري تثبيت Visions of Chaos ، وسيعمل تعلم وتوليد midi من سطر الأوامر.

هنا هو السيناريو التدريب 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() 

وفي ما lstm_music_predict.py النص البرمجي للجيل 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() 

أحجام الملفات النموذجية


عيب تضمين الشبكات العصبية في رؤى الفوضى هو حجم الملفات. إذا كان توليد النموذج أسرع ، فسأضيف زرًا حتى يتسنى للمستخدم النهائي تدريب النماذج بنفسه. ولكن نظرًا لأن بعض الدورات التدريبية للعديد من النماذج قد تستغرق عدة أيام ، فإن هذا ليس عمليًا بشكل خاص. بدا لي أنه من الأفضل القيام بكل التدريب واختبار نفسك ، وإضافة فقط أفضل النماذج العاملة. هذا يعني أيضًا أن المستخدم النهائي يحتاج فقط إلى الضغط على زر ، وأن النماذج المدربة ستنشئ مقطوعات موسيقية.

يبلغ حجم كل طراز 22 ميجابايت. في ظل ظروف الإنترنت الحديثة ، ليس هذا كثيرًا ، ولكن على مدار سنوات التطوير ، ازداد حجم رؤى Chaos تدريجياً ، ومؤخراً زادت بشكل مفاجئ من 70 إلى 91 ميغابايت (بسبب نموذج البحث عن الأوتوماتة الخلوية). لذلك ، أضفت حتى الآن نموذجًا واحدًا فقط إلى أداة تثبيت Visions of Chaos. بالنسبة للمستخدمين الذين يريدون المزيد ، فقد نشرت رابطًا لطرازات 1 غيغابايت أخرى. يمكنهم أيضًا استخدام البرنامج النصي أعلاه لإنشاء نماذج خاصة بهم استنادًا إلى ملفات midi الخاصة بهم.

ما التالي؟


في هذه المرحلة ، يعد ملحن LSTM أبسط مثال على استخدام الشبكات العصبية لإنشاء الموسيقى.

لقد وجدت بالفعل ملحنين موسيقيين آخرين على شبكات عصبية سوف أجربها في المستقبل ، لذلك يمكنك أن تتوقع أن في Visions of Chaos ستكون هناك إمكانيات جديدة لتأليف الموسيقى تلقائيًا.

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


All Articles