Ascend
GPU
CPU
入门
数据是深度学习的基础,高质量数据输入会在整个深度神经网络中起到积极作用。
在网络训练和推理流程中,原始数据一般存储在磁盘或数据库中,需要首先通过数据加载步骤将其读取到内存空间,转换成框架通用的张量(Tensor)格式,然后通过数据处理和增强步骤,将其映射到更加易于学习的特征空间,同时增加样本的数量和泛化性,最后输入到网络进行计算。
整体流程如下图所示:
本章节介绍mindspore.dataset
(以下简称Dataset)中的数据加载、数据处理和增强等操作涉及到的一些基础概念。
数据集为一组样本的集合,数据集的一行即为一个样本包含一个或多个特征,此外还可能包含一个标签。数据集都需要符合一定规范要求,便于评估模型的效果。
Dataset支持多种格式数据集,包括MindSpore自研数据格式MindRecord,常用的公开图像数据集和文本数据集,用户自定义的数据集等。 详细的Mindspore支持的数据集请参考: MindSpore支持数据集。
Dataset也支持将常用的数据集和用户自定义的数据集转为MindSpore数据格式(MindRecord),详情可参考: 转换数据集为MindRecord。
数据集加载使得模型训练时能源源不断地获取数据进行训练。
Dataset对多种常用的数据集提供对应的类来实现数据集的加载,同时对于不同存储格式的数据文件,Dataset也有对应的类来进行数据加载。MindSpore数据集加载请参考:MindSpore数据集加载。
Dataset提供了多种用途的采样器(Sampler),采样器负责生成读取的index序列,Dataset负责根据index读取相应数据,帮助用户对数据集进行不同形式的采样,以满足训练需求,解决诸如数据集过大或样本类别分布不均等问题,注意,采样器负责对样本做filter和reorder操作,不会执行Batch操作。
Mindspore的数据采样介绍请参考:MindSpore数据采样。
Dataset将数据加载到内存后,数据按Tensor形式进行组织。同时Tensor也是数据增强操作中的基本数据结构。
训练一般是多个epoch,shuffle操作打乱数据的顺序,保证训练时每个epoch的数据顺序不同,防止训练过拟合。
Dataset提供多种方式来实现全局shuffle操作。
数据集加载类的shuffle
参数
import numpy as np
import mindspore.dataset as ds
data = [1, 2, 3, 4]
dataset = ds.NumpySlicesDataset(data=data, column_names=["column_1"], shuffle=True)
详情请参考:NumpySlicesDataset。
shuffle算子
import numpy as np
import mindspore.dataset as ds
data = [1, 2, 3, 4]
dataset = ds.NumpySlicesDataset(data=data, column_names=["column_1"])
# buffer_size equal to the number of rows in the entire dataset will result in a global shuffle
dataset = dataset.shuffle(4)
详情请参考:shuffle API。
随机采样
import numpy as np
import mindspore.dataset as ds
data = [1, 2, 3, 4]
sampler = ds.RandomSampler()
dataset = ds.NumpySlicesDataset(data=data, column_names=["column_1"],sampler=sampler)
详情请参考:RandomSampler。
Map操作对各类数据做数据增强,负责启动和执行Dataset提供或用户自定义的数据增强算子,对数据进行映射变换,其中数据增强是一种创造有着不同方向的“新”数据的方法,一是从有限数据中生成“更多数据”,二是防止过拟合。
Dataset的c_transforms
和py_transforms
模块分别提供了基于C++
和Python
的数据增强算子实现,同时用户可以自定义函数来进行数据增强。
图像类数据增强操作请参考:图像类数据增强。
文本类数据增强操作请参考:文本类数据增强。
Map操作请参考:Map操作。
每次只使用一个样本训练模型,具有较好的随机性,但并行化差,导致训练效率过低。引入mini-batch可以较好均衡训练速度和训练效果。
Batch 操作负责将多个shape
相同的Tensor
“打包”到一起,以实现以mini-batch的方式来进行训练,Batch操作还提供drop_remainder参数,表示把最后一个不足batch_size的batch删除,默认会保留。假如数据集大小为17373,使用8张卡进行训练并且Batch size为16,每张卡分配2172条样本,当drop_remainder为True时,每张卡上可打包135个mini-batch。
在“打包”动作之前,Batch支持将shape
不一致的Tensor
根据用户需求、或者自动将Tensor
的shape
填充一致,以及通过Per_batch_map
在“打包”之前
执行用户自定义的函数。
padding操作
import numpy as np
import mindspore.dataset as ds
# col1d: [0],[1]
# col2d: [[100],[200]], [[101],[201]]
def gen_2cols(num):
for i in range(num):
yield (np.array([i]), np.array([[i + 100], [i + 200]]))
dataset = ds.GeneratorDataset((lambda: gen_2cols(2)), ["col1d", "col2d"])
dataset = dataset.batch(batch_size=2, drop_remainder=False, pad_info={"col2d": ([2, 2], -2) , "col1d": ([2], -1)})
# col1d: [0, -1], [1, -1]
# col2d: [[100, -2], [200, -2]], [[101, -2], [201, -2]]
per_batch_map操作
import numpy as np
import mindspore.dataset as ds
# first column: 0, 3, 6, 9 ...
# second column:1, 4, 7, 10 ...
# third column: 2, 5, 8, 11 ...
def gen_3_cols(num):
for i in range(num):
yield (np.array([i * 3]), np.array([i * 3 + 1]), np.array([i * 3 + 2]))
# first epoch batch_size per batch: 1, 2 ,3 ...
# second epoch batch_size per batch: 2, 4, 6 ...
# third epoch batch_size per batch: 3, 6 ,9 ...
def batch_func(batchInfo):
return (batchInfo.get_batch_num() + 1) * (batchInfo.get_epoch_num() + 1)
# multiply first col by batch_num, multiply second col by -batch_num
def map_func(col1, col2, batchInfo):
return ([np.copy((1 + batchInfo.get_batch_num()) * arr) for arr in col1],
[np.copy(-(1 + batchInfo.get_batch_num()) * arr) for arr in col2])
# col1: [[0]], [[ 6], [12]], [[27]]
# col2: [[-1]],[[ -8], [-14]], [[-30]]
# col3: [[2]], [[5], [8]], [[11]]
dataset = ds.GeneratorDataset((lambda: gen_3_cols(4)), ["col1", "col2", "col3"]).batch (batch_size=batch_func, input_columns=["col1", "col2"], per_batch_map=map_func)
Batch操作请参考:Batch操作。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。