Data is the cornerstone of deep learning—its quality, structure, and preprocessing directly influence model convergence and generalization. MindSpore’s mindspore.dataset module provides a high-performance, pipeline-based data engine that decouples data loading from transformation logic, enabling scalable and composable preprocessing workflows.
Loading Built-in Datasets
The MNIST dataset serves as an ideal starting point for demonstrating dataset loading. MindSpore offers native support via MnistDataset, which handles automatic download, extraction, and format parsing:
from mindspore.dataset import MnistDataset
from mindspore.dataset.transforms import Compose
# Load training split from local path or auto-download
train_ds = MnistDataset(dataset_dir="./MNIST_Data", usage="train", shuffle=True)
Iterating Over Data
Once loaded, datasets expose iterator interfaces to stream samples efficiently. Two primary modes are supported:
create_tuple_iterator(): yields tuples (e.g.,(image, label))create_dict_iterator(): yields dictionaries (e.g.,{"image": ..., "label": ...})
By default, outputs are Tensor objects; setting output_numpy=True returns NumPy arrays instead.
Here's a reusable visualization helper that renders the first nine samples:
import matplotlib.pyplot as plt
def show_samples(dataset, num_samples=9):
fig, axes = plt.subplots(3, 3, figsize=(6, 6))
axes = axes.flatten()
for i, (img, lbl) in enumerate(dataset.create_tuple_iterator()):
if i >= num_samples:
break
img_np = img.asnumpy().squeeze()
axes[i].imshow(img_np, cmap="gray")
axes[i].set_title(f"Label: {int(lbl)}")
axes[i].axis("off")
plt.tight_layout()
plt.show()
Core Dataset Operations
MindSpore adopts a lazy-evaluation pipeline model: operations like shuffle, map, and batch return new Dataset objects without immediate execution. Actual computation occurs only during iteration—enabling optimization, parallelism, and memory efficiency.
Shuffling for Uniform Sampling
To mitigate bias from ordered data, use shuffle() with a buffer size appropriate for your dataset scale:
train_ds = train_ds.shuffle(buffer_size=1000)
Applying Transformations with map()
The map() method applies user-defined or built-in transforms to specified columns. For example, normalizing pixel values and converting to float32:
from mindspore.dataset.transforms import TypeCast
from mindspore.dataset.vision import Normalize
transform_list = [
Normalize(mean=[0.1307], std=[0.3081]),
TypeCast(mindspore.float32)
]
train_ds = train_ds.map(
operations=transform_list,
input_columns=["image"]
)
Batching for Efficient Training
Grouping samples into batches balances GPU utilization and gradient variance. Use batch() to control batch size and drop remainder if needed:
train_ds = train_ds.batch(batch_size=32, drop_remainder=True)
Building Custom Datasets
When standard loaders don’t fit your data format, GeneratorDataset enables flexible integration via three patterns:
Indexable (Random-Access) Source
Implement __len__() and __getitem__(idx) to allow direct access by integer index:
class IndexedCustomDataset:
def __init__(self, image_paths, labels):
self.image_paths = image_paths
self.labels = labels
def __len__(self):
return len(self.image_paths)
def __getitem__(self, idx):
# Load and preprocess image + label on demand
img = load_image_as_tensor(self.image_paths[idx])
lbl = self.labels[idx]
return img, lbl
Iterable Source
For streaming or stateful sources (e.g., database cursors), implement __iter__() and __next__():
class StreamingDataset:
def __init__(self, data_stream):
self.stream = data_stream
def __iter__(self):
return self
def __next__(self):
try:
item = next(self.stream)
return preprocess(item)
except StopIteration:
raise StopIteration
Generator Function
A clean alternative is defining a Python generator function that yields samples:
def sample_generator():
for i in range(1000):
yield np.random.randn(28, 28).astype(np.float32), np.int32(i % 10)
custom_ds = GeneratorDataset(
source=sample_generator,
column_names=["image", "label"],
num_parallel_workers=2
)
All three approaches integrate seamlessly into the same pipeline interface—supporting chaining, batching, and distributed sharding out-of-the-box.