'Returns a new minibatch of data with each call.
Yields:
tuple: The next minibatch which includes both features and labels.'

def __iter__(self):

    for i1 in range(self.start, self.ndata, self.be.bsz):
        bsz = min(self.be.bsz, (self.ndata - i1))
        (islice1, oslice1) = (slice(0, bsz), slice(i1, (i1 + bsz)))
        (islice2, oslice2) = (None, None)
        if (self.be.bsz > bsz):
            (islice2, oslice2) = (slice(bsz, None), slice(0, (self.be.bsz - bsz)))
            self.start = (self.be.bsz - bsz)
        for (buf, dev, unpack_func) in zip(self.hbuf, self.dbuf, self.unpack_func):
            unpack_func(dev[oslice1], buf[:, islice1])
            if oslice2:
                unpack_func(dev[oslice2], buf[:, islice2])
        inputs = (self.Xbuf[0] if (len(self.Xbuf) == 1) else self.Xbuf)
        targets = (self.ybuf if self.ybuf else inputs)
        (yield (inputs, targets))
