docs: public DataSetIterator getTrainIterator() {
          return new DataSetIterator() {
              @Override
              public DataSet next(int i) {
                  throw new UnsupportedOperationException();
              }
  
              @Override
              public List<String> getLabels() {
                  return backedIterator.getLabels();
              }
  
              @Override
              public int inputColumns() {
                  return backedIterator.inputColumns();
              }
  
              @Override
              public void remove() {
                  throw new UnsupportedOperationException();
              }
  
              @Override
              public int totalOutcomes() {
                  return backedIterator.totalOutcomes();
              }
  
              @Override
              public boolean resetSupported() {
                  return backedIterator.resetSupported();
              }
  
              @Override
              public boolean asyncSupported() {
                  return backedIterator.asyncSupported();
              }
  
              @Override
              public void reset() {
                  resetPending.set(true);
              }
  
              @Override
              public int batch() {
                  return backedIterator.batch();
              }
  
              @Override
              public void setPreProcessor(DataSetPreProcessor dataSetPreProcessor) {
                  backedIterator.setPreProcessor(dataSetPreProcessor);
              }
  
              @Override
              public DataSetPreProcessor getPreProcessor() {
                  return backedIterator.getPreProcessor();
              }
  
  
              @Override
              public boolean hasNext() {
                  if (resetPending.get()) {
                      if (resetSupported()) {
                          backedIterator.reset();
                          counter.set(0);
                          resetPending.set(false);
                      } else
                          throw new UnsupportedOperationException("Reset isn't supported by underlying iterator");
                  }
  
                  val state = backedIterator.hasNext();
                  if (state && counter.get() < numTrain)
                      return true;
                  else
                      return false;
              }
  
              @Override
              public DataSet next() {
                  counter.incrementAndGet();
                  val p = backedIterator.next();
  
                  if (counter.get() == 1 && firstTrain == null) {
                      // first epoch ever, we'll save first dataset and will use it to check for equality later
                      firstTrain =  p.copy();
                      firstTrain.detach();
                  } else if (counter.get() == 1) {
                      // epoch > 1, comparing first dataset to previously stored dataset. they should be equal
                      int cnt = 0;
                      if (!p.getFeatures().equalsWithEps(firstTrain.getFeatures(), 1e-5))
                          throw new ND4JIllegalStateException("First examples do not match. Randomization was used?");
                  }
  
                  return p;
              }
          };
      }