Skip to content

Instantly share code, notes, and snippets.

@jonkelly
Created July 3, 2019 16:52
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jonkelly/fb2f2b45553ed541238e23e8509af69c to your computer and use it in GitHub Desktop.
Save jonkelly/fb2f2b45553ed541238e23e8509af69c to your computer and use it in GitHub Desktop.
Loading_S3_data_into_TensorFlow.ipynb
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "Loading_S3_data_into_TensorFlow.ipynb",
"version": "0.3.2",
"provenance": [],
"collapsed_sections": [],
"toc_visible": true,
"include_colab_link": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/jonkelly/fb2f2b45553ed541238e23e8509af69c/loading_s3_data_into_tensorflow.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "dtIb-cz0YMrw",
"colab_type": "text"
},
"source": [
"# Introduction\n",
"\n",
"In this exercise, we will show how to load data from S3 into Tensorflow for training.\n",
"\n",
"We will provide implementations for both Tensorflow\"s built-in S3 functionality, and for the Boto3 library. \n",
"\n",
"We\"ll use the [MNIST](http://yann.lecun.com/exdb/mnist/) dataset for speed and simplicity.\n",
"\n",
"In Part II we'll review the actual training, but for now we will focus on loading and preprocessing the dataset.\n",
"\n",
"If at any point you have questions, comments, concerns, corrections, complaints, consternation, conniptions, compliments, or other things that may or may not start with the letter 'c', you can reach me at jkelly@swiftstack.com \n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "xgnhIyG6QcTF",
"colab_type": "text"
},
"source": [
"# Prerequisites\n",
"\n",
"You will need access to an S3-compatible object store. Fortunately, one is provided for you here, but you are also free to use your own Object Store if you prefer, and you can find a quick tutorial on setting one up using a docker image [here](https://hub.docker.com/r/swiftstack/picoswiftstack), and instructions for downloading the MNIST dataset below.\n",
"\n",
"You will also need either a google account to clone this page, if you wish to run it in colab (recommended), or a system with Python, Jupyter, and the libraries listed in the \"Imports\" section installed. The code is tested against Python 3, and Tensorflow 1.x, and I am not certain whether it will function properly on Python 2/TensorFlow 2."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Q2uOMzSprzgl",
"colab_type": "text"
},
"source": [
"# Imports"
]
},
{
"cell_type": "code",
"metadata": {
"id": "bU3WSCT-r0_-",
"colab_type": "code",
"outputId": "9e2f1624-d9d8-495c-8c82-286e59bb1f78",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 34
}
},
"source": [
"import boto3\n",
"import botocore\n",
"import os, re, math, json, shutil, pprint\n",
"import PIL.Image, PIL.ImageFont, PIL.ImageDraw\n",
"import numpy as np\n",
"from io import StringIO\n",
"import tensorflow as tf\n",
"from matplotlib import pyplot as plt\n",
"from tensorflow.python.platform import tf_logging\n",
"print(\"Tensorflow version \" + tf.__version__)"
],
"execution_count": 0,
"outputs": [
{
"output_type": "stream",
"text": [
"Tensorflow version 1.14.0-rc1\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "bxReF9bq4X9D",
"colab_type": "text"
},
"source": [
"## Helper Functions for Visualization: RUN THIS CODE BLOCK!\n",
"\n",
"From https://github.com/GoogleCloudPlatform/training-data-analyst\n",
"\n",
"No need to read this section. It is required to visualize what we are doing, but contains nothing relevant to our interests here."
]
},
{
"cell_type": "code",
"metadata": {
"id": "_TcAqXd54YIS",
"colab_type": "code",
"cellView": "form",
"colab": {}
},
"source": [
"#@title visualization utilities [RUN ME]\n",
"\"\"\"\n",
"This cell contains helper functions used for visualization\n",
"and downloads only. You can skip reading it. There is very\n",
"little useful Keras/Tensorflow code here.\n",
"\"\"\"\n",
"\n",
"# Matplotlib config\n",
"plt.rc('image', cmap='gray_r')\n",
"plt.rc('grid', linewidth=0)\n",
"plt.rc('xtick', top=False, bottom=False, labelsize='large')\n",
"plt.rc('ytick', left=False, right=False, labelsize='large')\n",
"plt.rc('axes', facecolor='F8F8F8', titlesize=\"large\", edgecolor='white')\n",
"plt.rc('text', color='a8151a')\n",
"plt.rc('figure', facecolor='F0F0F0')# Matplotlib fonts\n",
"MATPLOTLIB_FONT_DIR = os.path.join(os.path.dirname(plt.__file__), \"mpl-data/fonts/ttf\")\n",
"\n",
"# pull a batch from the datasets. This code is not very nice, it gets much better in eager mode (TODO)\n",
"def dataset_to_numpy_util(training_dataset, validation_dataset, N):\n",
" \n",
" # get one batch from each: 10000 validation digits, N training digits\n",
" unbatched_train_ds = training_dataset.apply(tf.data.experimental.unbatch())\n",
" v_images, v_labels = validation_dataset.make_one_shot_iterator().get_next()\n",
" t_images, t_labels = unbatched_train_ds.batch(N).make_one_shot_iterator().get_next()\n",
" \n",
" # Run once, get one batch. Session.run returns numpy results\n",
" with tf.Session() as ses:\n",
" (validation_digits, validation_labels,\n",
" training_digits, training_labels) = ses.run([v_images, v_labels, t_images, t_labels])\n",
" \n",
" # these were one-hot encoded in the dataset\n",
" validation_labels = np.argmax(validation_labels, axis=1)\n",
" training_labels = np.argmax(training_labels, axis=1)\n",
" \n",
" return (training_digits, training_labels,\n",
" validation_digits, validation_labels)\n",
"\n",
"# create digits from local fonts for testing\n",
"def create_digits_from_local_fonts(n):\n",
" font_labels = []\n",
" img = PIL.Image.new('LA', (28*n, 28), color = (0,255)) # format 'LA': black in channel 0, alpha in channel 1\n",
" font1 = PIL.ImageFont.truetype(os.path.join(MATPLOTLIB_FONT_DIR, 'DejaVuSansMono-Oblique.ttf'), 25)\n",
" font2 = PIL.ImageFont.truetype(os.path.join(MATPLOTLIB_FONT_DIR, 'STIXGeneral.ttf'), 25)\n",
" d = PIL.ImageDraw.Draw(img)\n",
" for i in range(n):\n",
" font_labels.append(i%10)\n",
" d.text((7+i*28,0 if i<10 else -4), str(i%10), fill=(255,255), font=font1 if i<10 else font2)\n",
" font_digits = np.array(img.getdata(), np.float32)[:,0] / 255.0 # black in channel 0, alpha in channel 1 (discarded)\n",
" font_digits = np.reshape(np.stack(np.split(np.reshape(font_digits, [28, 28*n]), n, axis=1), axis=0), [n, 28*28])\n",
" return font_digits, font_labels\n",
"\n",
"# utility to display a row of digits with their predictions\n",
"def display_digits(digits, predictions, labels, title, n):\n",
" plt.figure(figsize=(13,3))\n",
" digits = np.reshape(digits, [n, 28, 28])\n",
" digits = np.swapaxes(digits, 0, 1)\n",
" digits = np.reshape(digits, [28, 28*n])\n",
" plt.yticks([])\n",
" plt.xticks([28*x+14 for x in range(n)], predictions)\n",
" for i,t in enumerate(plt.gca().xaxis.get_ticklabels()):\n",
" if predictions[i] != labels[i]: t.set_color('red') # bad predictions in red\n",
" plt.imshow(digits)\n",
" plt.grid(None)\n",
" plt.title(title)\n",
" \n",
"# utility to display multiple rows of digits, sorted by unrecognized/recognized status\n",
"def display_top_unrecognized(digits, predictions, labels, n, lines):\n",
" idx = np.argsort(predictions==labels) # sort order: unrecognized first\n",
" for i in range(lines):\n",
" display_digits(digits[idx][i*n:(i+1)*n], predictions[idx][i*n:(i+1)*n], labels[idx][i*n:(i+1)*n],\n",
" \"{} sample validation digits out of {} with bad predictions in red and sorted first\".format(n*lines, len(digits)) if i==0 else \"\", n)\n",
" \n",
"# utility to display training and validation curves\n",
"def display_training_curves(training, validation, title, subplot):\n",
" if subplot%10==1: # set up the subplots on the first call\n",
" plt.subplots(figsize=(10,10), facecolor='#F0F0F0')\n",
" plt.tight_layout()\n",
" ax = plt.subplot(subplot)\n",
" ax.grid(linewidth=1, color='white')\n",
" ax.plot(training)\n",
" ax.plot(validation)\n",
" ax.set_title('model '+ title)\n",
" ax.set_ylabel(title)\n",
" ax.set_xlabel('epoch')\n",
" ax.legend(['train', 'valid.'])"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "7jVS6kchox7c",
"colab_type": "text"
},
"source": [
"# Set environment variables\n",
"\n",
"Using os.environ for pythonicalness. You could use %env in jupyter/colab, or shell environment variables from the CLI if you wanted. The preset values will pull the data from a read-only account on a public SwiftStack sandbox.\n",
"\n",
"From the tensorflow doc for reference: \n",
"\n",
"```\n",
"AWS_ACCESS_KEY_ID=XXXXX # Credentials only needed if connecting to a private endpoint\n",
"AWS_SECRET_ACCESS_KEY=XXXXX\n",
"AWS_REGION=us-east-1 # Region for the S3 bucket, this is not always needed. Default is us-east-1.\n",
"S3_ENDPOINT=s3.us-east-1.amazonaws.com # The S3 API Endpoint to connect to. This is specified in a HOST:PORT format.\n",
"S3_USE_HTTPS=1 # Whether or not to use HTTPS. Disable with 0.\n",
"S3_VERIFY_SSL=1 # If HTTPS is used, controls if SSL should be enabled. Disable with 0.\n",
"```\n",
"\n",
"Full Tensorflow S3 documentation can be found [here](https://github.com/tensorflow/examples/blob/master/community/en/docs/deploy/s3.md)\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "WhaiRSu4ZDiN",
"colab_type": "code",
"colab": {}
},
"source": [
"# set environment variable variables\n",
"ENDPOINT = \"tellus.swiftstack.com\"\n",
"ACCESS_KEY = \"ai-training-ro:AUTH_ai-training\"\n",
"SECRET_KEY = \"0a10d895e686c7baa0419fa0288bf95e\"\n",
"REGION_NAME = \"us-east-1\"\n",
"\n",
"# set environment variables\n",
"os.environ[\"AWS_ACCESS_KEY_ID\"] = ACCESS_KEY\n",
"os.environ[\"AWS_SECRET_ACCESS_KEY\"] = SECRET_KEY\n",
"os.environ[\"AWS_REGION\"] = REGION_NAME\n",
"os.environ[\"S3_ENDPOINT\"] = ENDPOINT\n",
"#os.environ[\"S3_USE_HTTPS\"] = \"1\"\n",
"#os.environ[\"S3_VERIFY_SSL\"] = \"1\""
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "nttx8QwP3oCN",
"colab_type": "text"
},
"source": [
"# Prepare the dataset: S3 Implementation\n",
"\n",
"Before the next step, we need to ensure that we have the mnist dataset present in a bucket on the S3 target. Files can be downloaded [here](http://yann.lecun.com/exdb/mnist/)\n",
"\n",
"Files are downloaded in .gz format, but this script assumes they have been uncompressed. The following script can be run locally to download and extract the files:\n",
"\n",
"```\n",
"mkdir mnist\n",
"cd mnist/\n",
"wget http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz\n",
"wget http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz\n",
"wget http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz\n",
"wget http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz\n",
"gunzip *\n",
"```\n",
"\n",
"Then upload the files to your S3 compatible storage of choice! Here you can find a [GUI S3 client](https://www.swiftstack.com/downloads) as well as a [docker-based object storage service container](https://hub.docker.com/r/swiftstack/picoswiftstack) if needed.\n",
"\n",
"In this example, I created a bucket called 'mnist' and uploaded the files there. If you use a different bucket name, or different filenames, you'll need to change the variables below to reflect that.\n",
"\n",
"This workflow is based on this [MNIST on GPU/TPU using tf.Keras and tf.data.Dataset tutorial](https://colab.research.google.com/github/tensorflow/tpu/blob/master/tools/colab/keras_mnist_tpu.ipynb) which is in turn based on the [Tensorflow Data Input Pipline Performance Guide](https://www.tensorflow.org/guide/performance/datasets). This workflow has been gratuitously commented for comprehensibility. \n",
"\n",
"In essence, what we need to do here is to extract the labels and images from the data files and convert them into a format that TensorFlow can use for training and validation. Tensorflow may look a bit odd if you are used to regular imperative python, since it isn't designed to be executed in real time, but rather to assemble a [graph](https://www.tensorflow.org/guide/graphs) representing operations to be performed once an actual session is created. The five functions we are defining will be compiled by Tensorflow into a pipeline for loading and transforming our images and labels, and when we actually call the *get_training_dataset* or *get_validation_dataset* function, the data will be fetched via the S3 API and processed. \n",
"\n",
"If you are unfamiliar with one-hot encoding, and want to understand what's going on in the 'read_label' function, you can find a brief overview [here](https://www.kaggle.com/dansbecker/using-categorical-data-with-one-hot-encoding). You can read just the intro and skip the rest for the purposes of this exercise.\n",
"\n",
"#####Read this part if you care about what is inside these files, otherwise skip ahead to the next code block\n",
"\n",
"\n",
"The exact format of these files is specified [here](http://yann.lecun.com/exdb/mnist/). To put it succinctly, each of these files is a stream of bytes that represents the label or image data. The _labels_ files contain a header, followed by a stream of bytes (ranging in value from 0-9) with each byte being the number depicted in the corresponding image in the corresponding _images_ file. The _images_ files contain a header followed by a stream of image headers and data: two 32-bit integers representing number of rows and columns in the following image followed by one single-byte unsigned integer per pixel representing that pixel's grayscale value.\n",
"\n",
"For example, if the first 'real' (non-header) byte of the _labels_ file is '5', then the corresponding first entry in the _images_ file will be a picture of a '5.' That picture will actually be two 32-bit bytes representing rows and columns, followed by the individual pixel data. This specific dataset uses 28x28 grayscale images, so the first two 32-bit numbers should be '28 and '28' and that the following 784 bytes (28x28 = 784) each represent a grayscale pixel that makes up that image. The pixels are organized row-wise, so the first pixel would be the upper-left-most pixel, the second would be top row second from the left, etc.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "fQU2nDJX3nli",
"colab_type": "code",
"colab": {}
},
"source": [
"BATCH_SIZE = 128\n",
"\n",
"# Edit these if needed: point these at the MNIST dataset\n",
"training_images_file = \"s3://mnist/train-images-idx3-ubyte\"\n",
"training_labels_file = \"s3://mnist/train-labels-idx1-ubyte\"\n",
"validation_images_file = \"s3://mnist/t10k-images-idx3-ubyte\"\n",
"validation_labels_file = \"s3://mnist/t10k-labels-idx1-ubyte\"\n",
"\n",
"\"\"\"\n",
"read_label:\n",
"This function reads the label data as individual bytes, converts each byte into \n",
"an 8-bit unsigned integer, reshapes that integer into zero-dimensional tensor\n",
"(a scalar) and then one-hot encodes that value (see comments below for more details)\n",
"\n",
"\"\"\"\n",
"def read_label(tf_bytestring):\n",
" label = tf.decode_raw(tf_bytestring, tf.uint8)\n",
" label = tf.reshape(label, [])\n",
" \"\"\" \n",
" Convert the scalar into \"one-hot\" encoding.\n",
" This effectively turns numerical integer data into binary class data.\n",
" Think of a 10-bit bitfield where the bit corresponding to the class \n",
" is set to 1 and all other to 0, so for the number 5, it would be\n",
" 0b0000010000 (0-indexed array, so the first bit = 0, 6th bit = 5)\n",
" as an additional example, 2 would be 0b0010000000\n",
" \"\"\"\n",
" label = tf.one_hot(label, 10)\n",
" return label\n",
"\n",
"\"\"\"\n",
"read_image:\n",
"This function reads a bunch of bytes representing grayscale values as \n",
"8-bit unsigned integers, then rescales them so instead of a 0-255 integer value\n",
"they are a 0-1 float value. It creates a tensor consisting of 784 of those\n",
"32-bit floats that represent one 28x28 image.\n",
"\"\"\"\n",
"def read_image(tf_bytestring):\n",
" image = tf.decode_raw(tf_bytestring, tf.uint8)\n",
" image = tf.cast(image, tf.float32)/256.0\n",
" image = tf.reshape(image, [28*28])\n",
" return image\n",
"\n",
"\"\"\"\n",
"load_dataset:\n",
"Call the read_label and read_image functions we defined above to 'map' the data\n",
"in the image_file and the label_file into useable images and labels. For those not\n",
"familiar with 'Map', you can think of this operation as dividing the files up \n",
"into appropriately-sized 'chunks' (1 byte for labels, 784 bytes for images) and running\n",
"the function we specify (read_label for labels, read_images for images) against each \n",
"of those chunks and returing a list/array of the results. For a deeper and more accurate\n",
"summary, see: https://en.wikipedia.org/wiki/Map_(higher-order_function)\n",
"\"\"\" \n",
"def load_dataset(image_file, label_file):\n",
" imagedataset = tf.data.FixedLengthRecordDataset(image_file, 28*28, header_bytes=16)\n",
" imagedataset = imagedataset.map(read_image, num_parallel_calls=16)\n",
" labelsdataset = tf.data.FixedLengthRecordDataset(label_file, 1, header_bytes=8)\n",
" labelsdataset = labelsdataset.map(read_label, num_parallel_calls=16)\n",
" dataset = tf.data.Dataset.zip((imagedataset, labelsdataset))\n",
" return dataset \n",
"\n",
"\"\"\"\n",
"get_training_dataset:\n",
"Creates a dataset consisting of 5,000 random image/label combinations\n",
"While one 5,000-item batch is training, the next batch will automatically be\n",
"prefetched.\n",
"This is not executed in an imperative manner, but rather you can think of it as \n",
"creating a data pipeline. You can see this most easily by running the\n",
"visualization code in the next block repeatedly. You'll notice the output is \n",
"different each time, even though you haven't specified to load more data,\n",
"shuffle the data, etc.\n",
"\"\"\" \n",
"def get_training_dataset(image_file, label_file, batch_size):\n",
" dataset = load_dataset(image_file, label_file)\n",
" dataset = dataset.cache() # this small dataset can be entirely cached in RAM, for TPU this is important to get good performance from such a small dataset\n",
" dataset = dataset.shuffle(5000, reshuffle_each_iteration=True)\n",
" dataset = dataset.repeat() # Mandatory for Keras for now\n",
" dataset = dataset.batch(batch_size, drop_remainder=True) # drop_remainder is important on TPU, batch size must be fixed\n",
" dataset = dataset.prefetch(10) # fetch next batches while training on the current one\n",
" return dataset\n",
" \n",
"\"\"\"\n",
"get_validation_dataset:\n",
"Creates a dataset consisting of all 10,000 validation image/label combinations \n",
"\"\"\"\n",
"def get_validation_dataset(image_file, label_file):\n",
" dataset = load_dataset(image_file, label_file)\n",
" dataset = dataset.cache() # this small dataset can be entirely cached in RAM, for TPU this is important to get good performance from such a small dataset\n",
" dataset = dataset.batch(10000, drop_remainder=True) # 10000 items in eval dataset, all in one batch\n",
" dataset = dataset.repeat() # Mandatory for Keras for now\n",
" return dataset\n",
"\n",
"# instantiate the datasets\n",
"training_dataset = get_training_dataset(training_images_file, training_labels_file, BATCH_SIZE)\n",
"validation_dataset = get_validation_dataset(validation_images_file, validation_labels_file)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "avgiWlN0sPss",
"colab_type": "text"
},
"source": [
"## View Processed Data\n",
"\n",
"Note as mentioned in the code comments above, that the *get_training_dataset* function creates a data pipeline that will shuffle and produce 5000 random data-pairs each time you retrieve data from the corresponding variable.\n",
"\n",
"Since the *get_validation_dataset* does NOT shuffle, and fetches all 10,000 validation item-pairs, it will always be ordered the same way.\n",
"\n",
"You can observe this behavior by running the following codeblock repeatedly: you will see that the training data changes with each run, but the validation data remains constant.\n",
"\n",
"If you were to comment out the *dataset.shuffle* line from the *get_training_dataset* you would see the same behavior there."
]
},
{
"cell_type": "code",
"metadata": {
"id": "m4lW_BxLsP5H",
"colab_type": "code",
"outputId": "3e3dd94e-594c-4e32-9a82-5cd46b5e3fc7",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 245
}
},
"source": [
"# Visualize a sample of our dataset: the images and their associated labels\n",
"N = 24\n",
"(training_digits, training_labels,\n",
" validation_digits, validation_labels) = dataset_to_numpy_util(training_dataset, validation_dataset, N)\n",
"display_digits(training_digits, training_labels, training_labels, \"training digits and their labels\", N)\n",
"display_digits(validation_digits[:N], validation_labels[:N], validation_labels[:N], \"validation digits and their labels\", N)\n",
"font_digits, font_labels = create_digits_from_local_fonts(N)"
],
"execution_count": 0,
"outputs": [
{
"output_type": "stream",
"text": [
"WARNING: Logging before flag parsing goes to stderr.\n",
"W0626 16:50:58.377922 140642584397696 deprecation.py:323] From <ipython-input-2-d9829cc3ee7d>:22: DatasetV1.make_one_shot_iterator (from tensorflow.python.data.ops.dataset_ops) is deprecated and will be removed in a future version.\n",
"Instructions for updating:\n",
"Use `for ... in dataset:` to iterate over a dataset. If using `tf.estimator`, return the `Dataset` object directly from your input function. As a last resort, you can use `tf.compat.v1.data.make_one_shot_iterator(dataset)`.\n"
],
"name": "stderr"
},
{
"output_type": "display_data",
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 936x216 with 1 Axes>"
]
},
"metadata": {
"tags": []
}
},
{
"output_type": "display_data",
"data": {
"image/png": "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\nUExdDIC6d+8u2U7HO3fuFB8+eJ4XRVxLnDt3TnRM+Pj4kI+PjyT1Edi2bRsB0mYla476C0y3bdsm\nm51//etfLY7JFy9eJEtLS+I4ThKhTkQUExOjdFMjwaO+e/duhXzqcmhOZdy7d4/69u1LAFTeKbvD\nCPWioiJxu225BE19oZ6WliY+tdc/hHj4qqoq8bX09HQxj/GcOXNo3rx57UrVZGtrS7a2tgRAttzh\nPXv2VBBJP/74I/34448tphJUFx9//LGCUL969arkNuo/VS9dulTy8lXF2tqaDAwM1LoteENqa2sp\nODiYOI6jZcuWSV7+qlWriOM40tHRoVmzZtH58+dp8uTJsgv1s2fPkrGxsfg9GxkZkZGRUavTKDZH\ncnIyGRsbqyzUa2pqaNKkSQSA7Ozs6Oeff26zbWGXWSGGteG4k5CQQBkZGZSdnU0hISHEcXXp5OQU\n6ER1WV/k8mBfunSJrKysiOd5lT241tbWZGVlJXmaW4GOKtSvXbtG165dI0tLS+rTp4/k5ScnJ4v9\ntzlvsJQITgXhHmVoaCj5/UHw8nIcRykpKSqNF9u2bRMzs8yfP5/mz58veZ0AUFJSkqTlKuP27dui\nc8Pf31+StIjNIaSZDQkJaTR7fufOHXHmkOd5+uabbySzm52dLWaBaerw9PSU3ZMucOLECVGkDx06\nVOUdSzuEUK+pqRG3CpYyx3RDVNnkICgoiBYsWCCKmqaOtk7jnzp1SvReyynU161b12jDo/p/K3tt\n3rx5stRFGfV3hZXrAWHjxo0E1O3W2NRGT3KzadMmAupSNmqaS5cukb6+PnEcJ/mioQsXLih8n6+9\n9pp4UxOOd955RzJ7AkuXLhUHXAMDAzp+/Lgkubwb4uTkRM7Ozs3+jq5cuUKzZs0S05wCaPcunXfv\n3lWIj3311Vdpz549ohdw6dKl4k1OCEORY3F6Q4TdBlubwlVVtm/fLj50tPQgIGzKJMc6COH3VP/G\nLodQX7duHe3YsUOlzZ0EsrKyKDAwkAIDAyWN365P/b0T1CHUT5w4ofDgDUi/2SFRXRjKa6+9RhzH\nkaOjIzk6OtKMGTOUjonr168nFxcX0Qsvt1BvT9ipKty7d0/cQKtr165tXovWGh4+fEh2dnaiWD98\n+DDt3buX9u7dS7a2tmKK17bsOtsa6nvYw8LCJMuZ3hRCOFF5eTlFRESQgYGB+HDwyy+/qFxOhxDq\n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\n",
"text/plain": [
"<Figure size 936x216 with 1 Axes>"
]
},
"metadata": {
"tags": []
}
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "1-nFyPZqMJkl",
"colab_type": "text"
},
"source": [
"## Prepare the dataset: Download files with Boto3\n",
"\n",
"We're going to reuse the functions from our S3 exercise, since they don't need to change, but this time we're going to retrieve the dataset using the Boto3 library rather than native S3 functionality. This method will download data to disk rather than loading directly into memory, which can be useful if you want to keep the data files around for reuse.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ZVpkyLw2TghG",
"colab_type": "text"
},
"source": [
"# Boto3"
]
},
{
"cell_type": "code",
"metadata": {
"id": "luuQ9ekVXF5f",
"colab_type": "code",
"colab": {}
},
"source": [
"# B3 wants the https://, note that trying to use that with S3 will not work\n",
"B3_ENDPOINT = \"https://tellus.swiftstack.com\"\n",
"# Edit these if needed: point these at the MNIST dataset\n",
"B3_BUCKET = \"mnist\"\n",
"b3_training_images_file = \"train-images-idx3-ubyte\"\n",
"b3_training_labels_file = \"train-labels-idx1-ubyte\"\n",
"b3_validation_images_file = \"t10k-images-idx3-ubyte\"\n",
"b3_validation_labels_file = \"t10k-labels-idx1-ubyte\"\n",
"\n",
"\n",
"# build the parameters for creating the s3 resource\n",
"kwargs = {\"endpoint_url\": B3_ENDPOINT, \"aws_access_key_id\": ACCESS_KEY, \"aws_secret_access_key\": SECRET_KEY, \"region_name\": REGION_NAME}\n",
"\n",
"# create the s3 resource\n",
"s3 = boto3.resource(\"s3\", **kwargs)\n",
"\n",
"# create a bucket resource from our s3 resource (referring to an existing bucket)\n",
"mnistbucket = s3.Bucket(B3_BUCKET)\n",
"\n",
"\"\"\"\n",
"download files, first variable is remote filename, second is local filename\n",
"both are required, since we don't want to rename the file, we just use the same name twice (source and destination)\n",
"first we check to see if the file already exists so we don't download if we don't have to\n",
"\"\"\"\n",
"\n",
"if(not os.path.isfile(b3_training_images_file)):\n",
" mnistbucket.download_file(b3_training_images_file, b3_training_images_file)\n",
"if(not os.path.isfile(b3_training_labels_file)): \n",
" mnistbucket.download_file(b3_training_labels_file, b3_training_labels_file)\n",
"if(not os.path.isfile(b3_validation_images_file)):\n",
" mnistbucket.download_file(b3_validation_images_file, b3_validation_images_file)\n",
"if(not os.path.isfile(b3_validation_labels_file)):\n",
" mnistbucket.download_file(b3_validation_labels_file, b3_validation_labels_file)\n",
"\n",
"# instantiate the datasets--reusing previously defined functions\n",
"# if you encounter errors, make sure you run the preceeding code blocks\n",
"b3_training_dataset = get_training_dataset(b3_training_images_file, b3_training_labels_file, BATCH_SIZE)\n",
"b3_validation_dataset = get_validation_dataset(b3_validation_images_file, b3_validation_labels_file)\n",
"\n",
"# You can uncomment the following command if you want to see the downloaded files on disk\n",
"#!ls -l\n",
"\n",
"# If you need to remove the local files to force redownload for whatever reason\n",
"#!rm -f *ubyte"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "wOaRM7h_gSOb",
"colab_type": "text"
},
"source": [
"### View Boto3 Processed Data"
]
},
{
"cell_type": "code",
"metadata": {
"id": "Z_tR5ehogSTj",
"colab_type": "code",
"outputId": "1416ae7d-489d-4469-f220-3a4d23fa01e9",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 177
}
},
"source": [
"# Visualize a sample of our dataset: the images and their associated labels\n",
"N = 24\n",
"(training_digits, training_labels,\n",
" validation_digits, validation_labels) = dataset_to_numpy_util(b3_training_dataset, b3_validation_dataset, N)\n",
"display_digits(training_digits, training_labels, training_labels, \"training digits and their labels\", N)\n",
"display_digits(validation_digits[:N], validation_labels[:N], validation_labels[:N], \"validation digits and their labels\", N)\n",
"font_digits, font_labels = create_digits_from_local_fonts(N)"
],
"execution_count": 0,
"outputs": [
{
"output_type": "display_data",
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 936x216 with 1 Axes>"
]
},
"metadata": {
"tags": []
}
},
{
"output_type": "display_data",
"data": {
"image/png": "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\nUExdDIC6d+8u2U7HO3fuFB8+eJ4XRVxLnDt3TnRM+Pj4kI+PjyT1Edi2bRsB0mYla476C0y3bdsm\nm51//etfLY7JFy9eJEtLS+I4ThKhTkQUExOjdFMjwaO+e/duhXzqcmhOZdy7d4/69u1LAFTeKbvD\nCPWioiJxu225BE19oZ6WliY+tdc/hHj4qqoq8bX09HQxj/GcOXNo3rx57UrVZGtrS7a2tgRAttzh\nPXv2VBBJP/74I/34448tphJUFx9//LGCUL969arkNuo/VS9dulTy8lXF2tqaDAwM1LoteENqa2sp\nODiYOI6jZcuWSV7+qlWriOM40tHRoVmzZtH58+dp8uTJsgv1s2fPkrGxsfg9GxkZkZGRUavTKDZH\ncnIyGRsbqyzUa2pqaNKkSQSA7Ozs6Oeff26zbWGXWSGGteG4k5CQQBkZGZSdnU0hISHEcXXp5OQU\n6ER1WV/k8mBfunSJrKysiOd5lT241tbWZGVlJXmaW4GOKtSvXbtG165dI0tLS+rTp4/k5ScnJ4v9\ntzlvsJQITgXhHmVoaCj5/UHw8nIcRykpKSqNF9u2bRMzs8yfP5/mz58veZ0AUFJSkqTlKuP27dui\nc8Pf31+StIjNIaSZDQkJaTR7fufOHXHmkOd5+uabbySzm52dLWaBaerw9PSU3ZMucOLECVGkDx06\nVOUdSzuEUK+pqRG3CpYyx3RDVNnkICgoiBYsWCCKmqaOtk7jnzp1SvReyynU161b12jDo/p/K3tt\n3rx5stRFGfV3hZXrAWHjxo0E1O3W2NRGT3KzadMmAupSNmqaS5cukb6+PnEcJ/mioQsXLih8n6+9\n9pp4UxOOd955RzJ7AkuXLhUHXAMDAzp+/Lgkubwb4uTkRM7Ozs3+jq5cuUKzZs0S05wCaPcunXfv\n3lWIj3311Vdpz549ohdw6dKl4k1OCEORY3F6Q4TdBlubwlVVtm/fLj50tPQgIGzKJMc6COH3VP/G\nLodQX7duHe3YsUOlzZ0EsrKyKDAwkAIDAyWN365P/b0T1CHUT5w4ofDgDUi/2SFRXRjKa6+9RhzH\nkaOjIzk6OtKMGTOUjonr168nFxcX0Qsvt1BvT9ipKty7d0/cQKtr165tXovWGh4+fEh2dnaiWD98\n+DDt3buX9u7dS7a2tmKK17bsOtsa6nvYw8LCJMuZ3hRCOFF5eTlFRESQgYGB+HDwyy+/qFxOhxDq\n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\n",
"text/plain": [
"<Figure size 936x216 with 1 Axes>"
]
},
"metadata": {
"tags": []
}
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "vMKbcUwGTUmN",
"colab_type": "text"
},
"source": [
"# Conclusion\n",
"\n",
"In the exercise, we loaded data via the S3 API, preprocessed it into usable Tensorflow data, and verified that the processed data was functioning properly in the form we expected.\n",
"\n",
"We used the native Tensorflow/Python S3 interface to load the data directly into memory, and we used the Boto3 library to download the data to disk. In practice, for single-use training of small datasets, loading the data straight into memory is going to be the most efficient approach. For larger datasets, datasets that will be reused (e.g. for Hyperparameter tuning), or datasets that should be retained locally for whatever reason, downloading a local copy first and then processing that is preferable.\n",
"\n",
"Stay tuned for part 2, where we will go over training examples!\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ASTrhPH12fmB",
"colab_type": "text"
},
"source": [
"# Appendix\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "vi_GHfgxo1nM",
"colab_type": "text"
},
"source": [
"\n",
"## Code Snippets"
]
},
{
"cell_type": "code",
"metadata": {
"id": "D3Dh9hUoo2a0",
"colab_type": "code",
"outputId": "69072289-ccd2-457c-a981-e3dab8106439",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 34
}
},
"source": [
"# S3 is easy, just use s3://path/to/object for anything that expects a file\n",
"# Here's a smoke test that can be useful for troubleshooting\n",
"# note that client variables must be set in os.env or one of the ~/.aws/[config|credentials] files\n",
"# we set them in the 'Set Environment Variables' section above\n",
"\n",
"# Smoke test for troubleshooting\n",
"FILENAME = \"t10k-labels-idx1-ubyte\"\n",
"BUCKET = \"mnist\"\n",
"from tensorflow.python.lib.io import file_io\n",
"# using old-school string variables for backwards compatibility with Python 2\n",
"print(file_io.file_exists(\"s3://%s/%s\" % (BUCKET, FILENAME)))\n",
"\n",
"# ==============================================================================\n",
"\n",
"# Boto3 is a bit more complex, as there are several different ways to go about\n",
"# accessing files. Examples can be found here:\n",
"# https://boto3.amazonaws.com/v1/documentation/api/latest/guide/s3-examples.html\n",
"# This client provides lower-level access, but it is generally preferable\n",
"# build the parameters for creating the s3 resource\n",
"kwargs = {\"endpoint_url\": B3_ENDPOINT, \"aws_access_key_id\": ACCESS_KEY, \"aws_secret_access_key\": SECRET_KEY, \"region_name\": REGION_NAME}\n",
"\n",
"# create the s3 resource\n",
"s3 = boto3.resource(\"s3\", **kwargs)\n",
"\n",
"# create a bucket resource from our s3 resource (referring to an existing bucket)\n",
"mnistbucket = s3.Bucket(BUCKET)\n",
"mnistbucket.download_file(FILENAME, FILENAME) # remote filename, local filename\n"
],
"execution_count": 0,
"outputs": [
{
"output_type": "stream",
"text": [
"True\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "nfJzQYH8ozkC",
"colab_type": "text"
},
"source": [
"## Notes and Troubleshooting\n",
"\n",
"For S3, DO NOT USE http:// or https:// in front of the endpoint, just the FQDN\n",
"\n",
"To make things confusing, Boto3 REQUIRES you to use http:// or https:// in front of the endpoint.\n",
"\n",
"The python S3 client uses environment variables and config files in ~/.aws/config and ~/.aws/credentials. There is a lot of potential for conflicts and unexpected behavior as a result. Be warned!\n",
"\n",
"Using boto3 seems to be more consistent and reliable, and makes error handling a lot easier. \n",
"\n",
"If you encounter errors, go to Runtime->View Runtime Logs and/or use \"%xmode debug\" to increase error verbosity in colab."
]
}
]
}
@martin-gorner
Copy link

Some attribution for using my code would be welcome. Thank you.

@adizhol
Copy link

adizhol commented Sep 23, 2020

How to read regular images (.png) from s3 with tensorflow?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment