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

news2024/11/28 0:58:06

学AI还能赢奖品?每天30分钟,25天打通AI任督二脉 (qq.com)

数据集 Dataset

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

此外MindSpore的领域开发库也提供了大量的预加载数据集,可以使用API一键下载使用。本教程将分别对不同的数据集加载方式、数据集常见操作和自定义数据集方法进行详细阐述。

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库下载数据集并解压。

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

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

MindSpore 提供了许多内置的公开数据集,如MnistDataset。这些数据集接口只支持解压后的数据文件,需要先进行解压处理。

数据集迭代

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

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

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

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)

数据集加载完成后可以使用迭代器访问。MindSpore 提供 create_tuple_iterator 和 create_dict_iterator 方法。通过迭代器,可以获取处理后的数据并将其输入到神经网络中进行训练。

数据集常用操作

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

下面分别介绍几种常见的数据集操作。

shuffle¶

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

op-shuffle

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

train_dataset = train_dataset.shuffle(buffer_size=64)

visualize(train_dataset)

shuffle 操作用于打乱数据集顺序,以消除数据排列造成的分布不均问题。MindSpore在数据加载时可以设定`shuffle=True`,也可以在后续对数据集做shuffle操作。

map

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

Dataset支持的不同变换类型详见数据变换Transforms。

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

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

train_dataset = train_dataset.map(vision.Rescale(1.0 / 255.0, 0), input_columns='image')

对比map前后的数据,可以看到数据类型变化。

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

map可以为数据集的某一列添加数据变换。

batch

将数据集打包为固定大小的batch是在有限硬件资源下使用梯度下降进行模型优化的折中方法,可以保证梯度下降的随机性和优化计算量。

op-batch

一般我们会设置一个固定的batch size,将连续的数据分为若干批(batch)。

train_dataset = train_dataset.batch(batch_size=32)

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

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

batch 用于将数据集分成固定大小的批次进行处理,方便在有限的硬件资源下进行模型训练。Batch后的数据增加了一维,其大小为batch_size。

自定义数据集

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

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

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

可随机访问数据集

可随机访问数据集是实现了__getitem____len__方法的数据集,表示可以通过索引/键直接访问对应位置的数据样本。

例如,当使用dataset[idx]访问这样的数据集时,可以读取dataset内容中第idx个样本或标签。

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

实现 __getitem__ 和 __len__ 方法,可以通过索引直接访问数据集,适用于需要随机访问的数据集。可以通过 GeneratorDataset 进行封装加载。

可迭代数据集

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

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

下面构造一个简单迭代器,并将其加载至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)

实现 __iter__ 和 __next__ 方法,可以通过迭代器逐步获取数据样本,适用于随机访问成本较高的数据集。

生成器

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

下面构造一个生成器,并将其加载至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)

直接使用 Python 的生成器(generator)来返回数据,直到生成器抛出 StopIteration 异常。

数据变换 Transforms

通常情况下,直接加载的原始数据并不能直接送入神经网络进行训练,此时我们需要对其进行数据预处理。MindSpore提供不同种类的数据变换(Transforms),配合数据处理Pipeline来实现数据预处理。所有的Transforms均可通过map方法传入,实现对指定数据列的处理。

mindspore.dataset提供了面向图像、文本、音频等不同数据类型的Transforms,同时也支持使用Lambda函数。下面分别对其进行介绍。

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

Common Transforms

mindspore.dataset.transforms模块支持一系列通用Transforms。这里我们以Compose为例,介绍其使用方式。

Compose

Compose接收一个数据增强操作序列,然后将其组合成单个数据增强操作。我们仍基于Mnist数据集呈现Transforms的应用效果。

# Download data from open datasets

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

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)

更多通用Transforms详见mindspore.dataset.transforms。

transforms.Compose 方法,可以将多个数据变换操作组合成一个整体。例如,对图像数据的缩放、标准化及格式变换可以通过 Compose 组合成一个操作序列。

Vision Transforms

mindspore.dataset.vision模块提供一系列针对图像数据的Transforms。在Mnist数据处理过程中,使用了RescaleNormalizeHWC2CHW变换。下面对其进行详述。

Rescale

