{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "6XvCUmCEd4Dm" }, "source": [ "# TensorFlow Datasets\n", "\n", "TFDS は、TensorFlow、Jax、およびその他の機械学習フレームワークですぐに使用できる一連のデータセットを提供しています。\n", "\n", "データの確定的なダウンロードと準備、および `tf.data.Dataset`(または `np.array`)の構築を行います。\n", "\n", "注意: [TFDS](https://www.tensorflow.org/datasets)(このライブラリ)と `tf.data`(有効なデータパイプラインを構築する TensorFlow API)を混同しないようにしてください。TFDS は `tf.data` を囲む高レベルのラッパーです。この API をよく知らない方は、まず [ tf.data の公式ガイド](https://www.tensorflow.org/guide/data)を読むことをお勧めします。\n" ] }, { "cell_type": "markdown", "metadata": { "id": "J8y9ZkLXmAZc" }, "source": [ "Copyright 2018 The TensorFlow Datasets Authors, Licensed under the Apache License, Version 2.0" ] }, { "cell_type": "markdown", "metadata": { "id": "OGw9EgE0tC0C" }, "source": [ "\n", " \n", " \n", " \n", " \n", "
TensorFlow.org で表示Google Colab で実行GitHub でソースを表示ノートブックをダウンロード
" ] }, { "cell_type": "markdown", "metadata": { "id": "_7hshda5eaGL" }, "source": [ "## インストール\n", "\n", "TFDS は 2 つのパッケージで存在します。\n", "\n", "- `pip install tensorflow-datasets`: 安定バージョン。数か月おきにリリースされます。\n", "- `pip install tfds-nightly`: 毎日リリースされ、データセットの最終バージョンが含まれます。\n", "\n", "この Colabでは、`tfds-nightly` を使用します。\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "cellView": "both", "id": "boeZp0sYbO41" }, "outputs": [], "source": [ "!pip install -q tfds-nightly tensorflow matplotlib" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "TTBSvHcSLBzc" }, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import tensorflow as tf\n", "\n", "import tensorflow_datasets as tfds" ] }, { "cell_type": "markdown", "metadata": { "id": "VZZyuO13fPvk" }, "source": [ "## 利用可能なデータセットを特定する\n", "\n", "すべてのデータセットビルダーは、`tfds.core.DatasetBuilder` のサブクラスです。利用可能なビルダーのリストを取得するには、`tfds.list_builders()` を使用するか、[カタログ](https://www.tensorflow.org/datasets/catalog/overview)をご覧ください。" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "FAvbSVzjLCIb" }, "outputs": [], "source": [ "tfds.list_builders()" ] }, { "cell_type": "markdown", "metadata": { "id": "VjI6VgOBf0v0" }, "source": [ "## データセットを読み込む\n", "\n", "### tfds.load\n", "\n", "データセットを最も簡単に読み込むには、`tfds.load` を使用します。次の内容が行われます。\n", "\n", "1. データをダウンロードし、[`tfrecord`](https://www.tensorflow.org/tutorials/load_data/tfrecord) ファイルとして保存します。\n", "2. `tfrecord` を読み込んで、`tf.data.Dataset` を作成します。\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "dCou80mnLLPV" }, "outputs": [], "source": [ "ds = tfds.load('mnist', split='train', shuffle_files=True)\n", "assert isinstance(ds, tf.data.Dataset)\n", "print(ds)" ] }, { "cell_type": "markdown", "metadata": { "id": "byOXYCEJS7S6" }, "source": [ "次ような一般的な属性があります。\n", "\n", "- `split=`: 分割して読み取ります(`'train'`、`['train', 'test']`、`'train[80%:]'`、など)。[split API ガイド](https://www.tensorflow.org/datasets/splits)をご覧ください。\n", "- `shuffle_files=`: エポック間でファイルをシャッフルするかどうかを制御します(TFDS は大規模なデータセットを複数の小さなファイルに保存します)。\n", "- `data_dir=`: データセットが保存される場所(デフォルトは `~/tensorflow_datasets/`)\n", "- `with_info=True`: データセットのメタデータを含む `tfds.core.DatasetInfo` を返します。\n", "- `download=False`: ダウンロードを無効にします。\n" ] }, { "cell_type": "markdown", "metadata": { "id": "qeNmFx_1RXCb" }, "source": [ "### tfds.builder\n", "\n", "`tfds.load` は、`tfds.core.DatasetBuilder` の新ラッパーです。`tfds.core.DatasetBuilder` API を使用して同じ出力を取得することができます。" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "2zN_jQ2ER40W" }, "outputs": [], "source": [ "builder = tfds.builder('mnist')\n", "# 1. Create the tfrecord files (no-op if already exists)\n", "builder.download_and_prepare()\n", "# 2. Load the `tf.data.Dataset`\n", "ds = builder.as_dataset(split='train', shuffle_files=True)\n", "print(ds)" ] }, { "cell_type": "markdown", "metadata": { "id": "IwrjccfjoQCD" }, "source": [ "### `tfds build` CLI\n", "\n", "特定のデータセットを生成する場合は、[`tfds` コマンドライン](https://www.tensorflow.org/datasets/cli) を使用できます。以下に例を示します。\n", "\n", "```sh\n", "tfds build mnist\n", "```\n", "\n", "利用できるフラグについては、[ドキュメント](https://www.tensorflow.org/datasets/cli)をご覧ください。" ] }, { "cell_type": "markdown", "metadata": { "id": "aW132I-rbJXE" }, "source": [ "## データセットをイテレートする\n", "\n", "### dict 型\n", "\n", "デフォルトでは、`tf.data.Dataset` オブジェクトには、`tf.Tensor` の `dict` が含まれます。" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "JAGjXdk_bIYQ" }, "outputs": [], "source": [ "ds = tfds.load('mnist', split='train')\n", "ds = ds.take(1) # Only take a single example\n", "\n", "for example in ds: # example is `{'image': tf.Tensor, 'label': tf.Tensor}`\n", " print(list(example.keys()))\n", " image = example[\"image\"]\n", " label = example[\"label\"]\n", " print(image.shape, label)" ] }, { "cell_type": "markdown", "metadata": { "id": "sIqX2bmhu-8d" }, "source": [ "`dict` のキー名と構造を知るには、[カタログ](https://www.tensorflow.org/datasets/catalog/overview#all_datasets)のデータセットドキュメントを確認します。例: [mnist ドキュメント](https://www.tensorflow.org/datasets/catalog/mnist)。" ] }, { "cell_type": "markdown", "metadata": { "id": "umAtqBBqdkDG" }, "source": [ "### タプル (`as_supervised=True`)\n", "\n", "`as_supervised=True` を使用すると、スーパーバイズされたデータセットの代わりにタプル型 `(features, label)` を取得することができます。" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "nJ4O0xy3djfV" }, "outputs": [], "source": [ "ds = tfds.load('mnist', split='train', as_supervised=True)\n", "ds = ds.take(1)\n", "\n", "for image, label in ds: # example is (image, label)\n", " print(image.shape, label)" ] }, { "cell_type": "markdown", "metadata": { "id": "u9palgyHfEwQ" }, "source": [ "### NumPy 配列 (`tfds.as_numpy`)\n", "\n", "`tfds.as_numpy` を使用して、次のように変換します。\n", "\n", "- `tf.Tensor` -> `np.array`\n", "- `tf.data.Dataset` -> `Iterator[Tree[np.array]]`(`Tree` は任意のネストされた `Dict`、`Tuple`)\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "tzQTCUkAfe9R" }, "outputs": [], "source": [ "ds = tfds.load('mnist', split='train', as_supervised=True)\n", "ds = ds.take(1)\n", "\n", "for image, label in tfds.as_numpy(ds):\n", " print(type(image), type(label), label)" ] }, { "cell_type": "markdown", "metadata": { "id": "XaRN-LdXUkl_" }, "source": [ "### バッチ化された tf.Tensor(`batch_size=-1`)\n", "\n", "`batch_size=-1` を使用すると、単一のバッチで全データセットを読み込むことができます。\n", "\n", "これは `as_supervised=True` と `tfds.as_numpy` に組み合わせることで、データを `(np.array, np.array)` として取得できます。\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "Gg8BNsv-UzFl" }, "outputs": [], "source": [ "image, label = tfds.as_numpy(tfds.load(\n", " 'mnist',\n", " split='test',\n", " batch_size=-1,\n", " as_supervised=True,\n", "))\n", "\n", "print(type(image), image.shape)" ] }, { "cell_type": "markdown", "metadata": { "id": "kRJrB3L6wgKI" }, "source": [ "データセットがメモリに収まる可能性があり、すべてのサンプルの形状が同じであることに注意してください。" ] }, { "cell_type": "markdown", "metadata": { "id": "heaKNg7-X4jN" }, "source": [ "## データセットのベンチマークを作成する\n", "\n", "データセットのベンチマーク作成は、単純な `tfds.benchmark` 呼び出しを任意のイテラブル(`tf.data.Dataset`、`tfds.as_numpy` など)に対して行います。\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "ZyQzZ98bX3dM" }, "outputs": [], "source": [ "ds = tfds.load('mnist', split='train')\n", "ds = ds.batch(32).prefetch(1)\n", "\n", "tfds.benchmark(ds, batch_size=32)\n", "tfds.benchmark(ds, batch_size=32) # Second epoch much faster due to auto-caching" ] }, { "cell_type": "markdown", "metadata": { "id": "MT0yEX_4kYnV" }, "source": [ "- `batch_size=` kwarg でバッチサイズごとに結果を必ず正規化してください。\n", "- まとめると、最初のウォームアップバッチは、`tf.data.Dataset` の追加のセットアップ時間(バッファの初期化など)をキャプチャするために、ほかのバッチとは分離されます。\n", "- 2 つ目のイテレーションが、[TFDS auto-caching](https://www.tensorflow.org/datasets/performances#auto-caching) にいよってはるかに高速に行われるのがわかります。\n", "- `tfds.benchmark` は以降の分析で検査できる `tfds.core.BenchmarkResult` を返します。" ] }, { "cell_type": "markdown", "metadata": { "id": "o-cuwvVbeb43" }, "source": [ "### エンドツーエンドパイプラインを構築する\n", "\n", "先に進むには、次の項目をご覧ください。\n", "\n", "- [エンドツーエンド Keras の例](https://www.tensorflow.org/datasets/keras_example)。完全なトレーニングパイプラインを確認してください(バッチ処理、シャッフルなど)。\n", "- [パフォーマンスガイド](https://www.tensorflow.org/datasets/performances)。パイプラインの速度を改善します(ヒント: データセットのベンチマークに `tfds.benchmark(ds)` を使用します)。\n" ] }, { "cell_type": "markdown", "metadata": { "id": "gTRTEQqscxAE" }, "source": [ "## 視覚化する\n", "\n", "### tfds.as_dataframe\n", "\n", "`tf.data.Dataset` オブジェクトは、[`pandas.DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html) に変換可能で、その `tfds.as_dataframe` を [Colab](https://colab.research.google.com) で視覚化できます。\n", "\n", "- 画像、オーディオ、テキスト、動画などを視覚化するには、`tfds.as_dataframe` の 2 つ目の引数として `tfds.core.DatasetInfo` を追加します。\n", "- 最初の `x` サンプルのみを表示するには、`ds.take(x)` を使用します。`pandas.DataFrame` はメモリ内の全データセットを読み込むため、表示するには非常にコストがかかる可能性があります。" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "FKouwN_yVSGQ" }, "outputs": [], "source": [ "ds, info = tfds.load('mnist', split='train', with_info=True)\n", "\n", "tfds.as_dataframe(ds.take(4), info)" ] }, { "cell_type": "markdown", "metadata": { "id": "b-eDO_EXVGWC" }, "source": [ "### tfds.show_examples\n", "\n", "`tfds.show_examples` は `matplotlib.figure.Figure` を返します(現在は画像データセットのみがサポートされています)。" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "DpE2FD56cSQR" }, "outputs": [], "source": [ "ds, info = tfds.load('mnist', split='train', with_info=True)\n", "\n", "fig = tfds.show_examples(ds, info)" ] }, { "cell_type": "markdown", "metadata": { "id": "Y0iVVStvk0oI" }, "source": [ "## データセットのメタデータにアクセスする\n", "\n", "すべてのビルダーには、データセットのメタデータを含む `tfds.core.DatasetInfo` オブジェクトが含まれます。\n", "\n", "次の方法でアクセスできます。\n", "\n", "- `tfds.load` API:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "UgLgtcd1ljzt" }, "outputs": [], "source": [ "ds, info = tfds.load('mnist', with_info=True)" ] }, { "cell_type": "markdown", "metadata": { "id": "XodyqNXrlxTM" }, "source": [ "- `tfds.core.DatasetBuilder` API:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "nmq97QkilxeL" }, "outputs": [], "source": [ "builder = tfds.builder('mnist')\n", "info = builder.info" ] }, { "cell_type": "markdown", "metadata": { "id": "zMGOk_ZsmPeu" }, "source": [ "データセット情報には、データセットに関する追加情報(バージョン、引用、ホームページ、説明など)が含まれます。" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "O-wLIKD-mZQT" }, "outputs": [], "source": [ "print(info)" ] }, { "cell_type": "markdown", "metadata": { "id": "1zvAfRtwnAFk" }, "source": [ "### 特徴量メタデータ(ラベル名、画像形状など)\n", "\n", "次のようにして `tfds.features.FeatureDict` にアクセスします。" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "RcyZXncqoFab" }, "outputs": [], "source": [ "info.features" ] }, { "cell_type": "markdown", "metadata": { "id": "KAm9AV7loyw5" }, "source": [ "クラス数、ラベル名:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "HhfzBH6qowpz" }, "outputs": [], "source": [ "print(info.features[\"label\"].num_classes)\n", "print(info.features[\"label\"].names)\n", "print(info.features[\"label\"].int2str(7)) # Human readable version (8 -> 'cat')\n", "print(info.features[\"label\"].str2int('7'))" ] }, { "cell_type": "markdown", "metadata": { "id": "g5eWtk9ro_AK" }, "source": [ "形状、dtype:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "SergV_wQowLY" }, "outputs": [], "source": [ "print(info.features.shape)\n", "print(info.features.dtype)\n", "print(info.features['image'].shape)\n", "print(info.features['image'].dtype)" ] }, { "cell_type": "markdown", "metadata": { "id": "thMOZ4IKm55N" }, "source": [ "### 分割メタデータ(分割名、サンプル数など)\n", "\n", "次のようにして `tfds.core.SplitDict` にアクセスします。" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "FBbfwA8Sp4ax" }, "outputs": [], "source": [ "print(info.splits)" ] }, { "cell_type": "markdown", "metadata": { "id": "EVw1UVYa2HgN" }, "source": [ "利用可能な分割:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "fRBieOOquDzX" }, "outputs": [], "source": [ "print(list(info.splits.keys()))" ] }, { "cell_type": "markdown", "metadata": { "id": "iHW0VfA0t3dO" }, "source": [ "個々の分割に関する情報の取得:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "-h_OSpRsqKpP" }, "outputs": [], "source": [ "print(info.splits['train'].num_examples)\n", "print(info.splits['train'].filenames)\n", "print(info.splits['train'].num_shards)" ] }, { "cell_type": "markdown", "metadata": { "id": "fWhSkHFNuLwW" }, "source": [ "subsplit API でも動作します。" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "HO5irBZ3uIzQ" }, "outputs": [], "source": [ "print(info.splits['train[15%:75%]'].num_examples)\n", "print(info.splits['train[15%:75%]'].file_instructions)" ] }, { "cell_type": "markdown", "metadata": { "id": "YZp2XJwQQrI0" }, "source": [ "## トラブルシューティング\n", "\n", "### 手動ダウンロード(ダウンロードに失敗した場合)\n", "\n", "何らかの理由(オフラインなど)でダウンロードに失敗した場合は、手動でデータをダウンロードして `manual_dir`(デフォルトは `~/tensorflow_datasets/download/manual/`)にダウンロードすることができます。\n", "\n", "ダウンロードする URL を見つけるには、次を確認してください。\n", "\n", "- 新しいデータセットの場合(フォルダとして実装されている場合): [`tensorflow_datasets/`](https://github.com/tensorflow/datasets/tree/master/tensorflow_datasets/)`//checksums.tsv`。例: [`tensorflow_datasets/datasets/bool_q/checksums.tsv`](https://github.com/tensorflow/datasets/blob/master/tensorflow_datasets/datasets/bool_q/checksums.tsv)\n", "\n", " データセットのソースの場所は[カタログ](https://www.tensorflow.org/datasets/catalog/overview)をご覧ください。\n", "\n", "- 古いデータセットの場合: [`tensorflow_datasets/url_checksums/.txt`](https://github.com/tensorflow/datasets/tree/master/tensorflow_datasets/url_checksums)\n", "\n", "### `NonMatchingChecksumError` を修正する\n", "\n", "TFDS では、ダウンロード URL のチェックサムを検証することで、決定性を確保しています。`NonMatchingChecksumError` が発生する場合は、以下のことが考えられます。\n", "\n", "- ウェブサイトがダウンしている(`503 ステータスコード`など)。URL を確認してください。\n", "- Google Drive の URL の場合は、Drive の同じ URL に多くの人がアクセスしている場合にダウンロードを拒否することがあるため、後でもう一度試してみてください。[バグ](https://github.com/tensorflow/datasets/issues/1482)をご覧ください。\n", "- 元のデータセットファイルが更新されている。この場合、TFDS データセットビルダーを更新する必要があります。新しい Github issue か PR を発行してください。\n", " - `tfds build --register_checksums` で新しいチェックサムを登録します。\n", " - 最終的に、データセットの生成コードを更新します。\n", " - データセットの `VERSION` を更新します。\n", " - データセットの `RELEASE_NOTES` を更新します。チェックサムの変更理由、Example の変更有無など。\n", " - データセットが構築可能であることを確認します。\n", " - PR を送信します。\n", "\n", "注意: `~/tensorflow_datasets/download/` でダウンロードされたファイルを検査することも可能です。\n" ] }, { "cell_type": "markdown", "metadata": { "id": "GmeeOokMODg2" }, "source": [ "## 引用\n", "\n", "論文で `tensorflow-datasets` を使用する場合は、使用したデータセットの固有の引用([dataset catalog](https://www.tensorflow.org/datasets/catalog/overview) で確認できます)のほかに次の引用を含めてください。\n", "\n", "```\n", "@misc{TFDS,\n", " title = { {TensorFlow Datasets}, A collection of ready-to-use datasets},\n", " howpublished = {\\url{https://www.tensorflow.org/datasets}},\n", "}\n", "```" ] } ], "metadata": { "colab": { "collapsed_sections": [], "name": "overview.ipynb", "toc_visible": true }, "kernelspec": { "display_name": "Python 3", "name": "python3" } }, "nbformat": 4, "nbformat_minor": 0 }