def next(self) -> mx.io.DataBatch:
        """
        Returns the next batch from the data iterator.
        """
        if not self.iter_next():
            raise StopIteration

        i, j = self.batch_indices[self.curr_batch_index]
        self.curr_batch_index += 1

        batch_size = self.bucket_batch_sizes[i].batch_size
        source = self.data.source[i][j:j + batch_size]
        target = self.data.target[i][j:j + batch_size]
        if self.preload_features:
            loaded_source = []  # type: List[np.ndarray]
            for k in source:
                loaded_source.append(self.loaded_source[k])
        else:
            loaded_source = self.data_loader(source)
        # zero pad features if not agree with expected shape
        loaded_source = zero_pad_features(loaded_source, self.image_size)
        loaded_source = mx.nd.array(loaded_source)

        label = [self.data.label[i][j:j + batch_size]]

        provide_data = [mx.io.DataDesc(name=self.source_data_name, shape=loaded_source.shape, layout=C.BATCH_MAJOR_IMAGE)]
        if self.with_text:
            provide_data += [mx.io.DataDesc(name=self.target_data_name, shape=target.shape, layout=C.BATCH_MAJOR)]
        provide_label = [mx.io.DataDesc(name=n, shape=x.shape, layout=C.BATCH_MAJOR) for n, x in
                         zip(self.label_names, label)]

        data = [loaded_source]
        if self.with_text:
            data += [target]
        return mx.io.DataBatch(data, label,
                               pad=0, index=None, bucket_key=self.buckets[i],
                               provide_data=provide_data, provide_label=provide_label)
Returns the next batch from the data iterator.