Rescale变换用于调整图像像素值的大小,包括两个参数:

  • rescale:缩放因子。
  • shift:平移因子。

图像的每个像素将根据这两个参数进行调整,输出的像素值为𝑜𝑢𝑡𝑝𝑢𝑡𝑖=𝑖𝑛𝑝𝑢𝑡𝑖∗𝑟𝑒𝑠𝑐𝑎𝑙𝑒+𝑠ℎ𝑖𝑓𝑡𝑜𝑢𝑡𝑝𝑢𝑡𝑖=𝑖𝑛𝑝𝑢𝑡𝑖∗𝑟𝑒𝑠𝑐𝑎𝑙𝑒+𝑠ℎ𝑖𝑓𝑡。

这里我们先使用numpy随机生成一个像素值在[0, 255]的图像,将其像素值进行缩放。

random_np = np.random.randint(0, 255, (48, 48), np.uint8)
random_image = Image.fromarray(random_np)
print(random_np)

为了更直观地呈现Transform前后的数据对比,我们使用Transforms的Eager模式进行演示。首先实例化Transform对象,然后调用对象进行数据处理。

rescale = vision.Rescale(1.0 / 255.0, 0)
rescaled_image = rescale(random_image)
print(rescaled_image)

可以看到,使用Rescale后的每个像素值都进行了缩放。

Normalize

Normalize变换用于对输入图像的归一化,包括三个参数:

  • mean:图像每个通道的均值。
  • std:图像每个通道的标准差。
  • is_hwc:bool值,输入图像的格式。True为(height, width, channel),False为(channel, height, width)。

图像的每个通道将根据meanstd进行调整,计算公式为𝑜𝑢𝑡𝑝𝑢𝑡𝑐=𝑖𝑛𝑝𝑢𝑡𝑐−𝑚𝑒𝑎𝑛𝑐𝑠𝑡𝑑𝑐𝑜𝑢𝑡𝑝𝑢𝑡𝑐=𝑖𝑛𝑝𝑢𝑡𝑐−𝑚𝑒𝑎𝑛𝑐𝑠𝑡𝑑𝑐,其中 𝑐𝑐代表通道索引。

normalize = vision.Normalize(mean=(0.1307,), std=(0.3081,))
normalized_image = normalize(rescaled_image)
print(normalized_image)

HWC2CHW¶

HWC2CHW变换用于转换图像格式。在不同的硬件设备中可能会对(height, width, channel)或(channel, height, width)两种不同格式有针对性优化。MindSpore设置HWC为默认图像格式,在有CHW格式需求时,可使用该变换进行处理。

这里我们先将前文中normalized_image处理为HWC格式,然后进行转换。可以看到转换前后的shape发生了变化。

hwc_image = np.expand_dims(normalized_image, -1)
hwc2chw = vision.HWC2CHW()
chw_image = hwc2chw(hwc_image)
print(hwc_image.shape, chw_image.shape)

更多Vision Transforms详见mindspore.dataset.vision。

图像的标准化、像素值缩放、格式变换(如 HWC to CHW)等操作都可以通过 vision 模块提供的方法实现。

Text Transforms¶

mindspore.dataset.text模块提供一系列针对文本数据的Transforms。与图像数据不同,文本数据需要有分词(Tokenize)、构建词表、Token转Index等操作。这里简单介绍其使用方法。

首先我们定义三段文本,作为待处理的数据,并使用GeneratorDataset进行加载。

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

PythonTokenizer

分词(Tokenize)操作是文本数据的基础处理方法,MindSpore提供多种不同的Tokenizer。这里我们选择基础的PythonTokenizer举例,此Tokenizer允许用户自由实现分词策略。随后我们利用map操作将此分词器应用到输入的文本中,对其进行分词。

def my_tokenizer(content):
    return content.split()

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

Lookup

Lookup为词表映射变换,用来将Token转换为Index。在使用Lookup前,需要构造词表,一般可以加载已有的词表,或使用Vocab生成词表。这里我们选择使用Vocab.from_dataset方法从数据集中生成词表。

vocab = text.Vocab.from_dataset(test_dataset)

获得词表后我们可以使用vocab方法查看词表。

print(vocab.vocab())

