Runtime preprocessing on the whole dataset.

    Return a tf.data.Datset -- the preprocessed version of the given one.
    By default this function calls preprocess_example.

    Args:
      dataset: the Dataset of already decoded but not yet preprocessed features.
      mode: tf.estimator.ModeKeys
      hparams: HParams, model hyperparameters
      interleave: bool, whether to use parallel_interleave, which is faster
        but will alter the order of samples non-deterministically, or flat_map,
        which is slower but will preserve the sample order.

    Returns:
      a Dataset

def preprocess(self, dataset, mode, hparams, interleave=True):
    """Runtime preprocessing on the whole dataset.

    Return a tf.data.Datset -- the preprocessed version of the given one.
    By default this function calls preprocess_example.

    Args:
      dataset: the Dataset of already decoded but not yet preprocessed features.
      mode: tf.estimator.ModeKeys
      hparams: HParams, model hyperparameters
      interleave: bool, whether to use parallel_interleave, which is faster
        but will alter the order of samples non-deterministically, or flat_map,
        which is slower but will preserve the sample order.

    Returns:
      a Dataset
    """
    def _preprocess(example):
      examples = self.preprocess_example(example, mode, hparams)
      if not isinstance(examples, tf.data.Dataset):
        examples = tf.data.Dataset.from_tensors(examples)
      return examples

    if interleave:
      dataset = dataset.apply(
          tf.data.experimental.parallel_interleave(
              _preprocess, sloppy=True, cycle_length=8))
    else:
      dataset = dataset.flat_map(_preprocess)

    return dataset