'Generator that can be used to iterate over this dataset.
Yields:
tuple : the next minibatch of data.'

def __iter__(self):

    self.batch_index = 0
    while (self.batch_index < self.nbatches):
        X_batch = self.X[:, self.batch_index, :].T.astype(np.float32, order='C')
        if (self.reverse_target is False):
            y_batch = self.y[:, self.batch_index, :].T.astype(np.float32, order='C')
        else:
            y_batch = self.y[:, self.batch_index, ::(-1)].T.astype(np.float32, order='C')
        self.dev_lbl.set(y_batch)
        self.dev_y[:] = self.be.onehot(self.dev_lblflat, axis=0)
        if self.onehot_input:
            self.dev_lbl.set(X_batch)
            self.dev_X[:] = self.be.onehot(self.dev_lblflat, axis=0)
            if self.get_prev_target:
                self.dev_Z[:, self.be.bsz:] = self.dev_y[:, :(- self.be.bsz)]
                self.dev_Z[:, 0:self.be.bsz] = 0
        else:
            self.dev_X.set(X_batch)
            if self.get_prev_target:
                self.dev_lbl.set(y_batch)
                self.dev_Z[1:, :] = self.dev_lbl[:(-1), :]
                self.dev_Z[0, :] = 0
        self.batch_index += 1
        if self.get_prev_target:
            (yield ((self.dev_X, self.dev_Z), self.dev_y))
        else:
            (yield (self.dev_X, self.dev_y))