生成词表后,可以配合map方法进行词表映射变换,将Token转为Index。

test_dataset = test_dataset.map(text.Lookup(vocab))
print(next(test_dataset.create_tuple_iterator()))

更多Text Transforms详见mindspore.dataset.text。

针对文本数据的变换方法,如分词(Tokenizer)、词表映射(Lookup)等。

Lambda Transforms

Lambda函数是一种不需要名字、由一个单独表达式组成的匿名函数,表达式会在调用时被求值。Lambda Transforms可以加载任意定义的Lambda函数,提供足够的灵活度。在这里,我们首先使用一个简单的Lambda函数,对输入数据乘2:

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

可以看到map传入Lambda函数后,迭代获得数据进行了乘2操作。

我们也可以定义较复杂的函数,配合Lambda函数实现复杂数据处理:

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

test_dataset = test_dataset.map(lambda x: func(x))

print(list(test_dataset.create_tuple_iterator()))

使用 Lambda 函数可以实现自定义的变换操作。例如,可以使用 Lambda 函数对输入数据进行数学运算或其他自定义操作。

数据集加载与管理:内置数据集类。支持自定义数据集,通过随机访问、迭代访问、生成器方式。
Pipeline设计:Pipeline设计,将数据预处理操作以异步方式组织,直到迭代时才执行。
数据预处理:通过map操作集成的vision, text, transforms等模块,提供了丰富的数据变换方法。Lambda函数的集成,进一步增强了灵活性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1844986.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt: linux 下用纯c 编写一按钮,当按钮按下在一新窗口显示hello world

用这个程序模板,就可以告别只能在黑框框的终端中编程了。 在 Linux 环境下使用纯 C 语言编写一个按钮,当按钮按下时,在一个新窗口显示 "Hello World"。我们可以使用 GTK 库来实现这个功能。GTK 是一个用于创建图形用户界面的跨平台…

论文辅导 | 基于K-means聚类和ELM神经网络的养殖水质溶解氧预测

辅导文章 模型描述 1)相似度统计量构造。数据归一化后,利用皮尔森相关系数确定环境因子权重,构造相似日的统计量-相似度。 2)K-means 聚类。根据相似度应用 K-means 聚类法对历史日数据样本聚类,找出合适样…

clean code-代码整洁之道 阅读笔记(第十一章)

第十一章 系统 “复杂要人命,它消磨开发者的生命,让产品难以规划、构建和测试。” --RayOzzie,微软公司首席技术官 11.1 如何建造一个城市 每个城市都有一组组人管理不同的部分,有些人负责全局,其他人负责细节。 城市能运转&#…

昨天发的 npm 包,却因为 registry 同步问题无法安装使用

用过 HBuilderX 云打包的都知道,云上面的 Android 环境很有限,其实并不能覆盖 uniapp 生态所有的版本,甚至说只能覆盖最新的一两个版本。 如果你需要用到 HBuilderX 安卓云打包,就必须及时跟进 HBuilderX 的版本更新,…

【人机交互 复习】第7章 可视化设计

一、窗口界面类型 1.多文档界面 (1)优点 a.节省系统资源 b.最小的可视集 c.协同工作区 d.多文档同时可视化 (2)缺点 a.菜单随活动文档窗口状态变化,导致不一致性 b.文档窗口必须在主窗口内部,减弱多文档显…

[C++][数据结构][B-树][上]详细讲解

