{ "cells": [ { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "[![在线运行](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/r2.1/resource/_static/logo_modelarts.svg)](https://authoring-modelarts-cnnorth4.huaweicloud.com/console/lab?share-url-b64=aHR0cHM6Ly9vYnMuZHVhbHN0YWNrLmNuLW5vcnRoLTQubXlodWF3ZWljbG91ZC5jb20vbWluZHNwb3JlLXdlYnNpdGUvbm90ZWJvb2svcjIuMS90dXRvcmlhbHMvemhfY24vYmVnaW5uZXIvbWluZHNwb3JlX2RhdGFzZXQuaXB5bmI==&imageid=96a10081-8eac-4009-9b45-25a9d4f599b6) [![下载Notebook](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/r2.1/resource/_static/logo_notebook.svg)](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/r2.1/tutorials/zh_cn/beginner/mindspore_dataset.ipynb) [![下载样例代码](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/r2.1/resource/_static/logo_download_code.svg)](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/r2.1/tutorials/zh_cn/beginner/mindspore_dataset.py) [![查看源文件](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/r2.1/resource/_static/logo_source.svg)](https://gitee.com/mindspore/docs/blob/r2.1/tutorials/source_zh_cn/beginner/dataset.ipynb)\n", "\n", "[基本介绍](https://www.mindspore.cn/tutorials/zh-CN/r2.1/beginner/introduction.html) || [快速入门](https://www.mindspore.cn/tutorials/zh-CN/r2.1/beginner/quick_start.html) || [张量 Tensor](https://www.mindspore.cn/tutorials/zh-CN/r2.1/beginner/tensor.html) || **数据集 Dataset** || [数据变换 Transforms](https://www.mindspore.cn/tutorials/zh-CN/r2.1/beginner/transforms.html) || [网络构建](https://www.mindspore.cn/tutorials/zh-CN/r2.1/beginner/model.html) || [函数式自动微分](https://www.mindspore.cn/tutorials/zh-CN/r2.1/beginner/autograd.html) || [模型训练](https://www.mindspore.cn/tutorials/zh-CN/r2.1/beginner/train.html) || [保存与加载](https://www.mindspore.cn/tutorials/zh-CN/r2.1/beginner/save_load.html)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "# 数据集 Dataset\n", "\n", "数据是深度学习的基础,高质量的数据输入将在整个深度神经网络中起到积极作用。MindSpore提供基于Pipeline的[数据引擎](https://www.mindspore.cn/docs/zh-CN/r2.1/design/data_engine.html),通过[数据集(Dataset)](https://www.mindspore.cn/tutorials/zh-CN/r2.1/beginner/dataset.html)和[数据变换(Transforms)](https://www.mindspore.cn/tutorials/zh-CN/r2.1/beginner/transforms.html)实现高效的数据预处理。其中Dataset是Pipeline的起始,用于加载原始数据。`mindspore.dataset`提供了内置的文本、图像、音频等数据集加载接口,并提供了自定义数据集加载接口。\n", "\n", "此外MindSpore的领域开发库也提供了大量的预加载数据集,可以使用API一键下载使用。本教程将分别对不同的数据集加载方式、数据集常见操作和自定义数据集方法进行详细阐述。" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "from mindspore.dataset import vision\n", "from mindspore.dataset import MnistDataset, GeneratorDataset\n", "import matplotlib.pyplot as plt" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## 数据集加载\n", "\n", "我们使用**Mnist**数据集作为样例,介绍使用`mindspore.dataset`进行加载的方法。" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "`mindspore.dataset`提供的接口**仅支持解压后的数据文件**,因此我们使用`download`库下载数据集并解压。" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Downloading data from https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/datasets/MNIST_Data.zip (10.3 MB)\n", "\n", "file_sizes: 100%|██████████████████████████| 10.8M/10.8M [00:02<00:00, 4.15MB/s]\n", "Extracting zip file...\n", "Successfully downloaded / unzipped to ./\n" ] } ], "source": [ "# Download data from open datasets\n", "from download import download\n", "\n", "url = \"https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/\" \\\n", " \"notebook/datasets/MNIST_Data.zip\"\n", "path = download(url, \"./\", kind=\"zip\", replace=True)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "压缩文件删除后,直接加载,可以看到其数据类型为MnistDataset。" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "train_dataset = MnistDataset(\"MNIST_Data/train\", shuffle=False)\n", "print(type(train_dataset))" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## 数据集迭代\n", "\n", "数据集加载后,一般以迭代方式获取数据,然后送入神经网络中进行训练。我们可以用`create_tuple_iterator`或`create_dict_iterator`接口创建数据迭代器,迭代访问数据。\n", "\n", "访问的数据类型默认为`Tensor`;若设置`output_numpy=True`,访问的数据类型为`Numpy`。\n", "\n", "下面定义一个可视化函数,迭代9张图片进行展示。" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "def visualize(dataset):\n", " figure = plt.figure(figsize=(4, 4))\n", " cols, rows = 3, 3\n", "\n", " for idx, (image, label) in enumerate(dataset.create_tuple_iterator()):\n", " figure.add_subplot(rows, cols, idx + 1)\n", " plt.title(int(label))\n", " plt.axis(\"off\")\n", " plt.imshow(image.asnumpy().squeeze(), cmap=\"gray\")\n", " if idx == cols * rows - 1:\n", " break\n", " plt.show()" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "visualize(train_dataset)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## 数据集常用操作" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Pipeline的设计理念使得数据集的常用操作采用`dataset = dataset.operation()`的异步执行方式,执行操作返回新的Dataset,此时不执行具体操作,而是在Pipeline中加入节点,最终进行迭代时,并行执行整个Pipeline。\n", "\n", "下面分别介绍几种常见的数据集操作。" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### shuffle\n", "\n", "数据集随机`shuffle`可以消除数据排列造成的分布不均问题。\n", "\n", "![op-shuffle](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/r2.1/tutorials/source_zh_cn/advanced/dataset/images/op_shuffle.png)\n", "\n", "`mindspore.dataset`提供的数据集在加载时可配置`shuffle=True`,或使用如下操作:" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "train_dataset = train_dataset.shuffle(buffer_size=64)\n", "\n", "visualize(train_dataset)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### map" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "`map`操作是数据预处理的关键操作,可以针对数据集指定列(column)添加数据变换(Transforms),将数据变换应用于该列数据的每个元素,并返回包含变换后元素的新数据集。这里我们对Mnist数据集做数据缩放处理,将图像统一除255,数据类型由uint8转为float32。\n", "\n", "> Dataset支持的不同变换类型详见[数据变换Transforms](https://www.mindspore.cn/tutorials/zh-CN/r2.1/beginner/transforms.html)。" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(28, 28, 1) UInt8\n" ] } ], "source": [ "image, label = next(train_dataset.create_tuple_iterator())\n", "print(image.shape, image.dtype)" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [], "source": [ "train_dataset = train_dataset.map(vision.Rescale(1.0 / 255.0, 0), input_columns='image')" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "对比map前后的数据,可以看到数据类型变化。" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(28, 28, 1) Float32\n" ] } ], "source": [ "image, label = next(train_dataset.create_tuple_iterator())\n", "print(image.shape, image.dtype)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### batch\n", "\n", "将数据集打包为固定大小的`batch`是在有限硬件资源下使用梯度下降进行模型优化的折中方法,可以保证梯度下降的随机性和优化计算量。\n", "\n", "![op-batch](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/r2.1/tutorials/source_zh_cn/advanced/dataset/images/op_batch.png)\n", "\n", "一般我们会设置一个固定的batch size,将连续的数据分为若干批(batch)。" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [], "source": [ "train_dataset = train_dataset.batch(batch_size=32)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "batch后的数据增加一维,大小为`batch_size`。" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(32, 28, 28, 1) Float32\n" ] } ], "source": [ "image, label = next(train_dataset.create_tuple_iterator())\n", "print(image.shape, image.dtype)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## 自定义数据集" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "`mindspore.dataset`模块提供了一些常用的公开数据集和标准格式数据集的加载API。\n", "\n", "对于MindSpore暂不支持直接加载的数据集,可以构造自定义数据加载类或自定义数据集生成函数的方式来生成数据集,然后通过`GeneratorDataset`接口实现自定义方式的数据集加载。\n", "\n", "`GeneratorDataset`支持通过可随机访问数据集对象、可迭代数据集对象和生成器(generator)构造自定义数据集,下面分别对其进行介绍。" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### 可随机访问数据集\n", "\n", "可随机访问数据集是实现了`__getitem__`和`__len__`方法的数据集,表示可以通过索引/键直接访问对应位置的数据样本。\n", "\n", "例如,当使用`dataset[idx]`访问这样的数据集时,可以读取dataset内容中第idx个样本或标签。" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [], "source": [ "# Random-accessible object as input source\n", "class RandomAccessDataset:\n", " def __init__(self):\n", " self._data = np.ones((5, 2))\n", " self._label = np.zeros((5, 1))\n", "\n", " def __getitem__(self, index):\n", " return self._data[index], self._label[index]\n", "\n", " def __len__(self):\n", " return len(self._data)" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[Tensor(shape=[2], dtype=Float64, value= [ 1.00000000e+00, 1.00000000e+00]), Tensor(shape=[1], dtype=Float64, value= [ 0.00000000e+00])]\n", "[Tensor(shape=[2], dtype=Float64, value= [ 1.00000000e+00, 1.00000000e+00]), Tensor(shape=[1], dtype=Float64, value= [ 0.00000000e+00])]\n", "[Tensor(shape=[2], dtype=Float64, value= [ 1.00000000e+00, 1.00000000e+00]), Tensor(shape=[1], dtype=Float64, value= [ 0.00000000e+00])]\n", "[Tensor(shape=[2], dtype=Float64, value= [ 1.00000000e+00, 1.00000000e+00]), Tensor(shape=[1], dtype=Float64, value= [ 0.00000000e+00])]\n", "[Tensor(shape=[2], dtype=Float64, value= [ 1.00000000e+00, 1.00000000e+00]), Tensor(shape=[1], dtype=Float64, value= [ 0.00000000e+00])]\n" ] } ], "source": [ "loader = RandomAccessDataset()\n", "dataset = GeneratorDataset(source=loader, column_names=[\"data\", \"label\"])\n", "\n", "for data in dataset:\n", " print(data)" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[Tensor(shape=[], dtype=Int64, value= 2)]\n", "[Tensor(shape=[], dtype=Int64, value= 0)]\n", "[Tensor(shape=[], dtype=Int64, value= 1)]\n" ] } ], "source": [ "# list, tuple are also supported.\n", "loader = [np.array(0), np.array(1), np.array(2)]\n", "dataset = GeneratorDataset(source=loader, column_names=[\"data\"])\n", "\n", "for data in dataset:\n", " print(data)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### 可迭代数据集\n", "\n", "可迭代的数据集是实现了`__iter__`和`__next__`方法的数据集,表示可以通过迭代的方式逐步获取数据样本。这种类型的数据集特别适用于随机访问成本太高或者不可行的情况。\n", "\n", "例如,当使用`iter(dataset)`的形式访问数据集时,可以读取从数据库、远程服务器返回的数据流。\n", "\n", "下面构造一个简单迭代器,并将其加载至`GeneratorDataset`。" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [], "source": [ "# Iterator as input source\n", "class IterableDataset():\n", " def __init__(self, start, end):\n", " '''init the class object to hold the data'''\n", " self.start = start\n", " self.end = end\n", " def __next__(self):\n", " '''iter one data and return'''\n", " return next(self.data)\n", " def __iter__(self):\n", " '''reset the iter'''\n", " self.data = iter(range(self.start, self.end))\n", " return self" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[Tensor(shape=[], dtype=Int64, value= 1)]\n", "[Tensor(shape=[], dtype=Int64, value= 2)]\n", "[Tensor(shape=[], dtype=Int64, value= 3)]\n", "[Tensor(shape=[], dtype=Int64, value= 4)]\n" ] } ], "source": [ "loader = IterableDataset(1, 5)\n", "dataset = GeneratorDataset(source=loader, column_names=[\"data\"])\n", "\n", "for d in dataset:\n", " print(d)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### 生成器\n", "\n", "生成器也属于可迭代的数据集类型,其直接依赖Python的生成器类型`generator`返回数据,直至生成器抛出`StopIteration`异常。\n", "\n", "下面构造一个生成器,并将其加载至`GeneratorDataset`。" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [], "source": [ "# Generator\n", "def my_generator(start, end):\n", " for i in range(start, end):\n", " yield i" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[Tensor(shape=[], dtype=Int64, value= 3)]\n", "[Tensor(shape=[], dtype=Int64, value= 4)]\n", "[Tensor(shape=[], dtype=Int64, value= 5)]\n" ] } ], "source": [ "# since a generator instance can be only iterated once, we need to wrap it by lambda to generate multiple instances\n", "dataset = GeneratorDataset(source=lambda: my_generator(3, 6), column_names=[\"data\"])\n", "\n", "for d in dataset:\n", " print(d)" ] } ], "metadata": { "kernelspec": { "display_name": "MindSpore", "language": "python", "name": "mindspore" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.6" }, "vscode": { "interpreter": { "hash": "8c9da313289c39257cb28b126d2dadd33153d4da4d524f730c81a4aaccbd2ca7" } } }, "nbformat": 4, "nbformat_minor": 4 }