'Used to evaluate the rewards the model receives without exploring.
Generates num_trials compositions and computes the note_rnn and music
theory rewards. Uses no exploration so rewards directly relate to the
model\'s policy. Stores result in internal variables.
Args:
num_trials: The number of compositions to use for evaluation.
sample_next_obs: If True, the next note the model plays will be
sampled from its output distribution. If False, the model will
deterministically choose the note with maximum value.'

def evaluate_model(self, num_trials=100, sample_next_obs=True):

    note_rnn_rewards = ([0] * num_trials)
    music_theory_rewards = ([0] * num_trials)
    total_rewards = ([0] * num_trials)
    for t in range(num_trials):
        last_observation = self.prime_internal_models()
        self.reset_composition()
        for _ in range(self.num_notes_in_melody):
            (_, new_observation, reward_scores) = self.action(last_observation, 0, enable_random=False, sample_next_obs=sample_next_obs)
            note_rnn_reward = self.reward_from_reward_rnn_scores(new_observation, reward_scores)
            music_theory_reward = self.reward_music_theory(new_observation)
            adjusted_mt_reward = (self.reward_scaler * music_theory_reward)
            total_reward = (note_rnn_reward + adjusted_mt_reward)
            note_rnn_rewards[t] = note_rnn_reward
            music_theory_rewards[t] = (music_theory_reward * self.reward_scaler)
            total_rewards[t] = total_reward
            self.composition.append(np.argmax(new_observation))
            self.beat += 1
            last_observation = new_observation
    self.eval_avg_reward.append(np.mean(total_rewards))
    self.eval_avg_note_rnn_reward.append(np.mean(note_rnn_rewards))
    self.eval_avg_music_theory_reward.append(np.mean(music_theory_rewards))
