'Defines a generator that can be used to iterate over this dataset.
Yields:
tuple: The next minibatch. A minibatch includes both features and
labels.'

def __iter__(self):

    if (not self.allocated):
        self.allocate()
    full_shape = list(self.lshape)
    full_shape.append((-1))
    mini_batch_in = self.mini_batch_in
    if (self.outbuf is not None):
        mini_batch_out = self.mini_batch_out
    for i1 in range(self.start, self.ndata, self.be.bsz):
        i2 = min((i1 + self.be.bsz), self.ndata)
        bsz = (i2 - i1)
        if (i2 == self.ndata):
            self.start = (self.be.bsz - bsz)
        xdev = self.inp
        mini_batch_in[:, :bsz] = xdev[i1:i2, :].T.astype(np.float32)
        if (self.be.bsz > bsz):
            mini_batch_in[:, bsz:] = xdev[:(self.be.bsz - bsz), :].T.astype(np.float32)
        self.gen_input(mini_batch_in)
        if (self.outbuf is not None):
            mini_batch_out[:, :bsz] = self.out[i1:i2].T
            if (self.be.bsz > bsz):
                mini_batch_out[:, bsz:] = self.out[:(self.be.bsz - bsz)].T
            self.gen_output(mini_batch_out)
        inputs = self.inpbuf
        targets = self.outbuf
        (yield (inputs, targets))
