nextDataEpoch(numExamples) {
    this.generateExampleBeginIndices_();

    if (numExamples == null) {
      numExamples = this.exampleBeginIndices_.length;
    }

    const xsBuffer = new tf.TensorBuffer([
        numExamples, this.sampleLen_, this.charSetSize_]);
    const ysBuffer  = new tf.TensorBuffer([numExamples, this.charSetSize_]);
    for (let i = 0; i < numExamples; ++i) {
      const beginIndex = this.exampleBeginIndices_[
          this.examplePosition_ % this.exampleBeginIndices_.length];
      for (let j = 0; j < this.sampleLen_; ++j) {
        xsBuffer.set(1, i, j, this.indices_[beginIndex + j]);
      }
      ysBuffer.set(1, i, this.indices_[beginIndex + this.sampleLen_]);
      this.examplePosition_++;
    }
    return [xsBuffer.toTensor(), ysBuffer.toTensor()];
  }
Generate the next epoch of data for training models.

@param {number} numExamples Number examples to generate.
@returns {[tf.Tensor, tf.Tensor]} `xs` and `ys` Tensors.
  `xs` has the shape of `[numExamples, this.sampleLen, this.charSetSize]`.
  `ys` has the shape of `[numExamples, this.charSetSize]`.