简单的LSTM生成钢琴纯音乐

每天逛一趟GitHub,向大神们学习。
1.拿出所有的音符

import glob
import pickle
from music21 import converter,instrument,note,chord,stream
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense,Dropout,LSTM,Activation,BatchNormalization
#from tensorflow.keras.utils import np_utils
from tensorflow.keras.callbacks import ModelCheckpointfrom keras.utils import np_utilsimport numpy as np#1.从midi文件中获取音符和和弦
def get_notes():notes=[]for file in glob.glob('./midi_songs/*.mid'):midi=converter.parse(file)print('Parsing %s'%file)notes_to_parse=Nonetry: # file has instrument partss2 = instrument.partitionByInstrument(midi)notes_to_parse = s2.parts[0].recurse() except: # file has notes in a flat structurenotes_to_parse = midi.flat.notesfor 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('data/notes','wb') as f:pickle.dump(notes,f)return notes

2.准备用于循环神经网络训练的数据,整合序列数据

def prepare_sequences(notes,n_vocab):#vocab#有多少种音符sequence_length=100#以100个notes为一个输入pitchnames=sorted(set(item for item in notes))#将所有note整合成集合并按出现次数排序note_to_int=dict((note,number) for number,note in enumerate(pitchnames))#将notes的内容和顺序排成字典,字符到数字的映射network_input=[]normalized_input=[]network_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])network_output.append([note_to_int[sequence_out]])n_patterns=len(network_input)#一共有多少个以100个数字为输入的网络可以用的数据normalized_input=np.reshape(network_input,(n_patterns,sequence_length,1))#一所有数据作为一个batch,数据变成rnn的输入格式normalized_input=normalized_input/float(n_vocab)#输入数据标准化network_output=np_utils.to_categorical(network_output)#输出的一维数字转换成独热编码格式return (network_input,network_output,normalized_input,pitchnames)

3.创建循环训练网络

def creat_network(network_input,n_vocab):model=Sequential()model.add(LSTM(512,input_shape=(network_input.shape[1],network_input.shape[2]),recurrent_dropout=0.3,return_sequences=True))model.add(LSTM(512,recurrent_dropout=0.3,return_sequences=True))model.add(LSTM(512))model.add(BatchNormalization())model.add(Dropout(0.3))model.add(Dense(256))model.add(Activation('relu'))model.add(BatchNormalization())model.add(Dropout(0.3))model.add(Dense(n_vocab))model.add(Activation('softmax'))model.compile(loss='categorical_crossentropy',optimizer='rmsprop')return model
def train(model,network_input,network_output):filepath="weights-improvement-{epoch:02d}-{loss:.4f}-bigger.hdf5"checkpoint=ModelCheckpoint(filepath,monitor='loss',verbose=0,save_best_only=True,mode='min')callbacks_list=[checkpoint]model.fit(network_input, network_output, epochs=5, batch_size=128, callbacks=callbacks_list)

4.训练

def train_network():notes=get_notes()n_vocab=len(set(notes))network_input,network_output,normalized_input,pitchnames=prepare_sequences(notes, n_vocab)model=creat_network(normalized_input,n_vocab)train(model,normalized_input,network_output)return (notes,n_vocab,network_input,normalized_input,pitchnames)
if __name__=="__main__":notes,n_vocab,network_input,normalized_input,pitchnames=train_network()

5.实际生成音乐

def generate_notes(model,network_input,pitchnames,n_vocab):start=np.random.randint(0,len(network_input)-1)#随机生成一个序列的数字print(start)int_to_note={number:note for number,note in enumerate(pitchnames)}pattern=network_input[start]prediction_output=[]for note_index in range(20):#生成500个notesprediction_input=np.reshape(pattern, (1,len(pattern),1))prediction_input=prediction_input/float(n_vocab)#归一化prediction=model.predict(prediction_input,verbose=0)index=np.argmax(prediction)#预测出来概率最大的哪一项print(index)result=int_to_note[index]print(result)prediction_output.append(result)pattern.append(index)pattern=pattern[1:len(pattern)]return prediction_output
def create_midi(prediction_output):""" convert the output from the prediction to notes and create a midi filefrom the notes """offset = 0output_notes = []# create note and chord objects based on the values generated by the modelfor pattern in prediction_output:# pattern is a chordif ('.' 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 = offsetoutput_notes.append(new_chord)# pattern is a noteelse:new_note = note.Note(pattern)new_note.offset = offsetnew_note.storedInstrument = instrument.Piano()output_notes.append(new_note)# increase offset each iteration so that notes do not stackoffset += 0.5midi_stream = stream.Stream(output_notes)midi_stream.write('midi', fp='test_output.mid')
#开始生成
from tensorflow.keras.models import load_model
def generate(notes,n_vocab,network_input,normalized_input,pitchnames):model=load_model('weights-improvement-05-4.4652-bigger.hdf5')prediction_output= generate_notes(model,network_input,pitchnames,n_vocab)create_midi(prediction_output)
generate(notes,n_vocab,network_input,normalized_input,pitchnames)

参考:https://github.com/Xunzhuo/LSTM-Music
资源:https://download.csdn.net/download/weixin_38226321/12619361


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部