目录 0.常见的搜索结构1.B树概念2.B-树的插入分析1.流程分析2.插入过程总结 0.常见的搜索结构 种类数据格式时间复杂度顺序查找无要求 O ( N ) O(N) O(N)二分查找有序 O ( l o g 2 N ) O(log_2 N) O(log2​N)二叉搜索树无要求 O ( N ) O(N) O(N)二叉平衡树无要求 O ( l o g 2 …

【计算机网络仿真】b站湖科大教书匠思科Packet Tracer——实验5 交换机的自学习算法

一、实验目的 1.验证交换机的自学习算法; 2.了解交换机对帧的过滤特性; 3.学习交换机如何登记接收到的数据包; 4.学习交换机如何转发数据包(明确转发,盲目转发,丢弃)。 二、实验要求 1.使用Cisc…

自动化办公04 使用pyecharts制图

目录 一、柱状图 二、折线图 三、饼图 四、地图 1. 中国地图 2. 世界地图 3. 省会地图 五、词云 Pyecharts是一个用于数据可视化的Python库。它基于Echarts库,可以通过Python代码生成各种类型的图表,如折线图、柱状图、饼图、散点图等。 Pyecha…

养车小程序系统源码,汽修源码,仿途虎养车系统源码,车辆保养小程序系统

用户端+商家端+师傅端 功能介绍: 支持下单上门服务、到店核销,支持单独选择项目、 也支持选择服务人员、和选择门店多种下单方式, 支持上门服务和到店核销两种服务方式,支持自营和多商家联营两种运营模式&#xff…

静态路由(Static-Route)-Cisco

路由(Route) 世界上数亿的计算机大海 通过路由将世界连接 路由连接LAN、WAN、MAN,也连接世界 路由的工作 路由器将大块信息分解为小数据包 以实现可靠和高效的传输 过程称为“反汇编”和“封装数据有效负载” 路由表是一种逻辑数据结构…

Linux 服务管理(待更)

服务(service)本质就是进程,但是是运行在后台的,通常都会监听某个端口,等待其它程序的请求,比如(mysqld , sshd防火墙等),因此又称为守护进程。 比如通过xshell进行连接的时候,需要输入的端口号就是通过守护…

PyTorch梯度直通反传

有时我们想在层的输出端放置一个阈值函数。这可能出于多种原因。其中之一是我们想将激活总结为二进制值。这种激活的二值化在自编码器中很有用。 然而,阈值化在反向传播过程中会带来问题:阈值函数的导数为零。这种梯度的缺乏导致我们的网络无法学习任何…

CSDN图片居中、左对齐、右对齐、大小设置

图片居中、左对齐、右对齐 ![在这里插入图片描述](https://img-blog.csdnimg.cn/99dc1072e8f1471990b700e1c85d301a.jpeg#pic_center) 大小设置 空格400x150 空格30%x # 长400 宽200 ![在这里插入图片描述](https://img-blog.csdnimg.cn/99dc1072e8f1471990b700e1c85d301a.…

hive on spark 的架构和常见问题 - hive on spark 使用的是 yarn client 模式还是 yarn cluster 模式?

hive on spark 的架构和常见问题 - hive on spark 使用的是 yarn client 模式还是 yarn cluster 模式? 1. 回顾下 spark 的架构图和部署模式 来自官方的经典的 spark 架构图如下: 上述架构图,从进程的角度来讲,有四个角色/组件&…

opencascade AIS_InteractiveContext源码学习3 highlighting management 对象高亮管理

AIS_InteractiveContext 前言 交互上下文(Interactive Context)允许您在一个或多个视图器中管理交互对象的图形行为和选择。类方法使这一操作非常透明。需要记住的是,对于已经被交互上下文识别的交互对象,必须使用上下文方法进行…

TugraphDB:探索图数据库新境界

TugraphDB:释放图数据的全部潜能- 精选真开源,释放新价值。 概览 TugraphDB是支付宝背后的分布式图数据库。该项目是由蚂蚁集团和清华大学共同研发的高性能分布式图数据库,支持事务处理、TB 级大容量、低延迟查找和快速图分析等功能。专为处…

安卓系统安装linux搭建随手服务器termux平替软件介绍

引言 旧手机丢可惜,可以用ZeroTermux(一款代替termux)的超级终端,来模拟Linux(甚至你可以模拟Win,只要性能够用) ps:此软件只是termux的增强版,相当于增加右边菜单&…

第N5周:调用Gensim库训练Word2Vec模型

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 | 接辅导、项目定制🚀 文章来源:K同学的学习圈子 目录 本周任务: 1.安装Gensim库 2.对原始语料分词 3.停用词 4.训练Woed2Vec模型 …

单阶段目标检测--NMS

目录 一、概念: 二、算法过程 三、代码实现 一、概念: 在目标检测的初始结果中,同一个物体,可能对应有多个边界框 (bounding box,bb),这些边界框通常相互重叠。如何从中选择一个最合适 的(也就…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 披萨大作战(100分) - 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 &#x1f…