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

学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函数的集成,进一步增强了灵活性。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PPT可以转换成Word吗?归纳了三种转换方式

PPT可以转换成Word吗?在当今快节奏的工作和学习环境中,不同格式文件之间的转换变得日益重要。PPT作为演示文稿制作的首选工具,广泛应用于会议演讲、教育培训等多个场景,而Word则是文档编辑与编排的基石。为了便于进一步编辑、分享…

Tomcat部署和优化

一、Tomcat概述 1.1 Tomcat介绍 Tomcat服务器是一个免费的开放源代码的Web应用服务器,属于轻量级应用服务器,具备Web服务器的所有功能,在中小型系统和并发访问用户不是很多的场合下被普遍使用。实际上Tomcat是Apache服务器的扩展&#xff0c…

多智能体强化学习算法MA-POCA

论文原文:On the Use and Misuse of Absorbing States in Multi-agent Reinforcement Learning 预备知识参考: 强化学习纲要(周博磊课程) 强化学习实践教学 多智能体强化学习入门 MA-POCA是Unity官方2021年11月推出的多智能体…

JAVA基础10-包装类

Boolean b1new Boolean(true);System.out.println("b1" b1);//b1trueBoolean b2new Boolean("true" );System.out.println("b2" b2);//b2true 这里字符串也可转Boolean b3new Boolean("true123");System.out.println("b3"b3…

递归调用,将源路径下所有文件文件夹复制到目标路径中.

其实代码demo很简洁&#xff0c;只是逻辑有点绕&#xff0c;主要是要一层一层调用自己&#xff0c;要清楚当前是第几层调用&#xff0c;及递归调用时进的点和出的点在哪儿&#xff0c;一切就清晰明了了。 /// <summary>/// 删除指定目录下面的所有文件和文件夹/// </s…

《计算机英语》Unit1 计算机概述

期末试卷组成 1、选择20道 2、判断20道 3、词汇翻译&#xff08;单词词组&#xff0c;参照课后习题&#xff09; 4、翻译2道&#xff08;一道原题&#xff0c;参照作业&#xff09; Unit One Computer Overview 单元1 计算机概述 algorithm n. 算法 operate …

爬虫超详细介绍

爬虫&#xff08;Spider&#xff09;是一种自动化程序&#xff0c;用于在互联网上获取信息。 其工作原理主要可以分为以下几个步骤&#xff1a; 发起请求&#xff1a; 爬虫首先需要向目标网站发起HTTP请求&#xff0c;以获取网页的内容。这个请求可以包含一些额外的信息&…

优选算法刷题笔记 2024.6.10-24.6.20

一、双指针算法(快慢指针,对撞指针) 艹&#xff0c;CSDN吞了我是十三题笔记&#xff01;&#xff01;&#xff01; 二、滑动窗口(滑动窗口) 1、找到字符串中所有字母异位词 class Solution {public List<Integer> findAnagrams(String s, String p) {int[] hash1 new in…

小阿轩yx-Tomcat 部署及优化

小阿轩yx-Tomcat 部署及优化 Tomcat 概述 免费的、开放源代码的Web应用服务器Apache软件基金会(Apache Software Foundation)Jakarta项目中的一个核心项目由Apache、Sun和一些公司及个人共同开发而成深受Java爱好者的喜爱,并得到部分软件开发商的认可目前比较流行的Web应用服…

【Web APIs】DOM 文档对象模型 ④ ( querySelector 函数 | querySelectorAll 函数 | NodeList 对象 )

文章目录 一、querySelector 函数1、querySelector 函数简介2、完整代码示例 二、querySelectorAll 函数1、querySelectorAll 函数简介2、完整代码示例 三、NodeList 对象1、NodeList 对象简介2、完整代码示例 本博客相关参考文档 : WebAPIs 参考文档 : https://developer.moz…

ACL2024 | AI的时空穿越记:大型语言模型共时推理的奇幻之旅!

