Yassmen commited on
Commit
306bbb1
·
verified ·
1 Parent(s): 5530a43

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +70 -22
app.py CHANGED
@@ -11,74 +11,111 @@ from streamlit_lottie import st_lottie
11
 
12
 
13
  ####################### Music Generation Functions #######################
14
- def generate(seq_len, x):
15
  """ Generate a piano midi file """
 
16
  with open('final_notes', 'rb') as filepath:
17
  notes = pickle.load(filepath)
18
 
 
19
  pitchnames = sorted(set(item for item in notes))
20
  n_vocab = len(set(notes))
21
 
22
- network_input, normalized_input = prepare_sequences(notes, pitchnames, n_vocab, seq_length=seq_len)
23
  model = create_network(normalized_input, n_vocab)
24
  prediction_output = generate_notes(model, network_input, pitchnames, n_vocab, x)
25
  create_midi(prediction_output)
26
 
27
- def prepare_sequences(notes, pitchnames, n_vocab, seq_length):
 
 
 
28
  note_to_int = dict((note, number) for number, note in enumerate(pitchnames))
 
 
29
  network_input = []
30
  normalized_input = []
31
  output = []
32
- for i in range(0, len(notes) - seq_length, 1):
33
- sequence_in = notes[i:i + seq_length]
34
  sequence_out = notes[i + sequence_length]
35
  network_input.append([note_to_int[char] for char in sequence_in])
36
  output.append(note_to_int[sequence_out])
37
 
38
  n_patterns = len(network_input)
39
- normalized_input = np.reshape(network_input, (n_patterns, seq_length, 1))
 
 
 
40
  normalized_input = normalized_input / float(n_vocab)
41
 
42
  return (network_input, normalized_input)
43
 
44
-
45
  def create_network(network_input, n_vocab):
46
- model = tf.keras.Sequential()
47
- model.add(tf.keras.layers.LSTM(512, input_shape=(network_input.shape[1], network_input.shape[2]), return_sequences=True, recurrent_dropout=0.3))
48
- model.add(tf.keras.layers.LSTM(512, return_sequences=True, recurrent_dropout=0.3))
49
- model.add(tf.keras.layers.LSTM(256))
50
- model.add(tf.keras.layers.BatchNormalization())
51
- model.add(tf.keras.layers.Dropout(0.2))
52
- model.add(tf.keras.layers.Dense(256, activation='relu'))
53
- model.add(tf.keras.layers.BatchNormalization())
54
- model.add(tf.keras.layers.Dropout(0.2))
55
- model.add(tf.keras.layers.Dense(n_vocab, activation='softmax'))
56
- model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  model.load_weights('best2.h5')
 
58
  return model
59
 
60
- def generate_notes(model, network_input, pitchnames, n_vocab, x):
61
- start = np.random.randint(0, len(network_input)-1)
 
 
 
 
62
  int_to_note = dict((number, note) for number, note in enumerate(pitchnames))
 
63
  pattern = network_input[start]
64
  prediction_output = []
65
 
 
66
  for note_index in range(x):
67
- prediction_input = np.reshape(pattern, (1, len(pattern), 1))
68
  prediction_input = prediction_input / float(n_vocab)
 
69
  prediction = model.predict(prediction_input, verbose=0)
70
- index = np.argmax(prediction)
 
71
  result = int_to_note[index]
72
  prediction_output.append(result)
 
73
  pattern.append(index)
74
  pattern = pattern[1:len(pattern)]
75
 
76
  return prediction_output
77
 
 
78
  def create_midi(prediction_output):
 
79
  offset = 0
80
  output_notes = []
 
 
81
  for pattern in prediction_output:
 
82
  if ('.' in pattern) or pattern.isdigit():
83
  notes_in_chord = pattern.split('.')
84
  notes = []
@@ -89,21 +126,32 @@ def create_midi(prediction_output):
89
  new_chord = chord.Chord(notes)
90
  new_chord.offset = offset
91
  output_notes.append(new_chord)
 
 
92
  elif pattern == 'r':
93
  new_note = note.Rest(pattern)
94
  new_note.offset = offset
95
  new_note.storedInstrument = instrument.Piano()
96
  output_notes.append(new_note)
 
 
97
  else:
98
  new_note = note.Note(pattern)
99
  new_note.offset = offset
100
  new_note.storedInstrument = instrument.Piano()
101
  output_notes.append(new_note)
 
 
102
  offset += 0.5
103
 
104
  midi_stream = stream.Stream(output_notes)
 
105
  midi_stream.write('midi', fp='test_output2.mid')
106
 
 
 
 
 
107
 
108
  # Set page config
109
  st.set_page_config(page_title="Music Generation", page_icon=":tada:", layout="wide")
 
11
 
12
 
13
  ####################### Music Generation Functions #######################
14
+ def generate(seq_len,x):
15
  """ Generate a piano midi file """
16
+ #load the notes used to train the model
17
  with open('final_notes', 'rb') as filepath:
18
  notes = pickle.load(filepath)
19
 
20
+ # Get all pitch names
21
  pitchnames = sorted(set(item for item in notes))
