昇思25天学习打卡营第4天|MindSpore数据集和数据变换

# 打卡

目录

# 打卡

Dateset:Pipeline 的起始

具体步骤

数据处理 Pipeline

代码例子

内置数据集的情况

自定义数据集的情况

可迭代的数据集

生成器

Transforms:数据预处理

代码例子

通用变换Compose

文本变换 Text

Lambda变换


Dateset:Pipeline 的起始

mindspore.dataset — MindSpore master 文档

MindSpore Dataset 是所有数据集的基类,提供了数据处理方法来帮助用户很简便地定义数据预处理Pipeline,并以最高效(多进程/多线程)的方式处理数据集中的样本。 可用于数据集加载、迭代、操作。

具体步骤

  1. 加载数据集:1)用 *Dataset 类来加载已支持的数据集;2)通过 UDF Loader + GeneratorDataset 实现Python层自定义数据集的加载。// mindspore.dataset提供的接口仅支持解压后的数据文件,可用download库下载数据集并解压。
  2. 数据集操作:通过数据集对象方法 .shuffle / .filter / .skip / .split / .take / … 来实现数据集的进一步混洗、过滤、跳过、最多获取条数等操作。
  3. 数据集样本增强操作:将数据增强操作 (vision类 , nlp类 , audio类 ) 添加到map操作中执行,数据预处理过程中可以定义多个map操作,用于执行不同增强操作,数据增强操作也可以是 用户自定义增强的 PyFunc ;
  4. 批:用 .batch 操作将多个样本组织成batch,也可以通过batch的参数 per_batch_map 来自定义batch逻辑;
  5. 迭代器:通过数据集对象方法 create_tuple_iteratorcreate_dict_iterator 接口来创建迭代器, 可以将预处理完成的数据循环输出。

数据处理 Pipeline

  • 内置开源数据集分为视觉、文本、音频类。
  • 内置数据格式分为标准格式、用户自定义等。
  • 内置其他数据集处理接口,如采样器模块、全局配置模块等。

例如,视觉类(Cifar10DatasetCifar100DatasetFashionMnistDatasetFood101DatasetKITTIDatasetMnistDatasetQMnistDatasetVOCDatasetWIDERFaceDataset 等),文本类(AGNewsDatasetCLUEDatasetDBpediaDatasetIMDBDatasetSQuADDatasetTextFileDatasetWikiTextDatasetYahooAnswersDatasetYelpReviewDataset 等),音频类(CMUArcticDatasetGTZANDatasetLibriTTSDatasetLJSpeechDatasetSpeechCommandsDatasetTedliumDatasetYesNoDataset 等)。

例如,标准格式(CSVDatasetMindDatasetOBSMindDatasetTFRecordDataset ),用户自定义格式(GeneratorDatasetNumpySlicesDatasetPaddedDatasetRandomDataset

  • map操作可以针对数据集指定列(column)添加数据变换(Transforms),将数据变换应用于该列数据的每个元素,并返回包含变换后元素的新数据集。
  • batch操作可以将数据集打包为固定大小的batch,是在有限硬件资源下使用梯度下降进行模型优化的折中方法,可以保证梯度下降的随机性和优化计算量。

代码例子

内置数据集的情况

import numpy as np
from mindspore.dataset import vision
from mindspore.dataset import MnistDataset, GeneratorDataset
import matplotlib.pyplot as plt
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)

train_dataset = MnistDataset("MNIST_Data/train", shuffle=False)
print(type(train_dataset))

def visualize(dataset):
    figure = plt.figure(figsize=(4, 4))
    cols, rows = 4, 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()


### shuffle
train_dataset = train_dataset.shuffle(buffer_size=64)
visualize(train_dataset)

### 迭代访问
image, label = next(train_dataset.create_tuple_iterator())
print(image.shape, image.dtype, label)
plt.imshow(image.asnumpy().squeeze(), cmap="gray")

### 数据缩放处理map
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, label)
plt.imshow(image.asnumpy().squeeze(), cmap="gray")

### batch打包数据
train_dataset = train_dataset.batch(batch_size=32)
image, label = next(train_dataset.create_tuple_iterator())
print(image.shape, image.dtype)   ## 32个打包图片

自定义数据集的情况

下面自定义的可随机访问数据集是实现了 `__getitem__` 和 `__len__` 方法的数据集,表示可以通过索引/键直接访问对应位置的数据样本。

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

# 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)


loader = RandomAccessDataset()
dataset = GeneratorDataset(source=loader, column_names=["data", "label"])

for data in dataset:
    print(data)

# 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)

