{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "6XvCUmCEd4Dm"
},
"source": [
"# TensorFlow Datasets\n",
"\n",
"TFDS provides a collection of ready-to-use datasets for use with TensorFlow, Jax, and other Machine Learning frameworks.\n",
"\n",
"It handles downloading and preparing the data deterministically and constructing a `tf.data.Dataset` (or `np.array`).\n",
"\n",
"Note: Do not confuse [TFDS](https://www.tensorflow.org/datasets) (this library) with `tf.data` (TensorFlow API to build efficient data pipelines). TFDS is a high level wrapper around `tf.data`. If you're not familiar with this API, we encourage you to read [the official tf.data guide](https://www.tensorflow.org/guide/data) first.\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": [
"
"
],
"text/plain": [
"BenchmarkResult(stats= duration num_examples avg\n",
"first+lasts 0.300411 60032 199832.925534\n",
"first 0.013519 32 2367.040208\n",
"lasts 0.286892 60000 209137.961140, raw_stats= duration\n",
"start_time 2465.173582\n",
"first_batch_time 2465.187101\n",
"end_time 2465.473993\n",
"num_iter 1875.000000)"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"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": [
"* Do not forget to normalize the results per batch size with the `batch_size=` kwarg.\n",
"* In the summary, the first warmup batch is separated from the other ones to capture `tf.data.Dataset` extra setup time (e.g. buffers initialization,...).\n",
"* Notice how the second iteration is much faster due to [TFDS auto-caching](https://www.tensorflow.org/datasets/performances#auto-caching).\n",
"* `tfds.benchmark` returns a `tfds.core.BenchmarkResult` which can be inspected for further analysis."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "o-cuwvVbeb43"
},
"source": [
"### Build end-to-end pipeline\n",
"\n",
"To go further, you can look:\n",
"\n",
"* Our [end-to-end Keras example](https://www.tensorflow.org/datasets/keras_example) to see a full training pipeline (with batching, shuffling,...).\n",
"* Our [performance guide](https://www.tensorflow.org/datasets/performances) to improve the speed of your pipelines (tip: use `tfds.benchmark(ds)` to benchmark your datasets).\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "gTRTEQqscxAE"
},
"source": [
"## Visualization\n",
"\n",
"### tfds.as_dataframe\n",
"\n",
"`tf.data.Dataset` objects can be converted to [`pandas.DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html) with `tfds.as_dataframe` to be visualized on [Colab](https://colab.research.google.com).\n",
"\n",
"* Add the `tfds.core.DatasetInfo` as second argument of `tfds.as_dataframe` to visualize images, audio, texts, videos,...\n",
"* Use `ds.take(x)` to only display the first `x` examples. `pandas.DataFrame` will load the full dataset in-memory, and can be very expensive to display."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"execution": {
"iopub.execute_input": "2024-12-14T12:42:04.926139Z",
"iopub.status.busy": "2024-12-14T12:42:04.925607Z",
"iopub.status.idle": "2024-12-14T12:42:06.157855Z",
"shell.execute_reply": "2024-12-14T12:42:06.157137Z"
},
"id": "FKouwN_yVSGQ"
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2024-12-14 12:42:05.775782: W tensorflow/core/kernels/data/cache_dataset_ops.cc:914] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.\n"
]
},
{
"data": {
"text/html": [
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
image
\n",
"
label
\n",
"
\n",
" \n",
" \n",
"
\n",
"
0
\n",
"
\n",
"
4
\n",
"
\n",
"
\n",
"
1
\n",
"
\n",
"
1
\n",
"
\n",
"
\n",
"
2
\n",
"
\n",
"
0
\n",
"
\n",
"
\n",
"
3
\n",
"
\n",
"
7
\n",
"
\n",
" \n",
"
\n"
],
"text/plain": [
" image label\n",
"0 [[[0], [0], [0], [0], [0], [0], [0], [0], [0],... 4\n",
"1 [[[0], [0], [0], [0], [0], [0], [0], [0], [0],... 1\n",
"2 [[[0], [0], [0], [0], [0], [0], [0], [0], [0],... 0\n",
"3 [[[0], [0], [0], [0], [0], [0], [0], [0], [0],... 7"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"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` returns a `matplotlib.figure.Figure` (only image datasets supported now):"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"execution": {
"iopub.execute_input": "2024-12-14T12:42:06.161149Z",
"iopub.status.busy": "2024-12-14T12:42:06.160454Z",
"iopub.status.idle": "2024-12-14T12:42:07.144860Z",
"shell.execute_reply": "2024-12-14T12:42:07.144136Z"
},
"id": "DpE2FD56cSQR"
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2024-12-14 12:42:06.859043: W tensorflow/core/kernels/data/cache_dataset_ops.cc:914] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.\n"
]
},
{
"data": {
"image/png": "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I5p9//vfj2bf+973GnyvcuAJMwAAJCjMAACQoDADAECCwgwAAAkKMwAAJDgloxlNmjQpmlVUVESzk046KZpdeuml0ezOO+8sbGFAQfbdd99odthhhzX4ehs2bIhmS5YsafD1oBzMnTs373hqz3z84x9vquWUTJZl0WzdunXRbNq0aXnHp0+fHp2zYsWKgtfF//CEGQAAEhRmAABIUJgBACBBYQYAgASFGQAAEhRmAABIcKxcM0odGZPKXn755Wj2i1/8olFrAgrXr1+/aPaRj3ykwdf7wx/+EM3q6uoafD0oB2vWrMk7Pnz48Oic0aNHR7Prr78+mvXs2bPwhRXg3nvvjWa/+c1votkzzzwTzWpqahqzJArkCTMAACQozAAAkKAwAwBAgsIMAAAJCjMAACQozAAAkOBYuWZ0+OGHR7N33303mp111lnR7K233mrUmoDCnXHGGSW93j333FPS60E527BhQzS78847i8rgrzxhBgCABIUZAAASFGYAAEhQmAEAIEFhBgCABIUZAAASHCvXjDp27BjN3njjjWi2YsWKJlgN0FBTp06NZpdddlne8SzLonMeeeSRRq8JgKbnCTMAACQozAAAkKAwAwBAgsIMAAAJCjMAACQozAAAkOBYuWbUrVu33b0EoBHWrVsXzXr27NmMKwGgOXnCDAAACQozAAAkKMwAAJCgMAMAQILCDAAACQozAAAkKMwAAJCgMAMAQILCDAAACQozAAAkKMwAAJCgMAMAQILCDAAACQozAAAkKMwAAJCgMAMAQILCDAAACQozAAAkFFSYsyxr6nXAHqmcP/vl/N4pb+X62S/X9w2FfPYLKsy1tbWNXgy0ROX82S/n9055K9fPfrm+byjks5/LCqjV9fX1Yc2aNaGioiLkcrmSLA72ZFmWhdra2lBZWRlatSrP71yy7yk35b7v7XnKTUP2fEGFGQAAylX5/REaAAAaQGEGAIAEhRkAABIUZgAASFCY92B1dXWhb9++4Q9/+EPBcx566KEwePDgUF9f34QrA5rS8OHDw3333Vfw69etWxd69OgRXn/99SZcFdAUfK1vGRTmZvbd73435HK5cOWVV+7ytXfddVfo3bt3GDZs2E7Z+++/HwYPHhxyuVyorq7ePj5y5MjQtm3bMHPmzBKuGmioJ598MpxxxhmhsrIy5HK5MHv27ILmzZkzJ7zxxhth9OjR28emTZsWRowYETp37hxyuVzYuHHjDnO6desWxo4dGyZOnFjCdwA01NSpU8Ohhx4aOnToED7xiU+EP/3pT7uck+9r/fr168N5550XOnfuHLp06RIuvPDCsHnz5u25r/XNT2FuRgsWLAh33313GDRo0C5fm2VZmDJlSrjwwgvz5tdcc02orKzMm51//vlh8uTJjVor0DjvvvtuOOqoo8LUqVMbNG/y5Mlh/PjxO5wJumXLljBy5MjwjW98Izpv/PjxYebMmWH9+vVFrxko3s9//vNw1VVXhYkTJ4bnn38+HHXUUeG0004Lb775ZnRO7Gv9eeedF15++eUwb9688Jvf/CY8+eST4eKLL97hNb7WN7OMZlFbW5t97GMfy+bNm5edcMIJ2RVXXJF8/YIFC7JWrVplmzZt2imbO3duNmDAgOzll1/OQgjZCy+8sEO+cuXKLISQLV26tITvAChWCCGbNWvWLl/35ptvZrlcLlu8eHHe/PHHH89CCNmGDRvy5r17987uueeeRqwUKNZxxx2XTZgwYfv/3rZtW1ZZWZndfPPN0Tn5vtYvWbIkCyFkCxYs2D7229/+Nsvlctnq1au3j/la37w8YW4mEyZMCKeffno4+eSTC3r9/PnzQ79+/UJFRcUO42+88Ub4yle+Ev7jP/4jdOrUKe/cXr16hZ49e4b58+c3et1A83nqqadCp06dwuGHH17U/OOOO86+h92grq4uLFy4cIev8a1atQonn3xyeOaZZ6Lz8n2tf+aZZ0KXLl3CkCFDto+dfPLJoVWrVuGPf/zj9jFf65tXm929gHLws5/9LDz//PNhwYIFBc9ZuXLlTt9ykWVZOP/888NXv/rVMGTIkLBixYro/MrKyrBy5cpilwzsBitXrgw9e/Ys+p9lrqysDC+88EKJVwXsyrp168K2bdtCz549dxjv2bNneOWVV6Lz8n2tr6mpCT169NhhrE2bNqFr166hpqZmh3Ff65uPwtzEVq1aFa644oowb9680KFDh4Lnvffeezu9/oc//GGora0N11133S7nd+zYMWzZsqXB6wV2n3z7viHse2hZ7PmWw7dkNLGFCxeGN998Mxx99NGhTZs2oU2bNuGJJ54IkydPDm3atAnbtm3LO69bt25hw4YNO4w99thj4Zlnngnt27cPbdq0CX379g0hhDBkyJAwbty4HV67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AIAEhRkAABIUZgAASFCYAQAgQWEGAICEsjhWbuDAgdHshRdeKPn92rVrl3f82muvjc5JZS3B/Pnz846njsnZsGFDUy2HMjJq1Ki846lj2VJqa2uj2eOPPx7Nbr311rzjqWPlivXlL3+5wXM2b95c1L0qKiqi2aOPPpp3/J133inqXlDOBgwYUNLrxY59DCGECy64oKT3KgeeMAMAQILCDAAACQozAAAkKMwAAJCgMAMAQILCDAAACXvVsXKHHHJI3vHZs2eX/F6bNm2KZvX19XnH999//+icLMuKWkculyvpNVPHQe23337RbPjw4XnHb7rppuicyy67rPCFUdaOOOKIaBbb36nP/5/+9KdodvbZZ0ez1DFNzWnhwoXRbOrUqXnHX3/99eicf/7nf45m++67bzS79NJLoxnQMGPHji3p9aZNmxbNampqSnqvcuAJMwAAJCjMAACQoDADAECCwgwAAAkKMwAAJCjMAACQsFcdK3fxxRfnHY8dN7crkyZNimY/+MEPotl7772Xd/wzn/lMUetoTosXL45mf/7znxt8vYqKisYsB0IIIQwaNCiatWnT8N/GPvvZz0azDRs2NPh6zW3JkiXR7J/+6Z/yjo8ZMyY6p3v37tFsy5Yt0Sz2ex2QX2offuxjHyvpvVatWlXS65U7T5gBACBBYQYAgASFGQAAEhRmAABIUJgBACBBYQYAgIQWd6zc8ccfH82uvPLKkt5r8uTJ0ezNN99s8PV+9atfNWY5zaJv375FzcuyLO/4aaedFp3ToUOHaLZ169ai1sHeqaqqqqTXO+aYY6LZI488UtJ77Sm+/vWvFzXvtttuK/FKoHxdf/310axVq+KeYb711lt5xx944IGirkd+njADAECCwgwAAAkKMwAAJCjMAACQoDADAEBCizslI3U6RezUhbq6uuicKVOmRLMNGzYUvrC9xLnnnlvUvFwul3f84Ycfjs5xEgaFmjlzZjS7+uqrG3y93/3ud0Wt4ze/+U00i/1+sXbt2uic2bNnR7Nnn3224HX9rXHjxuUdHzx4cHROTU1NNPvmN79Z1DqAne2///4lv+btt9+ed3zTpk0lv1c584QZAAASFGYAAEhQmAEAIEFhBgCABIUZAAASFGYAAEhoccfK/fd//3c0O+KII/KO19bWRuesXr260Wvam3Tu3LmoeVmWlXgl8P9bsmRJNDv99NPzjt90003ROanPee/evRt8r5TYkYshhPDP//zP0eztt99u8L1CCGG//fbLO57ao6+99lo0O+qoo6LZiy++WPjCoEx8+ctfjmY9evQo6pqbN2+OZrfddltR16RhPGEGAIAEhRkAABIUZgAASFCYAQAgQWEGAIAEhRkAABJa3LFyqaORXnnllWZcSct14403RrMJEyYUdc3Y0X3Tp08v6nrwtz744INo9tvf/rZB4yGEUFFREc2KPVauS5cuecdTx8qlfj8bN25cNOvevXs0i90vda9jjz02mj3//PPRbNGiRXnHv/71r0fnzJs3L5rB3uCUU06JZq1aFfec8sMPP4xmqd8fKR1PmAEAIEFhBgCABIUZAAASFGYAAEhQmAEAIEFhBgCAhBZ3rByF+/a3v513/LrrrovOSR2BlXLPPffkHf/9739f1PWgKcWOQQwhhJdeeqmorBgnn3xyNLvkkkuKuubChQvzjt96663ROZ/97Gej2UknnRTNBg0alHf8P//zP6Nzjj766Gj2l7/8JZrBnmbw4MF5x88444zonNTxjim33HJLUfMoHU+YAQAgQWEGAIAEhRkAABIUZgAASFCYAQAgQWEGAIAEx8q1AKmj3s4777xo9r//9/9u8PVSHnvssWh27bXXFnVN2Nt985vfjGZf//rXo1nHjh2j2dNPPx3Nxo0bl3c8dWTb/fffH82OP/74aPbkk0/mHe/cuXN0zr777hvNoCX52Mc+lnd8v/32K/m9HnzwwZJfk4bxhBkAABIUZgAASFCYAQAgQWEGAIAEhRkAABKckrGHOPTQQ6PZt771rWj25S9/OZplWdbgdbz66qvRbPz48dHsww8/bPC9oKVp27ZtNJs9e3be8VGjRkXnpPbozJkzo9nll18ezd55551oVoyjjz66wXMWL14czZYsWdKY5UBZ+tSnPhXNXnrppWZcSfnyhBkAABIUZgAASFCYAQAgQWEGAIAEhRkAABIUZgAASHCsXDM68sgjo9mkSZOi2ciRI6NZMUfHzZo1K5pdffXV0ez1119v8L1gT3TggQdGs7PPPjuanXPOOQ2+5vvvvx+dk9r3qey9996LZsXYZ599otmll17a4OvdfPPN0cwRlOwtRo8e3Wz3uuWWW6LZnXfe2WzrKGeeMAMAQILCDAAACQozAAAkKMwAAJCgMAMAQILCDAAA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QwghvPjii+Gpp54Ko0aNis556qmnQqdOncLhhx++07V+/vOfh/Xr14f6+vrws5/9LGzdujWMGDFih9cdd9xx9j20ILE9Xyh7vvm02d0LKDezZ88OGzduDOeff37ydStXrgyVlZXJ10yfPj2cdtpp4aCDDtopq6ysDCtXrmzMUoFGuPbaa8OmTZvCgAEDQuvWrcO2bdvCTTfdFM4777zonJUrV4aePXvu9E+03n///eGcc84JBxxwQGjTpk3o1KlTmDVrVujbt+8Or6usrNzh2zSAPVtszxfKnm8+CnMzmz59ehg1atQuy/B7770XOnToEM1ff/318PDDD4f7778/b96xY8ewZcuWRq0VKN79998fZs6cGe67775wxBFHhOrq6nDllVeGysrKMG7cuLxzYvv++uuvDxs3bgyPPPJI6NatW5g9e3b40pe+FObPnx8GDhy4/XX2PbQsu/pavyv2fPNRmJvRypUrwyOPPBIeeOCBXb62W7duYdGiRdF8xowZ4YADDgj/8A//kDdfv3596N69e9FrBRrn61//erj22mu3/+T7wIEDw8qVK8PNN98cLczdunULGzZs2GFs2bJlYcqUKWHx4sXhiCOOCCGEcNRRR4X58+eHqVOnhrvuumv7a+17aFny7fmGsOebj+9hbkYzZswIPXr0CKeffvouX1tVVRVeeeWVvEdQZVkWZsyYEcaOHRvatm27U75169awbNmyUFVVVZJ1Aw23ZcuWnf6atXXr1skz0quqqkJNTc0OX0D/+vSokGstXrzYvocWJN+ebwh7vvkozM2kvr4+zJgxI4wbNy60abPrB/snnnhi2Lx5c3j55Zd3yh577LGwfPnycNFFF+Wd++yzz4b27duHoUOHNnrdQHHOOOOMcNNNN4UHH3wwrFixIsyaNSt8//vfD2eeeWZ0TlVVVejWrVt4+umnt48NGDAg9O3bN1xyySXhT3/6U1i2bFm47bbbwrx588LnP//57a/bsmVLWLhwYTj11FOb8m0BEZs3bw7V1dWhuro6hBDC8uXLQ3V1dXjttdeic/Lt+RD+5+z16urqsHTp0hBCCIsWLQrV1dU7HCFnzzez3X1MR7l4+OGHsxBC9uqrrxY850tf+lJ27bXX7jQ+ZsyYbNiwYdF5F198cXbJJZcUtU6gNDZt2pRdccUVWa9evbIOHTpkhx12WPYv//Iv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67UES5YsabJre8IMAAAJCjMAACQozAAAkKAwAwBAgsIMAAAJTslgB6mf0r3rrrui2bZt25piOVC2+vfvH80qKyujWZZlecdPPPHE6JwZM2YUvjCgaCNGjIhmP/7xj4u6ZmzPX3XVVdE5Tz31VFH3KmeeMAMAQILCDAAACQozAAAkKMwAAJCgMAMAQILCDAAACY6Va+HeeuutaLZu3bq84926dYvO6du3bzRr165dNHvvvfeiGdBwAwcOLOn1Fi1aVNLrAQ13ww03RLP27dsXdc0pU6bkHS/2mDry84QZAAASFGYAAEhQmAEAIEFhBgCABIUZAAASFGYAAEgoi2PlunTpEs0qKyuLuuaHH34Yzf785z8Xdc1idO/ePZqljo+Luf3226OZo+Og+ZT6WLnm/H0Jytmll14azY4//viirrly5cpo9n//7/8t6po0jCfMAACQoDADAECCwgwAAAkKMwAAJCjMAACQoDADAEDCXnWs3KhRo/KOp45K69evX1H3qquri2bf+ta38o7PnTs3OufFF18sah3/63/9r6LmxSxatKik14O9SWq/xY6BW758eXTOeeedF80GDBhQ+MIKMGXKlGh2zDHHRLMbbrihpOuAvUXPnj3zjv+f//N/onPatm0bzVLH1d56663RbNOmTdGM0vGEGQAAEhRmAABIUJgBACBBYQYAgASFGQAAEhRmAABI2KuOlfvVr36Vd7xNm9K/zXbt2kWzm266Ke/4xIkTo3N+/etfR7MHH3wwml1zzTXRLOaDDz6IZu+//36Drwd7k3vuuSeanXPOOdFsn332afC9crlcNMuyrMHXCyF+5GXq9ywgv1R/+PGPf5x3/JBDDinqXqljXadOnVrUNSkdT5gBACBBYQYAgASFGQAAEhRmAABIUJgBACBhrzolY/Xq1XnHi/2J1bVr10az1E+znnrqqXnHUz+l/oUvfKGorBhLly6NZn/84x9Leq+mcPTRR0ezgw8+OO947AQV+Hv/+q//Gs0++tGPRrM+ffrkHV+3bl10TuqUjF69ekWzAw88MJo99thjecdTJ3zU1tZGMyhnRx55ZDQ77bTTGny9Dz/8MJp9+9vfbvD1aD6eMAMAQILCDAAACQozAAAkKMwAAJCgMAMAQILCDAAACXvVsXI33nhj3vG77747OqdNm/h/goULF0aziy++OJp16NAh7/j8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",
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"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": [
"## Access the dataset metadata\n",
"\n",
"All builders include a `tfds.core.DatasetInfo` object containing the dataset metadata.\n",
"\n",
"It can be accessed through:\n",
"\n",
"* The `tfds.load` API:\n"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"execution": {
"iopub.execute_input": "2024-12-14T12:42:07.147922Z",
"iopub.status.busy": "2024-12-14T12:42:07.147344Z",
"iopub.status.idle": "2024-12-14T12:42:07.609154Z",
"shell.execute_reply": "2024-12-14T12:42:07.608367Z"
},
"id": "UgLgtcd1ljzt"
},
"outputs": [],
"source": [
"ds, info = tfds.load('mnist', with_info=True)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "XodyqNXrlxTM"
},
"source": [
"* The `tfds.core.DatasetBuilder` API:"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"execution": {
"iopub.execute_input": "2024-12-14T12:42:07.612570Z",
"iopub.status.busy": "2024-12-14T12:42:07.612038Z",
"iopub.status.idle": "2024-12-14T12:42:08.008414Z",
"shell.execute_reply": "2024-12-14T12:42:08.007595Z"
},
"id": "nmq97QkilxeL"
},
"outputs": [],
"source": [
"builder = tfds.builder('mnist')\n",
"info = builder.info"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "zMGOk_ZsmPeu"
},
"source": [
"The dataset info contains additional informations about the dataset (version, citation, homepage, description,...)."
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"execution": {
"iopub.execute_input": "2024-12-14T12:42:08.011773Z",
"iopub.status.busy": "2024-12-14T12:42:08.011185Z",
"iopub.status.idle": "2024-12-14T12:42:08.015475Z",
"shell.execute_reply": "2024-12-14T12:42:08.014814Z"
},
"id": "O-wLIKD-mZQT"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tfds.core.DatasetInfo(\n",
" name='mnist',\n",
" full_name='mnist/3.0.1',\n",
" description=\"\"\"\n",
" The MNIST database of handwritten digits.\n",
" \"\"\",\n",
" homepage='http://yann.lecun.com/exdb/mnist/',\n",
" data_dir='gs://tensorflow-datasets/datasets/mnist/3.0.1',\n",
" file_format=tfrecord,\n",
" download_size=11.06 MiB,\n",
" dataset_size=21.00 MiB,\n",
" features=FeaturesDict({\n",
" 'image': Image(shape=(28, 28, 1), dtype=uint8),\n",
" 'label': ClassLabel(shape=(), dtype=int64, num_classes=10),\n",
" }),\n",
" supervised_keys=('image', 'label'),\n",
" disable_shuffling=False,\n",
" splits={\n",
" 'test': ,\n",
" 'train': ,\n",
" },\n",
" citation=\"\"\"@article{lecun2010mnist,\n",
" title={MNIST handwritten digit database},\n",
" author={LeCun, Yann and Cortes, Corinna and Burges, CJ},\n",
" journal={ATT Labs [Online]. Available: http://yann.lecun.com/exdb/mnist},\n",
" volume={2},\n",
" year={2010}\n",
" }\"\"\",\n",
")\n"
]
}
],
"source": [
"print(info)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "1zvAfRtwnAFk"
},
"source": [
"### Features metadata (label names, image shape,...)\n",
"\n",
"Access the `tfds.features.FeatureDict`:"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"execution": {
"iopub.execute_input": "2024-12-14T12:42:08.018310Z",
"iopub.status.busy": "2024-12-14T12:42:08.017780Z",
"iopub.status.idle": "2024-12-14T12:42:08.022366Z",
"shell.execute_reply": "2024-12-14T12:42:08.021732Z"
},
"id": "RcyZXncqoFab"
},
"outputs": [
{
"data": {
"text/plain": [
"FeaturesDict({\n",
" 'image': Image(shape=(28, 28, 1), dtype=uint8),\n",
" 'label': ClassLabel(shape=(), dtype=int64, num_classes=10),\n",
"})"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"info.features"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "KAm9AV7loyw5"
},
"source": [
"Number of classes, label names:"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"execution": {
"iopub.execute_input": "2024-12-14T12:42:08.025203Z",
"iopub.status.busy": "2024-12-14T12:42:08.024690Z",
"iopub.status.idle": "2024-12-14T12:42:08.029083Z",
"shell.execute_reply": "2024-12-14T12:42:08.028430Z"
},
"id": "HhfzBH6qowpz"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"10\n",
"['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']\n",
"7\n",
"7\n"
]
}
],
"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": [
"Shapes, dtypes:"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"execution": {
"iopub.execute_input": "2024-12-14T12:42:08.031764Z",
"iopub.status.busy": "2024-12-14T12:42:08.031338Z",
"iopub.status.idle": "2024-12-14T12:42:08.039042Z",
"shell.execute_reply": "2024-12-14T12:42:08.038359Z"
},
"id": "SergV_wQowLY"
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"WARNING:absl:`FeatureConnector.dtype` is deprecated. Please change your code to use NumPy with the field `FeatureConnector.np_dtype` or use TensorFlow with the field `FeatureConnector.tf_dtype`.\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"WARNING:absl:`FeatureConnector.dtype` is deprecated. Please change your code to use NumPy with the field `FeatureConnector.np_dtype` or use TensorFlow with the field `FeatureConnector.tf_dtype`.\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'image': (28, 28, 1), 'label': ()}\n",
"{'image': tf.uint8, 'label': tf.int64}\n",
"(28, 28, 1)\n",
"\n"
]
}
],
"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": [
"### Split metadata (e.g. split names, number of examples,...)\n",
"\n",
"Access the `tfds.core.SplitDict`:"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"execution": {
"iopub.execute_input": "2024-12-14T12:42:08.041835Z",
"iopub.status.busy": "2024-12-14T12:42:08.041327Z",
"iopub.status.idle": "2024-12-14T12:42:08.044950Z",
"shell.execute_reply": "2024-12-14T12:42:08.044294Z"
},
"id": "FBbfwA8Sp4ax"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'test': , 'train': }\n"
]
}
],
"source": [
"print(info.splits)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "EVw1UVYa2HgN"
},
"source": [
"Available splits:"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"execution": {
"iopub.execute_input": "2024-12-14T12:42:08.047658Z",
"iopub.status.busy": "2024-12-14T12:42:08.047126Z",
"iopub.status.idle": "2024-12-14T12:42:08.050901Z",
"shell.execute_reply": "2024-12-14T12:42:08.050227Z"
},
"id": "fRBieOOquDzX"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['test', 'train']\n"
]
}
],
"source": [
"print(list(info.splits.keys()))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "iHW0VfA0t3dO"
},
"source": [
"Get info on individual split:"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"execution": {
"iopub.execute_input": "2024-12-14T12:42:08.053692Z",
"iopub.status.busy": "2024-12-14T12:42:08.053151Z",
"iopub.status.idle": "2024-12-14T12:42:08.057249Z",
"shell.execute_reply": "2024-12-14T12:42:08.056605Z"
},
"id": "-h_OSpRsqKpP"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"60000\n",
"['mnist-train.tfrecord-00000-of-00001']\n",
"1\n"
]
}
],
"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": [
"It also works with the subsplit API:"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"execution": {
"iopub.execute_input": "2024-12-14T12:42:08.060009Z",
"iopub.status.busy": "2024-12-14T12:42:08.059502Z",
"iopub.status.idle": "2024-12-14T12:42:08.063597Z",
"shell.execute_reply": "2024-12-14T12:42:08.062947Z"
},
"id": "HO5irBZ3uIzQ"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"36000\n",
"[FileInstruction(filename='gs://tensorflow-datasets/datasets/mnist/3.0.1/mnist-train.tfrecord-00000-of-00001', skip=9000, take=36000, examples_in_shard=60000)]\n"
]
}
],
"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": [
"## Troubleshooting\n",
"\n",
"### Manual download (if download fails)\n",
"\n",
"If download fails for some reason (e.g. offline,...). You can always manually download the data yourself and place it in the `manual_dir` (defaults to `~/tensorflow_datasets/downloads/manual/`.\n",
"\n",
"To find out which urls to download, look into:\n",
"\n",
" * For new datasets (implemented as folder): [`tensorflow_datasets/`](https://github.com/tensorflow/datasets/tree/master/tensorflow_datasets/)`//checksums.tsv`. For example: [`tensorflow_datasets/datasets/bool_q/checksums.tsv`](https://github.com/tensorflow/datasets/blob/master/tensorflow_datasets/datasets/bool_q/checksums.tsv).\n",
"\n",
" You can find the dataset source location in [our catalog](https://www.tensorflow.org/datasets/catalog/overview).\n",
" * For old datasets: [`tensorflow_datasets/url_checksums/.txt`](https://github.com/tensorflow/datasets/tree/master/tensorflow_datasets/url_checksums)\n",
"\n",
"### Fixing `NonMatchingChecksumError`\n",
"\n",
"TFDS ensure determinism by validating the checksums of downloaded urls.\n",
"If `NonMatchingChecksumError` is raised, might indicate:\n",
"\n",
" * The website may be down (e.g. `503 status code`). Please check the url.\n",
" * For Google Drive URLs, try again later as Drive sometimes rejects downloads when too many people access the same URL. See [bug](https://github.com/tensorflow/datasets/issues/1482)\n",
" * The original datasets files may have been updated. In this case the TFDS dataset builder should be updated. Please open a new Github issue or PR:\n",
" * Register the new checksums with `tfds build --register_checksums`\n",
" * Eventually update the dataset generation code.\n",
" * Update the dataset `VERSION`\n",
" * Update the dataset `RELEASE_NOTES`: What caused the checksums to change ? Did some examples changed ?\n",
" * Make sure the dataset can still be built.\n",
" * Send us a PR\n",
"\n",
"Note: You can also inspect the downloaded file in `~/tensorflow_datasets/download/`.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "GmeeOokMODg2"
},
"source": [
"## Citation\n",
"\n",
"If you're using `tensorflow-datasets` for a paper, please include the following citation, in addition to any citation specific to the used datasets (which can be found in the [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": "tensorflow/datasets",
"private_outputs": true,
"provenance": [],
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3",
"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.9.21"
}
},
"nbformat": 4,
"nbformat_minor": 0
}