作者&#xff1a;苏肇辰 标题&#xff1a;Living in the Moment: Can Large Language Models Grasp Co-Temporal Reasoning? 录取&#xff1a;ACL2024 Main 论文链接&#xff1a;https://arxiv.org/abs/2406.09072 代码链接&#xff1a;https://github.com/zhaochen0110/Cotem…

T200HSA单路SDI/HDMI+1路3.5音频高清万能采集卡

产品简介&#xff1a; 同三维T200HSA单路高清万能采集卡&#xff0c;可以采集1路SDI/HDMI高清信号1路3.5音频信号&#xff0c;卡上有1个是HDMI接口1个是SDI接口1个3.5音频口&#xff0c;配件有&#xff1a; 1个小档板&#xff0c;PCI-E2.0 X1&#xff0c;分辨率最高可以达到10…

利用星穹云Serverless云平台高效开发小程序的技术实践

一、引言 在快速迭代、持续创新的互联网环境下&#xff0c;开发者们面临着巨大的挑战。传统的小程序开发模式不仅需要掌握后端技术&#xff0c;还需要关注服务器部署、维护等一系列问题&#xff0c;这无疑增加了开发者的学习成本和项目复杂度。而Serverless架构的兴起&#xf…

【Android】Android Studio版本手动升级到指定版本方法

前言 Android Studio本身存在自动升级的功能&#xff0c;但是这个功能使用的时候基本都是要升级到最新版本&#xff0c;但是有时候我们也不想升级到最新版本&#xff0c;是想升级到某一个版本&#xff0c;这个时候&#xff0c;Android Studio的自动升级版本的功能就无法使用了…

简单分享github

一、官网 GitHub: Let’s build from here GitHub 二、注册 通过简单的注册步骤&#xff0c;你就可以拥有一个属于自己的GitHub账号。再简单注册完成之后会需要验证你所输入的邮箱才能正常使用你的GitHub。 三、设置自己的库 在注册完成之后&#xff0c;完成一些简单的设置之…

数据库系统概论——数据库恢复技术

文章目录 数据库恢复技术事务的基本概念什么是事务如何定义事务&#xff1a;事务的特性 数据库恢复概述故障的种类恢复的实现技术恢复策略事务故障的恢复系统故障的恢复介质故障的恢复 数据库恢复技术 事务的基本概念 什么是事务 事务使用户定义的一个数据库操作序列&#x…

排序算法Java_实现

1.引言 查找和排序算法是算法的入门知识&#xff0c;其经典思想可以用于比较常见。 1.1 内部排序和外部排序的区别 内部排序&#xff1a;待排序记录存放在计算机随机存储器中(内存)进行排序的过程。 外部排序&#xff1a;待排序记录的数量很大&#xff0c;以至于内存不能一…

AI与区块链的融合:Web3时代下的新应用探索

本文来源香港Web3媒体Techub News AI与区块链&#xff1a;Web3时代的新机遇 在香港这座金融与科技交汇的繁荣都市&#xff0c;AI与区块链的结合已经成为Web3时代的重要议题&#xff0c;为行业发展带来了新的可能性和机遇。越来越多的开发者正在积极探索这一领域的融合&#xff…

复分析——第5章——整函数(复可积函数)(E.M. Stein R. Shakarchi)

第5章 整函数(复可积函数)(Entire Functions) ...but after the 15th of October I felt myself a free man, with such longing for mathematical work, that the last two months flew by quickly, and that only today I found the letter of the 19th of October that…

鸿蒙 Web组件的生命周期(api10、11、12)

概述 开发者可以使用Web组件加载本地或者在线网页。 Web组件提供了丰富的组件生命周期回调接口&#xff0c;通过这些回调接口&#xff0c;开发者可以感知Web组件的生命周期状态变化&#xff0c;进行相关的业务处理。 Web组件的状态主要包括&#xff1a;Controller绑定到Web组…