/**
  * Returns pitch class evaluation percentages for training data with an option
  * to include validation data.
  */
 async evaluate(includeValidation = false): Promise<AccuracyPerClass> {
   const result: AccuracyPerClass = {};
   for (let i = 0; i < this.trainingClassTensors.length; i++) {
     result[pitchFromType(i)] = {
       training: this.calculateClassAccuracy(
           this.trainingClassTensors[i], i, TRAINING_DATA_PITCH_CLASS_SIZE)
     };
     if (includeValidation) {
       result[pitchFromType(i)].validation = this.calculateClassAccuracy(
           this.validationClassTensors[i], i,
           VALIDATION_DATA_PITCH_CLASS_SIZE);
     }
   }
   return result;
 }
  /**
   * Returns sorted pitch type classification predictions for a given Pitch.
   */
  predict(pitch: Pitch): PitchClass[] {
    const pitchTensor = createPitchTensor(pitch, this.fields);
    const predict = this.model.predict(pitchTensor) as tf.Tensor;
    const values = predict.dataSync();

    let list = [] as PitchClass[];
    for (let i = 0; i < values.length; i++) {
      list.push({value: values[i], type: pitchFromType(i), pitch_code: i});
    }
    list = list.sort((a, b) => b.value - a.value);
    return list;
  }