昇思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 downloadurl = "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, 3plt.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:breakplt.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 = startself.end = enddef __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 selfloader = 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 datasetsurl = "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 + 2test_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.mzph.cn/news/856682.shtml

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

相关文章

探寻Scala的魅力:大数据开发语言的入门指南

大数据开发语言Scala入门 一、引言1.1 概念介绍1.2 Scala作为大数据开发语言的优势和应用场景1.2.1 强大的函数式编程支持1.2.2 可与Java无缝集成1.2.3 高性能和可扩展性1.2.4 大数据生态系统的支持 二、Scala基础知识2.1. Scala简介:2.1.1 Scala的起源和背景2.1.2 …

基于微信共享充电桩小程序毕业设计作品成品(3)开发技术文档_充电桩小程序前端技术栈

后台管理系统文件 所在路径:后台源码ht目录是后台 绿色显示的是系统框架,不要动 位置程序名说明源码根目录login.php后台登录页面源码根目录check_u_login.php后台登录处理程序ht 后台根目录index.php后台首页left.php后台左侧菜单u_logout.php退出登…

服务器数据恢复—raid5热备盘同步失败导致阵列崩溃如何恢复数据?

服务器存储数据恢复环境&故障: 某品牌DS5300存储,包含一个存储机头和多个磁盘柜,组建了多组RAID5磁盘阵列。 某个磁盘柜中的一组RAID5阵列由15块数据盘和1块热备硬盘组建。该磁盘柜中的某块硬盘离线,热备盘自动替换并开始同步…

【vue3】for循环多选框勾选必填校验

业务场景&#xff1a; 多选项必选一个&#xff0c;选了的输入框必填 <el-row :gutter"20"><el-col :span"12"><el-form-item label"捆绑终端硬件标识" prop"terminalCodeList"><el-checkbox-groupv-model"…

工程施工安全检测嵌入式解决方案

工程施工安全检测嵌入式解决方案 1 范围1.1 引言1.2 系统概述1.3 文档概述 2 工程施工安全检测系统应用场景2.1 作业操作安全检查2.2 受限空间作业安全检测2.3 应急设备操作行为检测2.4 动火作业安全检测 3 工程施工安全检测系统设计方案概述3.1 AI识别系统3.2 AI关键技术介绍3…

【人机交互 复习】第1章 人机交互概述

人机交互的知识点碎&#xff0c;而且都是文字&#xff0c;过一遍脑子里什么都留不下&#xff0c;但是背时间已经来不及了&#xff0c;最好还是找题要题感吧&#xff0c;加深印象才是做对文科的关键 一、概念 1.人机交互&#xff08;Human-Computer Interaction,HCI)&#xff1…

编写水文专业串口通讯软件的开发经历

编写水文专业串口通讯软件的开发经历 一、关于开发 YAC9900 水位雨量 RTU 通讯软件二、软件开发遇到的问题和困难1、开发架构的适应2、开发语言的学习3、.net core 8 架构中串口构建的难点4、YAC9900 水位雨量 RTU 通讯软件开发中的 UI 冻结 三、发现问题解决问题的具体办法1、…

Linux—— ansible循环

1.如果有大量的变量要定义&#xff0c;如果多个变量本身类型相同或类似 再比如&#xff0c;同一个剧本&#xff0c;给主机同时安装多个软件包 按照已有的用法&#xff0c;每个软件包都对应不同变量&#xff0c;还会涉及到改剧本 2.现在可以用清单&#xff0c;以及playbook里…

中服云数字孪生平台

中服云数字孪生平台是基于中服云物联网平台和数据中台打造的一款实时数据2D/3D集成展示监控平台&#xff0c;旨在解决工业物联网数据的直观展示、实虚互动、仿真模拟、故障诊断、告警、预警、预测、实时观测、实时监控等问题。提供了数据采集、数据底座、监控逻辑、建模工具、展…

50ETF期权可以异地线上期权开户吗?

今天带你了解50ETF期权可以异地线上期权开户吗&#xff1f;有很多的股民、基金投资者都是有上证50ETF期权开户的需求的&#xff0c;大家都知道不能把鸡蛋放在一个篮子里&#xff0c;上证50ETF期权可以作为一种对冲大盘下跌的保险。 期权要看你在哪里开户&#xff0c;如果是在券…

React实现H5手势密码

监测应用进入前后台 在JavaScript中&#xff0c;监听H5页面是否在前台或后台运行&#xff0c;主要依赖于Page Visibility API。这个API在大多数现代浏览器中都是支持的&#xff0c;包括苹果的Safari和谷歌的Chrome&#xff08;也就基本覆盖了Android和iOS平台&#xff09;。下…

IOS逆向分析—终极详细(三)

IOS逆向分析—终极详细&#xff08;三&#xff09; 前言一、逆向分析是什么&#xff1f;二、IDA分析1.下载并安装IDA2.安装插件3.加载二进制4.代码分析5.其它 总结 前言 本文是个人完成对IOS上APP分析的整个过程&#xff0c;当然对于不同的机型还会遇到不同的情况&#xff0c;谨…

力扣144A

文章目录 1. 题目链接2. 题目代码3. 题目总结4. 代码分析 1. 题目链接 Arrival of the General 2. 题目代码 #include<iostream> using namespace std;int heightOfSoldier[110];int main(){int numberOfSoldier;cin >> numberOfSoldier;int maxHeight -1;int mi…

【科研基础】通感一体化讲座

高斯信道下通信感知一体化的性能极限(刘凡) 通信和感知在硬件结构上相似,高效地利用资源,实现相互的增益; 感知是基于不同的任务,比如目标检测(检测概率,虚警概率),估计任务(从收到的信号中去估计有用的参数,均方误差,CRB),识别(知道目标的语义信息,就是目标…

助力草莓智能自动化采摘,基于YOLOv8全系列【n/s/m/l/x】参数模型开发构建果园种植采摘场景下草莓成熟度智能检测识别系统

随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;技术已经渗透到我们生活的方方面面&#xff0c;从智能家居到自动驾驶&#xff0c;再到医疗健康&#xff0c;其影响力无处不在。然而&#xff0c;当我们把目光转向中国的农业领域时&#xff0c;一个令人惊讶的…

Go 内存模型与分配机制

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

前端开发流程与技术选型

目录 一、简介 二、前端职责 三、开发步骤 四、技术选型 五、页面展示 一、简介 做一个网站时&#xff0c;能看到的一切都是前端程序员的工作&#xff0c;负责网页或者app的结构、样式、用户操作网站时的事件逻辑&#xff08;比如点击一个按钮&#xff09;。 二、前端职…

【网络安全的神秘世界】文件上传、JBOSS、Struct漏洞复现

&#x1f31d;博客主页&#xff1a;泥菩萨 &#x1f496;专栏&#xff1a;Linux探索之旅 | 网络安全的神秘世界 | 专接本 | 每天学会一个渗透测试工具 攻防环境搭建及漏洞原理学习 Kali安装docker 安装教程 PHP攻防环境搭建 中间件介绍 介于应用系统和系统软件之间的软件。…

class的流光效果

效果图&#xff1a; 代码示例 <!DOCTYPE html> <html lang"zh"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title&g…

链表OJ

GDUFE 在期末前再刷一次链表题 ~ 203. 移除链表元素 - 力扣&#xff08;LeetCode&#xff09; /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode* removeElements(struct ListNode* head, int …