昇思25天学习打卡营第3天 | 数据集 Dataset

数据是深度学习的基础,高质量的数据输入将在整个深度神经网络中起到积极作用。MindSpore提供基于Pipeline的数据引擎,通过数据集(Dataset)和数据变换(Transforms)实现高效的数据预处理。其中Dataset是Pipeline的起始,用于加载原始数据。mindspore.dataset提供了内置的文本、图像、音频等数据集加载接口,并提供了自定义数据集加载接口。

环境搭建

首先,搭建环境并导入所需包。

python 复制代码
%%capture captured_output
# 实验环境已经预装了mindspore==2.2.14,如需更换mindspore版本,可更改下面mindspore的版本号
!pip uninstall mindspore -y
!pip install -i https://pypi.mirrors.ustc.edu.cn/simple mindspore==2.2.14

import numpy as np
from mindspore.dataset import vision
from mindspore.dataset import MnistDataset, GeneratorDataset
import matplotlib.pyplot as plt

数据集加载

我们使用Mnist数据集作为样例,演示如何使用mindspore.dataset进行加载。需要注意的是,mindspore.dataset提供的接口仅支持解压后的数据文件,因此我们使用download库下载数据集并解压。

python 复制代码
# Download data from open datasets
from download import download

url = "https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/" \
      "notebook/datasets/MNIST_Data.zip"
path = download(url, "./", kind="zip", replace=True)

压缩文件下载并解压后,直接加载数据集,可以看到其数据类型为MnistDataset。

python 复制代码
train_dataset = MnistDataset("MNIST_Data/train", shuffle=False)
print(type(train_dataset))
plaintext 复制代码
<class 'mindspore.dataset.engine.datasets_vision.MnistDataset'>

数据集迭代

数据集加载后,通常以迭代方式获取数据,然后送入神经网络中进行训练。我们可以用create_tuple_iteratorcreate_dict_iterator接口创建数据迭代器,迭代访问数据。

访问的数据类型默认为Tensor;若设置output_numpy=True,访问的数据类型为Numpy。

下面定义一个可视化函数,迭代9张图片进行展示。

python 复制代码
def visualize(dataset):
    figure = plt.figure(figsize=(4, 4))
    cols, rows = 3, 3

    plt.subplots_adjust(wspace=0.5, hspace=0.5)

    for idx, (image, label) in enumerate(dataset.create_tuple_iterator()):
        figure.add_subplot(rows, cols, idx + 1)
        plt.title(int(label))
        plt.axis("off")
        plt.imshow(image.asnumpy().squeeze(), cmap="gray")
        if idx == cols * rows - 1:
            break
    plt.show()
visualize(train_dataset)

数据集常用操作

Pipeline的设计理念使得数据集的常用操作采用dataset = dataset.operation()的异步执行方式,执行操作返回新的Dataset,此时不执行具体操作,而是在Pipeline中加入节点,最终进行迭代时,并行执行整个Pipeline。

shuffle

数据集随机shuffle可以消除数据排列造成的分布不均问题。

mindspore.dataset提供的数据集在加载时可配置shuffle=True,或使用如下操作:

python 复制代码
train_dataset = train_dataset.shuffle(buffer_size=64)
visualize(train_dataset)
map

map操作是数据预处理的关键操作,可以针对数据集指定列(column)添加数据变换(Transforms),将数据变换应用于该列数据的每个元素,并返回包含变换后元素的新数据集。

python 复制代码
image, label = next(train_dataset.create_tuple_iterator())
print(image.shape, image.dtype)
plaintext 复制代码
(28, 28, 1) UInt8

这里对Mnist数据集做数据缩放处理,将图像统一除以255,数据类型由uint8转为了float32。

python 复制代码
train_dataset = train_dataset.map(vision.Rescale(1.0 / 255.0, 0), input_columns='image')
image, label = next(train_dataset.create_tuple_iterator())
print(image.shape, image.dtype)
plaintext 复制代码
(28, 28, 1) Float32
batch

batch的作用是将数据集打包为固定大小的batch,适用于在有限硬件资源下使用梯度下降进行模型优化。一般设置一个固定的batch size,将连续的数据分为若干批(batch)。

python 复制代码
train_dataset = train_dataset.batch(batch_size=32)

batch后的数据增加一维,大小为batch_size。

