{ "cells": [ { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "[](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/r2.4.1/tutorials/zh_cn/beginner/mindspore_dataset.ipynb) [](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/r2.4.1/tutorials/zh_cn/beginner/mindspore_dataset.py) [](https://gitee.com/mindspore/docs/blob/r2.4.1/tutorials/source_zh_cn/beginner/dataset.ipynb)\n", "\n", "[基本介绍](https://www.mindspore.cn/tutorials/zh-CN/r2.4.1/beginner/introduction.html) || [快速入门](https://www.mindspore.cn/tutorials/zh-CN/r2.4.1/beginner/quick_start.html) || [张量 Tensor](https://www.mindspore.cn/tutorials/zh-CN/r2.4.1/beginner/tensor.html) || **数据加载与处理** || [网络构建](https://www.mindspore.cn/tutorials/zh-CN/r2.4.1/beginner/model.html) || [函数式自动微分](https://www.mindspore.cn/tutorials/zh-CN/r2.4.1/beginner/autograd.html) || [模型训练](https://www.mindspore.cn/tutorials/zh-CN/r2.4.1/beginner/train.html) || [保存与加载](https://www.mindspore.cn/tutorials/zh-CN/r2.4.1/beginner/save_load.html) || [使用静态图加速](https://www.mindspore.cn/tutorials/zh-CN/r2.4.1/beginner/accelerate_with_static_graph.html) || [自动混合精度](https://www.mindspore.cn/tutorials/zh-CN/r2.4.1/beginner/mixed_precision.html) ||" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "# 数据加载与处理\n", "\n", "数据是深度学习的基础,高质量的数据输入将在整个深度神经网络中起到积极作用。\n", "\n", "MindSpore提供基于Pipeline的[数据引擎](https://www.mindspore.cn/docs/zh-CN/r2.4.1/design/data_engine.html),通过 `数据集(Dataset)`、`数据变换(Transforms)`和`数据batch`实现高效的数据预处理。其中:\n", "\n", "1. 数据集(Dataset)是Pipeline的起始,用于从存储中加载原始数据至内存中,`mindspore.dataset`提供了内置的图像、文本、音频等[数据集加载接口](https://www.mindspore.cn/docs/zh-CN/r2.4.1/api_python/mindspore.dataset.html#),并提供了[自定义数据集加载接口](https://www.mindspore.cn/docs/zh-CN/r2.4.1/api_python/mindspore.dataset.html#%E7%94%A8%E6%88%B7%E8%87%AA%E5%AE%9A%E4%B9%89);\n", "\n", "2. 数据变换(Transforms)对内存中的数据做进一步的变换操作,`mindspore.dataset.transforms`提供[通用的数据变换操作](https://www.mindspore.cn/docs/zh-CN/r2.4.1/api_python/mindspore.dataset.transforms.html#%E9%80%9A%E7%94%A8)、`mindspore.dataset.transforms.vision`提供[图像数据变换操作](https://www.mindspore.cn/docs/zh-CN/r2.4.1/api_python/mindspore.dataset.transforms.html#%E8%A7%86%E8%A7%89)、`mindspore.dataset.transforms.text`提供[文本数据变换操作](https://www.mindspore.cn/docs/zh-CN/r2.4.1/api_python/mindspore.dataset.transforms.html#%E6%96%87%E6%9C%AC)、`mindspore.dataset.transforms.audio`提供[音频数据变换操作](https://www.mindspore.cn/docs/zh-CN/r2.4.1/api_python/mindspore.dataset.transforms.html#%E9%9F%B3%E9%A2%91);\n", "\n", "3. 数据batch完成对变换后的数据组batch,用于最终的神经网络训练,batch操作是针对一个数据集对象,其接口可参考:[batch操作](https://www.mindspore.cn/docs/zh-CN/r2.4.1/api_python/dataset/mindspore.dataset.MindDataset.html#batch%E6%89%B9%E6%93%8D%E4%BD%9C);\n", "\n", "4. 数据集迭代器是将最后的数据通过迭代的方式输出,迭代器也是针对一个数据集对象,其接口可参考:[迭代器](https://www.mindspore.cn/docs/zh-CN/r2.4.1/api_python/dataset/mindspore.dataset.MindDataset.html#%E8%BF%AD%E4%BB%A3%E5%99%A8)。\n", "\n", "此外MindSpore的领域开发库也提供了大量的预加载数据集,可以使用API一键下载使用。本教程将分别对不同的数据集(Dataset)加载方式:自定义数据集、标准格式数据集和常见数据集,数据变换(Transforms)和数据batch方法进行详细阐述。" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [], "source": [ "import os\n", "import numpy as np\n", "from mindspore import dtype as mstype\n", "from mindspore.dataset import transforms\n", "from mindspore.dataset import vision\n", "from mindspore.dataset import MindDataset, GeneratorDataset, MnistDataset, NumpySlicesDataset\n", "from mindspore.mindrecord import FileWriter\n", "import matplotlib.pyplot as plt" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## 数据集加载\n", "\n", "`mindspore.dataset`模块提供了自定义数据集、标准格式数据集和一些常用的公开常用数据集的加载API。\n", "\n", "### 自定义数据集\n", "\n", "对于MindSpore暂不支持直接加载的数据集,可以构造自定义数据加载类或自定义数据集生成函数的方式来生成数据集,然后通过`GeneratorDataset`接口实现自定义方式的数据集加载。\n", "\n", "`GeneratorDataset`支持通过可随机访问数据集对象、可迭代数据集对象和生成器(generator)构造自定义数据集,下面分别对其进行介绍。\n", "\n", "#### 可随机访问数据集\n", "\n", "可随机访问数据集是实现了`__getitem__`和`__len__`方法的数据集,表示可以通过索引/键直接访问对应位置的数据样本。\n", "\n", "例如,当使用`dataset[idx]`访问这样的数据集时,可以读取dataset内容中第idx个样本或标签。" ] }, { "cell_type": "code", "execution_count": 51, "metadata": { "pycharm": { "name": "#%%\n" } }, "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": [ "# 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", " def __getitem__(self, index):\n", " return self._data[index], self._label[index]\n", " def __len__(self):\n", " return len(self._data)\n", "\n", "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": 52, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[Tensor(shape=[], dtype=Int32, value= 2)]\n", "[Tensor(shape=[], dtype=Int32, value= 0)]\n", "[Tensor(shape=[], dtype=Int32, 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": 53, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[Tensor(shape=[], dtype=Int32, value= 1)]\n", "[Tensor(shape=[], dtype=Int32, value= 2)]\n", "[Tensor(shape=[], dtype=Int32, value= 3)]\n", "[Tensor(shape=[], dtype=Int32, value= 4)]\n" ] } ], "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\n", "\n", "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": { "pycharm": { "name": "#%% md\n" } }, "source": [ "#### 生成器\n", "\n", "生成器也属于可迭代的数据集类型,其直接依赖Python的生成器类型`generator`返回数据,直至生成器抛出`StopIteration`异常。\n", "\n", "下面构造一个生成器,并将其加载至`GeneratorDataset`。" ] }, { "cell_type": "code", "execution_count": 54, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[Tensor(shape=[], dtype=Int32, value= 3)]\n", "[Tensor(shape=[], dtype=Int32, value= 4)]\n", "[Tensor(shape=[], dtype=Int32, value= 5)]\n" ] } ], "source": [ "# Generator\n", "def my_generator(start, end):\n", " for i in range(start, end):\n", " yield i\n", "\n", "# 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)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "### 标准格式数据集\n", "\n", "对于MindSpore暂不支持直接加载的数据集,可以将数据集转换成**MindRecord格式**数据集,然后通过`MindDataset`接口实现数据集加载。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "首先通过**MindRecord格式**接口[FileWriter](https://www.mindspore.cn/docs/zh-CN/r2.4.1/api_python/mindspore.mindrecord.html#mindspore.mindrecord.FileWriter)创建一个新的**MindRecord格式**数据集,其中每个样本包含`file_name`、`label`和`data`三个字段。" ] }, { "cell_type": "code", "execution_count": 55, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "if os.path.exists(\"./test.mindrecord\"):\n", " os.remove(\"./test.mindrecord\")\n", "if os.path.exists(\"./test.mindrecord.db\"):\n", " os.remove(\"./test.mindrecord.db\")\n", "writer = FileWriter(file_name=\"test.mindrecord\", shard_num=1, overwrite=True)\n", "schema_json = {\"file_name\": {\"type\": \"string\"},\n", " \"label\": {\"type\": \"int32\"},\n", " \"data\": {\"type\": \"int32\", \"shape\": [-1]}}\n", "writer.add_schema(schema_json, \"test_schema\")\n", "for i in range(4):\n", " data = [{\"file_name\": str(i) + \".jpg\",\n", " \"label\": i,\n", " \"data\": np.array([i]*(i+1), dtype=np.int32)}]\n", " writer.write_raw_data(data)\n", "writer.commit()" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "然后通过**MindDataset**接口读取**MindRecord格式**数据集。" ] }, { "cell_type": "code", "execution_count": 56, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[Tensor(shape=[1], dtype=Int32, value= [0]), Tensor(shape=[], dtype=String, value= '0.jpg'), Tensor(shape=[], dtype=Int32, value= 0)]\n", "[Tensor(shape=[2], dtype=Int32, value= [1, 1]), Tensor(shape=[], dtype=String, value= '1.jpg'), Tensor(shape=[], dtype=Int32, value= 1)]\n", "[Tensor(shape=[3], dtype=Int32, value= [2, 2, 2]), Tensor(shape=[], dtype=String, value= '2.jpg'), Tensor(shape=[], dtype=Int32, value= 2)]\n", "[Tensor(shape=[4], dtype=Int32, value= [3, 3, 3, 3]), Tensor(shape=[], dtype=String, value= '3.jpg'), Tensor(shape=[], dtype=Int32, value= 3)]\n" ] } ], "source": [ "dataset = MindDataset(\"test.mindrecord\", shuffle=False)\n", "for data in dataset:\n", " print(data)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "### 常用数据集\n", "\n", "我们使用**Mnist**数据集作为样例,介绍使用常用数据集的加载方法。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`mindspore.dataset`提供的接口**仅支持解压后的数据文件**,因此我们使用`download`库下载数据集并解压。" ] }, { "cell_type": "code", "execution_count": 57, "metadata": { "pycharm": { "name": "#%%\n" } }, "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:01<00:00, 5.78MB/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": 58, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "<class 'mindspore.dataset.engine.datasets_vision.MnistDataset'>\n" ] } ], "source": [ "train_dataset = MnistDataset(\"MNIST_Data/train\", shuffle=False)\n", "print(type(train_dataset))" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "使用迭代器循环输出数据,下面定义一个可视化函数,迭代**Mnist**数据集中9张图片进行展示。" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [], "source": [ "def visualize(dataset):\n", " figure = plt.figure(figsize=(4, 4))\n", " cols, rows = 3, 3\n", "\n", " plt.subplots_adjust(wspace=0.5, hspace=0.5)\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": 60, "metadata": {}, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "<Figure size 400x400 with 9 Axes>" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "visualize(train_dataset)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## 数据变换\n", "\n", "通常情况下,直接加载的原始数据并不能直接送入神经网络进行训练,此时我们需要对其进行数据预处理。MindSpore提供不同种类的数据变换(Transforms),配合数据处理Pipeline来实现数据预处理,所有的Transforms均可通过`.map(...)`方法传入。\n", "\n", "1. `.map(...)`操作可以针对数据集指定列(column)添加数据变换(Transforms),将数据变换应用于该列数据的每个元素,并返回包含变换后元素的新数据集。\n", "\n", "2. `.map(...)`操作可以执行Dataset模块提供的内置数据变换操作,也可以执行用户自定义的变换操作。\n", "\n", "`mindspore.dataset`提供了面向图像、文本、音频等不同数据类型的内置数据变换操作,同时也支持使用自定义数据变换操作。下面分别对其进行介绍。\n", "\n", "### 内置数据变换操作\n", "\n", "`mindspore.dataset`提供的内置数据变换:[vision数据变换](https://www.mindspore.cn/docs/zh-CN/r2.4.1/api_python/mindspore.dataset.transforms.html#%E8%A7%86%E8%A7%89) , [nlp数据变换](https://www.mindspore.cn/docs/zh-CN/r2.4.1/api_python/mindspore.dataset.transforms.html#%E6%96%87%E6%9C%AC) , [audio数据变换](https://www.mindspore.cn/docs/zh-CN/r2.4.1/api_python/mindspore.dataset.transforms.html#%E9%9F%B3%E9%A2%91)。\n", "\n", "下面举例对**Mnist**数据集中**data**使用 `Rescale`、`Normalize`和`HWC2CHW`操作,对**label**使用`TypeCast`操作。\n", "\n", "1. Rescale:用于调整图像像素值的大小,包括两个参数:rescale(缩放因子)和shift(平移因子),图像的每个像素将根据这两个参数进行调整,输出的像素值为$output_{i} = input_{i} * rescale + shift$。\n", "\n", "2. Normalize:用于对输入图像的归一化,包括三个参数:mean(图像每个通道的均值)、std(图像每个通道的标准差)和is_hwc(bool值,输入图像的格式。True为(height, width, channel),False为(channel, height, width))。图像的每个通道将根据mean和std进行调整,计算公式为 $output_{c} = \\frac{input_{c} - mean_{c}}{std_{c}}$ ,其中 $c$ 代表通道索引。\n", "\n", "3. HWC2CHW:用于转换图像格式,将图像从HWC转换成CHW。" ] }, { "cell_type": "code", "execution_count": 61, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(1, 28, 28) Float32\n", "() Int32\n" ] } ], "source": [ "train_dataset = MnistDataset('MNIST_Data/train')\n", "train_dataset = train_dataset.map(operations=[vision.Rescale(1.0 / 255.0, 0),\n", " vision.Normalize(mean=(0.1307,), std=(0.3081,)),\n", " vision.HWC2CHW()],\n", " input_columns=['image'])\n", "train_dataset = train_dataset.map(operations=[transforms.TypeCast(mstype.int32)],\n", " input_columns=['label'])\n", "for data in train_dataset:\n", " print(data[0].shape, data[0].dtype)\n", " print(data[1].shape, data[1].dtype)\n", " break" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false }, "source": [ "### 自定义数据变换操作\n", "\n", "下面举例对**Mnist**数据集中**data**使用 自定义的`Rescale`、自定义的`Normalize`和 自定义的`HWC2CHW`操作,对**label**使用自定义的`TypeCast`操作。" ] }, { "cell_type": "code", "execution_count": 62, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(1, 28, 28) Float32\n", "() Int32\n" ] } ], "source": [ "train_dataset = MnistDataset('MNIST_Data/train')\n", "def rescale_normalize_hwc2chw(input_col):\n", " trans_result = input_col / 255.0\n", " trans_result = (trans_result - 0.1307) / 0.3081\n", " trans_result = trans_result.transpose(2, 0, 1)\n", " return trans_result.astype(np.float32)\n", "train_dataset = train_dataset.map(operations=rescale_normalize_hwc2chw,\n", " input_columns=['image'])\n", "def typecast(input_col):\n", " trans_result = input_col.astype(np.int32)\n", " return trans_result\n", "train_dataset = train_dataset.map(operations=typecast,\n", " input_columns=['label'])\n", "for data in train_dataset:\n", " print(data[0].shape, data[0].dtype)\n", " print(data[1].shape, data[1].dtype)\n", " break" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false }, "source": [ "## 数据batch\n", "\n", "batch意义在于将多个样本打包为固定大小的`batch`,且在有限硬件资源下使用梯度下降进行模型优化的折中方法,可以保证梯度下降的随机性和优化计算量。\n", "\n", "一般我们会设置一个固定的batch size,将连续的数据分为若干批(batch)。batch后的数据增加一维,大小为`batch_size`。\n", "\n", "" ] }, { "cell_type": "code", "execution_count": 63, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(2, 2) (2,)\n", "(2, 2) (2,)\n", "(2, 2) (2,)\n" ] } ], "source": [ "data = ([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]], [0, 1, 0, 1, 0, 1])\n", "dataset = NumpySlicesDataset(data=data, column_names=[\"data\", \"label\"], shuffle=False)\n", "dataset = dataset.batch(2)\n", "for data in dataset.create_tuple_iterator():\n", " print(data[0].shape, data[1].shape)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false }, "source": [ "## 数据集迭代器\n", "\n", "数据集Pipeline定义完成后,一般以迭代方式获取数据,然后送入神经网络中进行训练。我们可以用[create_tuple_iterator](https://www.mindspore.cn/docs/zh-CN/r2.4.1/api_python/dataset/dataset_method/iterator/mindspore.dataset.Dataset.create_tuple_iterator.html)或[create_dict_iterator](https://www.mindspore.cn/docs/zh-CN/r2.4.1/api_python/dataset/dataset_method/iterator/mindspore.dataset.Dataset.create_dict_iterator.html)接口创建数据迭代器,并迭代访问数据。\n", "\n", "访问的数据类型默认为`Tensor`;若设置`output_numpy=True`,访问的数据类型为`Numpy`。" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "下面展示`create_tuple_iterator`迭代器输出的结果。" ] }, { "cell_type": "code", "execution_count": 64, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[Tensor(shape=[2], dtype=Int32, value= [2, 4]), Tensor(shape=[2], dtype=Int32, value= [0, 1])]\n", "[Tensor(shape=[2], dtype=Int32, value= [6, 8]), Tensor(shape=[2], dtype=Int32, value= [0, 1])]\n", "[Tensor(shape=[2], dtype=Int32, value= [10, 12]), Tensor(shape=[2], dtype=Int32, value= [0, 1])]\n", "[Tensor(shape=[2], dtype=Int32, value= [14, 16]), Tensor(shape=[2], dtype=Int32, value= [0, 1])]\n" ] } ], "source": [ "data = ([1, 2, 3, 4, 5, 6, 7, 8], [0, 1, 0, 1, 0, 1, 0, 1])\n", "dataset = NumpySlicesDataset(data=data, column_names=[\"data\", \"label\"], shuffle=False)\n", "dataset = dataset.map(lambda x: x * 2, input_columns=[\"data\"])\n", "dataset = dataset.batch(2)\n", "for data in dataset.create_tuple_iterator():\n", " print(data)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "下面展示`create_dict_iterator`迭代器输出的结果。" ] }, { "cell_type": "code", "execution_count": 65, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'data': Tensor(shape=[2], dtype=Int32, value= [2, 4]), 'label': Tensor(shape=[2], dtype=Int32, value= [0, 1])}\n", "{'data': Tensor(shape=[2], dtype=Int32, value= [6, 8]), 'label': Tensor(shape=[2], dtype=Int32, value= [0, 1])}\n", "{'data': Tensor(shape=[2], dtype=Int32, value= [10, 12]), 'label': Tensor(shape=[2], dtype=Int32, value= [0, 1])}\n", "{'data': Tensor(shape=[2], dtype=Int32, value= [14, 16]), 'label': Tensor(shape=[2], dtype=Int32, value= [0, 1])}\n" ] } ], "source": [ "data = ([1, 2, 3, 4, 5, 6, 7, 8], [0, 1, 0, 1, 0, 1, 0, 1])\n", "dataset = NumpySlicesDataset(data=data, column_names=[\"data\", \"label\"], shuffle=False)\n", "dataset = dataset.map(lambda x: x * 2, input_columns=[\"data\"])\n", "dataset = dataset.batch(2)\n", "for data in dataset.create_dict_iterator():\n", " print(data)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3.7.5 64-bit", "language": "python", "name": "python3" }, "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.5" }, "vscode": { "interpreter": { "hash": "5109d816b82be14675a6b11f8e0f0d2e80f029176ed3710d54e125caa8520dfd" } } }, "nbformat": 4, "nbformat_minor": 4 }