可迭代的数据集

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

from mindspore.dataset import vision
from mindspore.dataset import GeneratorDataset

# 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


loader = IterableDataset(1, 5)
dataset = GeneratorDataset(source=loader, column_names=["data"])

for d in dataset:
    print(d)

生成器

生成器也属于可迭代的数据集类型,其直接依赖Python的生成器类型generator返回数据,直至生成器抛出StopIteration异常。

from mindspore.dataset import vision
from mindspore.dataset import GeneratorDataset

# Generator
def my_generator(start, end):
    for i in range(start, end):
        yield i


# since a generator instance can be only iterated once, we need to wrap it by lambda to generate multiple instances
dataset = GeneratorDataset(source=lambda: my_generator(3, 6), column_names=["data"])

for d in dataset:
    print(d)

Transforms:数据预处理

mindspore.dataset.transforms — MindSpore master 文档

在数据送入模型网络训练前进行的数据预处理操作。

MindSpore Dataset支持的不同变换类型的数据变换,配合数据处理Pipeline来实现数据预处理。所有的Transforms均可通过 map 方法传入,实现对指定数据列的处理。

代码例子

通用变换Compose

Compose接收一个数据增强操作序列,然后将其组合成单个数据增强操作。

下面代码的Compose包括了三个vision视觉变换过程, vision.Rescale、 vision.Normalize、vision.HWC2CHW。

  • Rescale 变换作用分别:用于调整图像像素值的大小,图像的每个像素将根据这rescale缩放因子、shift平移因子两个参数进行调整。输出的像素值为 output_{i} = input_{i} * rescale + shift
  • Normalize变换用于对输入图像的归一化。图像的每个通道将根据meanstd进行调整,output_c = (input_c - mean_c) / std_c,其中 c 代表通道索引。
  • HWC2CHW变换用于转换图像格式。在不同的硬件设备中可能会对(height, width, channel)或(channel, height, width)两种不同格式有针对性优化。MindSpore设置 HWC 为默认图像格式,在有CHW格式需求时,可使用该变换进行处理。
import numpy as np
from PIL import Image
from download import download
from mindspore.dataset import transforms, vision, text
from mindspore.dataset import GeneratorDataset, MnistDataset
import matplotlib.pyplot as plt


train_dataset = MnistDataset('MNIST_Data/train')

image, label = next(train_dataset.create_tuple_iterator())
print(image.shape)


composed = transforms.Compose(
    [
        vision.Rescale(1.0 / 255.0, 0),
        vision.Normalize(mean=(0.1307,), std=(0.3081,)),
        vision.HWC2CHW()
    ]
)

train_dataset = train_dataset.map(composed, 'image')
image, label = next(train_dataset.create_tuple_iterator())
print(image.shape)

plt.imshow(image.asnumpy().squeeze(), cmap="gray")

文本变换 Text

mindspore.dataset.transforms — MindSpore master 文档

针对文本数据的Transforms 与图像数据不同,文本数据需要有分词(Tokenize)、构建词表、Token转Index等操作。

  • MindSpore提供多种不同的Tokenizer,以PythonTokenizer举例,它允许用户自由实现分词策略。
  • Lookup为词表映射变换,用来将Token转换为Index。需要先构造词表,这里Vocab.from_dataset 方法从数据集中生成词表。
from mindspore.dataset import transforms, vision, text
from mindspore.dataset import GeneratorDataset, 

def my_tokenizer(content):
    ## 空格分词
    return content.split()


texts = ['Welcome to Beijing']
test_dataset = GeneratorDataset(texts, 'text')

test_dataset = test_dataset.map(text.PythonTokenizer(my_tokenizer))
print(next(test_dataset.create_tuple_iterator()))


### 词表构造
vocab = text.Vocab.from_dataset(test_dataset)
print(vocab.vocab())   ## 用vocab方法查看词表。

### 词表映射变换
test_dataset = test_dataset.map(text.Lookup(vocab))
print(next(test_dataset.create_tuple_iterator()))

Lambda变换

Lambda函数是一种不需要名字、由一个单独表达式组成的匿名函数,表达式会在调用时被求值。

from mindspore.dataset import transforms, vision, text
from mindspore.dataset import GeneratorDataset


test_dataset = GeneratorDataset([1, 2, 3], 'data', shuffle=False)
test_dataset = test_dataset.map(lambda x: x * 2)
print(list(test_dataset.create_tuple_iterator()))

def func(x):
    return x * x + 2

test_dataset = test_dataset.map(lambda x: func(x))
print(list(test_dataset.create_tuple_iterator()))

  • 10
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值