python 复制代码
image, label = next(train_dataset.create_tuple_iterator())
print(image.shape, image.dtype)
plaintext 复制代码
(32, 28, 28, 1) Float32

自定义数据集

mindspore.dataset模块提供了一些常用的公开数据集和标准格式数据集的加载API。

对于MindSpore暂不支持直接加载的数据集,可以构造自定义数据加载类或自定义数据集生成函数的方式来生成数据集,然后通过GeneratorDataset接口实现自定义方式的数据集加载。

GeneratorDataset支持通过可随机访问数据集对象、可迭代数据集对象和生成器(generator)构造自定义数据集,下面分别对其进行介绍。

可随机访问数据集

可随机访问数据集是实现了__getitem__和__len__方法的数据集,表示可以通过索引/键直接访问对应位置的数据样本。例如,当使用datasetidx访问这样的数据集时,可以读取dataset内容中第idx个样本或标签。

python 复制代码
# Random-accessible object as input source
class RandomAccessDataset:
    def __init__(self):
        self._data = np.ones((5, 2))
        self._label = np.zeros((5, 1))

    def __getitem__(self, index):
        return self._data[index], self._label[index]

    def __len__(self):
        return len(self._data)
python 复制代码
loader = RandomAccessDataset()
dataset = GeneratorDataset(source=loader, column_names=["data", "label"])

for data in dataset:
    print(data)
plaintext 复制代码
[Tensor(shape=[2], dtype=Float64, value= [ 1.00000000e+00,  1.00000000e+00]), Tensor(shape=[1], dtype=Float64, value= [ 0.00000000e+00])]
...
python 复制代码
# list, tuple are also supported.
loader = [np.array(0), np.array(1), np.array(2)]
dataset = GeneratorDataset(source=loader, column_names=["data"])

for data in dataset:
    print(data)
plaintext 复制代码
[Tensor(shape=[], dtype=Int64, value= 0)]
...

可迭代数据集

可迭代的数据集是实现了__iter__和__next__方法的数据集,表示可以通过迭代的方式逐步获取数据样本。这种类型的数据集特别适用于随机访问成本太高或者不可行的情况。

例如,当使用iter(dataset)的形式访问数据集时,可以读取从数据库、远程服务器返回的数据流。

下面构造一个简单迭代器,并将其加载至GeneratorDataset。

python 复制代码
# Iterator as input source
class IterableDataset():
    def __init__(self, start, end):
        '''init the class object to hold the data'''
        self.start = start
        self.end = end
    def __next__(self):
        '''iter one data and return'''
        return next(self.data)
    def __iter__(self):
        '''reset the iter'''
        self.data = iter(range(self.start, self.end))
        return self
python 复制代码
loader = IterableDataset(1, 5)
dataset = GeneratorDataset(source=loader, column_names=["data"])

for d in dataset:
    print(d)
plaintext 复制代码
[Tensor(shape=[], dtype=Int64, value= 1)]
...

学习心得

在本次学习中,我掌握了如何使用MindSpore进行数据集加载和预处理。通过实验,了解了Mnist数据集的加载、shuffle、map和batch等操作的具体实现。此外,还学习了自定义数据集的构建方法。这些技能将有助于提高深度学习模型的性能和效率。

相关推荐
用户83562907805112 小时前
Python 实现 PDF 文件加密与解密方法
后端·python
用户83562907805112 小时前
使用 Python 冻结与拆分 Excel 窗格教程
后端·python
垚森13 小时前
AI时代,让曾经的遗憾变成现实
ai
leonshi14 小时前
使用embedchain快速建立rag知识库,本地大模型
ai·rag·ollama
你好潘先生20 小时前
别再记命令了,用 yeero do 说句人话就能跑脚本,而且不烧 token
服务器·python·命令行
Agent_大师21 小时前
WebSocket 行情重连成功,K线缺口不会自动消失
python
荣码21 小时前
LLM结构化输出:让AI返回JSON而不是废话,我踩了4个坑
java·python
copyer_xyf21 小时前
FastAPI 如何连接 MySQL
后端·python
doiito1 天前
【Agent Harness】Gliding Horse 上下文感知与智能压缩:让 Agent 的“注意力”永不偏移
ai·rust·架构设计·系统设计·ai agent
apocelipes1 天前
常用编程语言和库的正则表达式性能对比
c语言·c++·python·性能优化·golang·开发工具和环境