22
  n_vocab = len(set(notes))
23
 
24
+ network_input, normalized_input = prepare_sequences(notes, pitchnames, n_vocab , seq_length = seq_len)
25
  model = create_network(normalized_input, n_vocab)
26
  prediction_output = generate_notes(model, network_input, pitchnames, n_vocab, x)
27
  create_midi(prediction_output)
28
 
29
+
30
+ def prepare_sequences(notes, pitchnames, n_vocab , seq_length):
31
+ """ Prepare the sequences used by the Neural Network """
32
+ # map between notes and integers and back
33
  note_to_int = dict((note, number) for number, note in enumerate(pitchnames))
34
+
35
+ sequence_length = seq_length
36
  network_input = []
37
  normalized_input = []
38
  output = []
39
+ for i in range(0, len(notes) - sequence_length, 1):
40
+ sequence_in = notes[i:i + sequence_length]
41
  sequence_out = notes[i + sequence_length]
42
  network_input.append([note_to_int[char] for char in sequence_in])
43
  output.append(note_to_int[sequence_out])
44
 
45
  n_patterns = len(network_input)
46
+
47
+ # reshape the input into a format compatible with LSTM layers
48
+ normalized_input = numpy.reshape(network_input, (n_patterns, sequence_length, 1))
49
+ # normalize input
50
  normalized_input = normalized_input / float(n_vocab)
51
 
52
  return (network_input, normalized_input)
53
 
 
54
  def create_network(network_input, n_vocab):
55
+ """ create the structure of the neural network """
56
+ adam = tf.keras.optimizers.Adam(0.001)
57
+
58
+ model = Sequential()
59
+ model.add(LSTM(
60
+ 512,
61
+ input_shape=(network_input.shape[1], network_input.shape[2]),
62
+ recurrent_dropout=0.3,
63
+ return_sequences=True
64
+ ))
65
+ model.add(LSTM(512, return_sequences=True, recurrent_dropout=0.3,))
66
+ model.add(LSTM(256))
67
+ model.add(BatchNorm())
68
+ model.add(Dropout(0.2))
69
+ model.add(Dense(256))
70
+ model.add(Activation('relu'))
71
+ model.add(BatchNorm())
72
+ model.add(Dropout(0.2))
73
+ model.add(Dense(n_vocab))
74
+ model.add(Activation('softmax'))
75
+ # 'rmsprop'
76
+ model.compile(loss='categorical_crossentropy', optimizer=adam, metrics=['accuracy'])
77
+
78
+ # Load the weights to each node
79
  model.load_weights('best2.h5')
80
+
81
  return model
82
 
83
+
84
+ def generate_notes(model, network_input, pitchnames, n_vocab , x):
85
+ """ Generate notes from the neural network based on a sequence of notes """
86
+ # pick a random sequence from the input as a starting point for the prediction
87
+ start = numpy.random.randint(0, len(network_input)-1)
88
+
89
  int_to_note = dict((number, note) for number, note in enumerate(pitchnames))
90
+
91
  pattern = network_input[start]
92
  prediction_output = []
93
 
94
+ # generate x notes (x entered by user)
95
  for note_index in range(x):
96
+ prediction_input = numpy.reshape(pattern, (1, len(pattern), 1))
97
  prediction_input = prediction_input / float(n_vocab)
98
+
99
  prediction = model.predict(prediction_input, verbose=0)
100
+
101
+ index = numpy.argmax(prediction)
102
  result = int_to_note[index]
103
  prediction_output.append(result)
104
+
105
  pattern.append(index)
106
  pattern = pattern[1:len(pattern)]
107
 
108
  return prediction_output
109
 
110
+
111
  def create_midi(prediction_output):
112
+ """ convert the output from the prediction to notes and create a midi file from the notes """
113
  offset = 0
114
  output_notes = []
115
+
116
+ # create note and chord objects based on the values generated by the model
117
  for pattern in prediction_output:
118
+ # pattern is a chord
119
  if ('.' in pattern) or pattern.isdigit():
120
  notes_in_chord = pattern.split('.')
121
  notes = []
 
126
  new_chord = chord.Chord(notes)
127
  new_chord.offset = offset
128
  output_notes.append(new_chord)
129
+
130
+ # pattern is a rest
131
  elif pattern == 'r':
132
  new_note = note.Rest(pattern)
133
  new_note.offset = offset
134
  new_note.storedInstrument = instrument.Piano()
135
  output_notes.append(new_note)
136
+
137
+ # pattern is a note
138
  else:
139
  new_note = note.Note(pattern)
140
  new_note.offset = offset
141
  new_note.storedInstrument = instrument.Piano()
142
  output_notes.append(new_note)
143
+
144
+ # increase offset each iteration so that notes do not stack
145
  offset += 0.5
146
 
147
  midi_stream = stream.Stream(output_notes)
148
+
149
  midi_stream.write('midi', fp='test_output2.mid')
150
 
151
+
152
+
153
+
154
+
155
 
156
  # Set page config
157
  st.set_page_config(page_title="Music Generation", page_icon=":tada:", layout="wide")