'Generates a music sequence with the current model, and saves it to MIDI.
The resulting MIDI file is saved to the model\'s output_dir directory. The
sequence is generated by sampling from the output probabilities at each
timestep, and feeding the resulting note back in as input to the model.
Args:
title: The name that will be used to save the output MIDI file.
visualize_probs: If True, the function will plot the softmax
probabilities of the model for each note that occur throughout the
sequence. Useful for debugging.
prob_image_name: The name of a file in which to save the softmax
probability image. If None, the image will simply be displayed.
length: The length of the sequence to be generated. Defaults to the
num_notes_in_melody parameter of the model.
most_probable: If True, instead of sampling each note in the sequence,
the model will always choose the argmax, most probable note.'

def generate_music_sequence(self, title='rltuner_sample', visualize_probs=False, prob_image_name=None, length=None, most_probable=False):

    if (length is None):
        length = self.num_notes_in_melody
    self.reset_composition()
    next_obs = self.prime_internal_models()
    tf.logging.info('Priming    with    note    %s', np.argmax(next_obs))
    lengths = np.full(self.q_network.batch_size, 1, dtype=int)
    if visualize_probs:
        prob_image = np.zeros((self.input_size, length))
    generated_seq = ([0] * length)
    for i in range(length):
        input_batch = np.reshape(next_obs, (self.q_network.batch_size, 1, self.num_actions))
        if (self.algorithm == 'g'):
            (softmax, self.q_network.state_value, self.reward_rnn.state_value) = self.session.run([self.action_softmax, self.q_network.state_tensor, self.reward_rnn.state_tensor], {self.q_network.melody_sequence: input_batch, self.q_network.initial_state: self.q_network.state_value, self.q_network.lengths: lengths, self.reward_rnn.melody_sequence: input_batch, self.reward_rnn.initial_state: self.reward_rnn.state_value, self.reward_rnn.lengths: lengths})
        else:
            (softmax, self.q_network.state_value) = self.session.run([self.action_softmax, self.q_network.state_tensor], {self.q_network.melody_sequence: input_batch, self.q_network.initial_state: self.q_network.state_value, self.q_network.lengths: lengths})
        softmax = np.reshape(softmax, self.num_actions)
        if visualize_probs:
            prob_image[:, i] = softmax
        if most_probable:
            sample = np.argmax(softmax)
        else:
            sample = rl_tuner_ops.sample_softmax(softmax)
        generated_seq[i] = sample
        next_obs = np.array(rl_tuner_ops.make_onehot([sample], self.num_actions)).flatten()
    tf.logging.info('Generated    sequence:    %s', generated_seq)
    print('Generated    sequence:', generated_seq)
    melody = mlib.Melody(rl_tuner_ops.decoder(generated_seq, self.q_network.transpose_amount))
    sequence = melody.to_sequence(qpm=rl_tuner_ops.DEFAULT_QPM)
    filename = rl_tuner_ops.get_next_file_name(self.output_dir, title, 'mid')
    midi_io.sequence_proto_to_midi_file(sequence, filename)
    tf.logging.info('Wrote    a    melody    to    %s', self.output_dir)
    if visualize_probs:
        tf.logging.info('Visualizing    note    selection    probabilities:')
        plt.figure()
        plt.imshow(prob_image, interpolation='none', cmap='Reds')
        plt.ylabel('Note    probability')
        plt.xlabel('Time    (beat)')
        plt.gca().invert_yaxis()
        if (prob_image_name is not None):
            plt.savefig(((self.output_dir + '/') + prob_image_name))
        else:
            plt.show()
