Unverified Commit 43178d7f authored by Ayushman Kumar's avatar Ayushman Kumar Committed by GitHub
Browse files

Merge pull request #1 from tensorflow/master

Updated
parents 8b47aa3d 75d13042
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "_index.ipynb",
"version": "0.3.2",
"provenance": []
}
},
"cells": [
{
"metadata": {
"id": "rX8mhOLljYeM",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"##### Copyright 2018 The TensorFlow Authors.\n",
"\n",
"Licensed under the Apache License, Version 2.0 (the \"License\");"
]
},
{
"metadata": {
"id": "BZSlp3DAjdYf",
"colab_type": "code",
"colab": {},
"cellView": "form"
},
"cell_type": "code",
"source": [
"#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"# you may not use this file except in compliance with the License.\n",
"# You may obtain a copy of the License at\n",
"#\n",
"# https://www.apache.org/licenses/LICENSE-2.0\n",
"#\n",
"# Unless required by applicable law or agreed to in writing, software\n",
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"# See the License for the specific language governing permissions and\n",
"# limitations under the License."
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "3wF5wszaj97Y",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"# Get Started with TensorFlow"
]
},
{
"metadata": {
"id": "AMrQVn--Aj1j",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"This file has moved."
]
},
{
"metadata": {
"id": "DUNzJc4jTj6G",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"<table class=\"tfo-notebook-buttons\" align=\"left\"><td>\n",
"<a target=\"_blank\" href=\"https://colab.research.google.com/github/tensorflow/docs/blob/master/site/en/tutorials/_index.ipynb\">\n",
" <img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" /><span>Run in Google Colab</span></a> \n",
"</td><td>\n",
"<a target=\"_blank\" href=\"https://github.com/tensorflow/docs/blob/master/site/en/tutorials/_index.ipynb\"><img width=32px src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" /><span>View source on GitHub</span></a></td></table>"
]
}
]
}
\ No newline at end of file
# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""An Example of a custom Estimator for the Iris dataset."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import argparse
import tensorflow as tf
import iris_data
parser = argparse.ArgumentParser()
parser.add_argument('--batch_size', default=100, type=int, help='batch size')
parser.add_argument('--train_steps', default=1000, type=int,
help='number of training steps')
def my_model(features, labels, mode, params):
"""DNN with three hidden layers and learning_rate=0.1."""
# Create three fully connected layers.
net = tf.feature_column.input_layer(features, params['feature_columns'])
for units in params['hidden_units']:
net = tf.layers.dense(net, units=units, activation=tf.nn.relu)
# Compute logits (1 per class).
logits = tf.layers.dense(net, params['n_classes'], activation=None)
# Compute predictions.
predicted_classes = tf.argmax(logits, 1)
if mode == tf.estimator.ModeKeys.PREDICT:
predictions = {
'class_ids': predicted_classes[:, tf.newaxis],
'probabilities': tf.nn.softmax(logits),
'logits': logits,
}
return tf.estimator.EstimatorSpec(mode, predictions=predictions)
# Compute loss.
loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)
# Compute evaluation metrics.
accuracy = tf.metrics.accuracy(labels=labels,
predictions=predicted_classes,
name='acc_op')
metrics = {'accuracy': accuracy}
tf.summary.scalar('accuracy', accuracy[1])
if mode == tf.estimator.ModeKeys.EVAL:
return tf.estimator.EstimatorSpec(
mode, loss=loss, eval_metric_ops=metrics)
# Create training op.
assert mode == tf.estimator.ModeKeys.TRAIN
optimizer = tf.train.AdagradOptimizer(learning_rate=0.1)
train_op = optimizer.minimize(loss, global_step=tf.train.get_global_step())
return tf.estimator.EstimatorSpec(mode, loss=loss, train_op=train_op)
def main(argv):
args = parser.parse_args(argv[1:])
# Fetch the data
(train_x, train_y), (test_x, test_y) = iris_data.load_data()
# Feature columns describe how to use the input.
my_feature_columns = []
for key in train_x.keys():
my_feature_columns.append(tf.feature_column.numeric_column(key=key))
# Build 2 hidden layer DNN with 10, 10 units respectively.
classifier = tf.estimator.Estimator(
model_fn=my_model,
params={
'feature_columns': my_feature_columns,
# Two hidden layers of 10 nodes each.
'hidden_units': [10, 10],
# The model must choose between 3 classes.
'n_classes': 3,
})
# Train the Model.
classifier.train(
input_fn=lambda:iris_data.train_input_fn(train_x, train_y, args.batch_size),
steps=args.train_steps)
# Evaluate the model.
eval_result = classifier.evaluate(
input_fn=lambda:iris_data.eval_input_fn(test_x, test_y, args.batch_size))
print('\nTest set accuracy: {accuracy:0.3f}\n'.format(**eval_result))
# Generate predictions from the model
expected = ['Setosa', 'Versicolor', 'Virginica']
predict_x = {
'SepalLength': [5.1, 5.9, 6.9],
'SepalWidth': [3.3, 3.0, 3.1],
'PetalLength': [1.7, 4.2, 5.4],
'PetalWidth': [0.5, 1.5, 2.1],
}
predictions = classifier.predict(
input_fn=lambda:iris_data.eval_input_fn(predict_x,
labels=None,
batch_size=args.batch_size))
for pred_dict, expec in zip(predictions, expected):
template = ('\nPrediction is "{}" ({:.1f}%), expected "{}"')
class_id = pred_dict['class_ids'][0]
probability = pred_dict['probabilities'][class_id]
print(template.format(iris_data.SPECIES[class_id],
100 * probability, expec))
if __name__ == '__main__':
tf.logging.set_verbosity(tf.logging.INFO)
tf.app.run(main)
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "Custom training: walkthrough",
"version": "0.3.2",
"provenance": []
}
},
"cells": [
{
"metadata": {
"id": "rX8mhOLljYeM",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"##### Copyright 2018 The TensorFlow Authors.\n",
"\n",
"Licensed under the Apache License, Version 2.0 (the \"License\");"
]
},
{
"metadata": {
"id": "BZSlp3DAjdYf",
"colab_type": "code",
"colab": {},
"cellView": "form"
},
"cell_type": "code",
"source": [
"#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"# you may not use this file except in compliance with the License.\n",
"# You may obtain a copy of the License at\n",
"#\n",
"# https://www.apache.org/licenses/LICENSE-2.0\n",
"#\n",
"# Unless required by applicable law or agreed to in writing, software\n",
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"# See the License for the specific language governing permissions and\n",
"# limitations under the License."
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "3wF5wszaj97Y",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"# Custom training: walkthrough"
]
},
{
"metadata": {
"id": "DUNzJc4jTj6G",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"<table class=\"tfo-notebook-buttons\" align=\"left\"><td>\n",
"<a target=\"_blank\" href=\"https://colab.research.google.com/github/tensorflow/docs/blob/master/site/en/tutorials/eager/custom_training_walkthrough.ipynb\">\n",
" <img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" /><span>Run in Google Colab</span></a> \n",
"</td><td>\n",
"<a target=\"_blank\" href=\"https://github.com/tensorflow/docs/blob/master/site/en/tutorials/eager/custom_training_walkthrough.ipynb\"><img width=32px src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" /><span>View source on GitHub</span></a></td></table>"
]
},
{
"metadata": {
"id": "hiH7AC-NTniF",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"This file has moved. Follow the links above to the new location."
]
}
]
}
\ No newline at end of file
# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""A simple smoke test that runs these examples for 1 training iteraton."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import tensorflow as tf
import pandas as pd
from six.moves import StringIO
import iris_data
import custom_estimator
import premade_estimator
FOUR_LINES = "\n".join([
"1,52.40, 2823,152,2",
"164, 99.80,176.60,66.20,1",
"176,2824, 136,3.19,0",
"2,177.30,66.30, 53.10,1",])
def four_lines_data():
text = StringIO(FOUR_LINES)
df = pd.read_csv(text, names=iris_data.CSV_COLUMN_NAMES)
xy = (df, df.pop("Species"))
return xy, xy
class RegressionTest(tf.test.TestCase):
"""Test the regression examples in this directory."""
@tf.test.mock.patch.dict(premade_estimator.__dict__,
{"load_data": four_lines_data})
def test_premade_estimator(self):
premade_estimator.main([None, "--train_steps=1"])
@tf.test.mock.patch.dict(custom_estimator.__dict__,
{"load_data": four_lines_data})
def test_custom_estimator(self):
custom_estimator.main([None, "--train_steps=1"])
if __name__ == "__main__":
tf.test.main()
import pandas as pd
import tensorflow as tf
TRAIN_URL = "http://download.tensorflow.org/data/iris_training.csv"
TEST_URL = "http://download.tensorflow.org/data/iris_test.csv"
CSV_COLUMN_NAMES = ['SepalLength', 'SepalWidth',
'PetalLength', 'PetalWidth', 'Species']
SPECIES = ['Setosa', 'Versicolor', 'Virginica']
def maybe_download():
train_path = tf.keras.utils.get_file(TRAIN_URL.split('/')[-1], TRAIN_URL)
test_path = tf.keras.utils.get_file(TEST_URL.split('/')[-1], TEST_URL)
return train_path, test_path
def load_data(y_name='Species'):
"""Returns the iris dataset as (train_x, train_y), (test_x, test_y)."""
train_path, test_path = maybe_download()
train = pd.read_csv(train_path, names=CSV_COLUMN_NAMES, header=0)
train_x, train_y = train, train.pop(y_name)
test = pd.read_csv(test_path, names=CSV_COLUMN_NAMES, header=0)
test_x, test_y = test, test.pop(y_name)
return (train_x, train_y), (test_x, test_y)
def train_input_fn(features, labels, batch_size):
"""An input function for training"""
# Convert the inputs to a Dataset.
dataset = tf.data.Dataset.from_tensor_slices((dict(features), labels))
# Shuffle, repeat, and batch the examples.
dataset = dataset.shuffle(1000).repeat().batch(batch_size)
# Return the dataset.
return dataset
def eval_input_fn(features, labels, batch_size):
"""An input function for evaluation or prediction"""
features=dict(features)
if labels is None:
# No labels, use only features.
inputs = features
else:
inputs = (features, labels)
# Convert the inputs to a Dataset.
dataset = tf.data.Dataset.from_tensor_slices(inputs)
# Batch the examples
assert batch_size is not None, "batch_size must not be None"
dataset = dataset.batch(batch_size)
# Return the dataset.
return dataset
# The remainder of this file contains a simple example of a csv parser,
# implemented using the `Dataset` class.
# `tf.parse_csv` sets the types of the outputs to match the examples given in
# the `record_defaults` argument.
CSV_TYPES = [[0.0], [0.0], [0.0], [0.0], [0]]
def _parse_line(line):
# Decode the line into its fields
fields = tf.decode_csv(line, record_defaults=CSV_TYPES)
# Pack the result into a dictionary
features = dict(zip(CSV_COLUMN_NAMES, fields))
# Separate the label from the features
label = features.pop('Species')
return features, label
def csv_input_fn(csv_path, batch_size):
# Create a dataset containing the text lines.
dataset = tf.data.TextLineDataset(csv_path).skip(1)
# Parse each line.
dataset = dataset.map(_parse_line)
# Shuffle, repeat, and batch the examples.
dataset = dataset.shuffle(1000).repeat().batch(batch_size)
# Return the dataset.
return dataset
# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""An Example of a DNNClassifier for the Iris dataset."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import argparse
import tensorflow as tf
import iris_data
parser = argparse.ArgumentParser()
parser.add_argument('--batch_size', default=100, type=int, help='batch size')
parser.add_argument('--train_steps', default=1000, type=int,
help='number of training steps')
def main(argv):
args = parser.parse_args(argv[1:])
# Fetch the data
(train_x, train_y), (test_x, test_y) = iris_data.load_data()
# Feature columns describe how to use the input.
my_feature_columns = []
for key in train_x.keys():
my_feature_columns.append(tf.feature_column.numeric_column(key=key))
# Build 2 hidden layer DNN with 10, 10 units respectively.
classifier = tf.estimator.DNNClassifier(
feature_columns=my_feature_columns,
# Two hidden layers of 10 nodes each.
hidden_units=[10, 10],
# The model must choose between 3 classes.
n_classes=3)
# Train the Model.
classifier.train(
input_fn=lambda:iris_data.train_input_fn(train_x, train_y,
args.batch_size),
steps=args.train_steps)
# Evaluate the model.
eval_result = classifier.evaluate(
input_fn=lambda:iris_data.eval_input_fn(test_x, test_y,
args.batch_size))
print('\nTest set accuracy: {accuracy:0.3f}\n'.format(**eval_result))
# Generate predictions from the model
expected = ['Setosa', 'Versicolor', 'Virginica']
predict_x = {
'SepalLength': [5.1, 5.9, 6.9],
'SepalWidth': [3.3, 3.0, 3.1],
'PetalLength': [1.7, 4.2, 5.4],
'PetalWidth': [0.5, 1.5, 2.1],
}
predictions = classifier.predict(
input_fn=lambda:iris_data.eval_input_fn(predict_x,
labels=None,
batch_size=args.batch_size))
template = ('\nPrediction is "{}" ({:.1f}%), expected "{}"')
for pred_dict, expec in zip(predictions, expected):
class_id = pred_dict['class_ids'][0]
probability = pred_dict['probabilities'][class_id]
print(template.format(iris_data.SPECIES[class_id],
100 * probability, expec))
if __name__ == '__main__':
tf.logging.set_verbosity(tf.logging.INFO)
tf.app.run(main)
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "autograph.ipynb",
"version": "0.3.2",
"provenance": [],
"private_outputs": true,
"collapsed_sections": [
"Jxv6goXm7oGF"
],
"toc_visible": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
}
},
"cells": [
{
"metadata": {
"id": "Jxv6goXm7oGF",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"##### Copyright 2018 The TensorFlow Authors.\n",
"\n",
"Licensed under the Apache License, Version 2.0 (the \"License\");"
]
},
{
"metadata": {
"id": "llMNufAK7nfK",
"colab_type": "code",
"colab": {}
},
"cell_type": "code",
"source": [
"#@title Licensed under the Apache License, Version 2.0 (the \"License\"); { display-mode: \"form\" }\n",
"# you may not use this file except in compliance with the License.\n",
"# You may obtain a copy of the License at\n",
"#\n",
"# https://www.apache.org/licenses/LICENSE-2.0\n",
"#\n",
"# Unless required by applicable law or agreed to in writing, software\n",
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"# See the License for the specific language governing permissions and\n",
"# limitations under the License."
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "8Byow2J6LaPl",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"# AutoGraph: Easy control flow for graphs "
]
},
{
"metadata": {
"id": "kGXS3UWBBNoc",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://www.tensorflow.org/guide/autograph\"><img src=\"https://www.tensorflow.org/images/tf_logo_32px.png\" />View on TensorFlow.org</a>\n",
" </td>\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://colab.research.google.com/github/tensorflow/docs/blob/master/site/en/guide/autograph.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
" </td>\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://github.com/tensorflow/docs/blob/master/site/en/guide/autograph.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View source on GitHub</a>\n",
" </td>\n",
"</table>"
]
}
]
}
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "Custom training: walkthrough",
"version": "0.3.2",
"provenance": [],
"private_outputs": true,
"collapsed_sections": [],
"toc_visible": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
}
},
"cells": [
{
"metadata": {
"id": "rwxGnsA92emp",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"##### Copyright 2018 The TensorFlow Authors."
]
},
{
"metadata": {
"id": "CPII1rGR2rF9",
"colab_type": "code",
"colab": {},
"cellView": "form"
},
"cell_type": "code",
"source": [
"#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"# you may not use this file except in compliance with the License.\n",
"# You may obtain a copy of the License at\n",
"#\n",
"# https://www.apache.org/licenses/LICENSE-2.0\n",
"#\n",
"# Unless required by applicable law or agreed to in writing, software\n",
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"# See the License for the specific language governing permissions and\n",
"# limitations under the License."
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "JtEZ1pCPn--z",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"# Custom training: walkthrough\n",
"\n",
"This file has moved."
]
},
{
"metadata": {
"id": "GV1F7tVTN3Dn",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://www.tensorflow.org/tutorials/eager/custom_training_walkthrough\"><img src=\"https://www.tensorflow.org/images/tf_logo_32px.png\" />View on TensorFlow.org</a>\n",
" </td>\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://colab.research.google.com/github/tensorflow/docs/blob/master/site/en/tutorials/eager/custom_training_walkthrough.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
" </td>\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://github.com/tensorflow/docs/blob/master/site/en/tutorials/eager/custom_training_walkthrough.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View source on GitHub</a>\n",
" </td>\n",
"</table>"
]
}
]
}
\ No newline at end of file
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "linear.ipynb",
"version": "0.3.2",
"provenance": [],
"private_outputs": true,
"collapsed_sections": [
"MWW1TyjaecRh"
],
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
}
},
"cells": [
{
"metadata": {
"id": "MWW1TyjaecRh",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"##### Copyright 2018 The TensorFlow Authors."
]
},
{
"metadata": {
"id": "mOtR1FzCef-u",
"colab_type": "code",
"colab": {}
},
"cell_type": "code",
"source": [
"#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"# you may not use this file except in compliance with the License.\n",
"# You may obtain a copy of the License at\n",
"#\n",
"# https://www.apache.org/licenses/LICENSE-2.0\n",
"#\n",
"# Unless required by applicable law or agreed to in writing, software\n",
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"# See the License for the specific language governing permissions and\n",
"# limitations under the License."
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "Zr7KpBhMcYvE",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"# Build a linear model with Estimators"
]
},
{
"metadata": {
"id": "gkkpAk4sEvQR",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"This file has moved."
]
},
{
"metadata": {
"id": "uJl4gaPFzxQz",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://www.tensorflow.org/tutorials/estimators/linear\"><img src=\"https://www.tensorflow.org/images/tf_logo_32px.png\" />View on TensorFlow.org</a>\n",
" </td>\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://colab.research.google.com/github/tensorflow/docs/blob/master/site/en/tutorials/estimators/linear.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
" </td>\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://github.com/tensorflow/docs/blob/master/site/en/tutorials/estimators/linear.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View source on GitHub</a>\n",
" </td>\n",
"</table>"
]
}
]
}
\ No newline at end of file
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "basic_classification.ipynb",
"version": "0.3.2",
"provenance": [],
"private_outputs": true,
"collapsed_sections": [],
"toc_visible": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
}
},
"cells": [
{
"metadata": {
"id": "MhoQ0WE77laV",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"##### Copyright 2018 The TensorFlow Authors."
]
},
{
"metadata": {
"id": "_ckMIh7O7s6D",
"colab_type": "code",
"colab": {},
"cellView": "form"
},
"cell_type": "code",
"source": [
"#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"# you may not use this file except in compliance with the License.\n",
"# You may obtain a copy of the License at\n",
"#\n",
"# https://www.apache.org/licenses/LICENSE-2.0\n",
"#\n",
"# Unless required by applicable law or agreed to in writing, software\n",
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"# See the License for the specific language governing permissions and\n",
"# limitations under the License."
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "vasWnqRgy1H4",
"colab_type": "code",
"colab": {},
"cellView": "form"
},
"cell_type": "code",
"source": [
"#@title MIT License\n",
"#\n",
"# Copyright (c) 2017 François Chollet\n",
"#\n",
"# Permission is hereby granted, free of charge, to any person obtaining a\n",
"# copy of this software and associated documentation files (the \"Software\"),\n",
"# to deal in the Software without restriction, including without limitation\n",
"# the rights to use, copy, modify, merge, publish, distribute, sublicense,\n",
"# and/or sell copies of the Software, and to permit persons to whom the\n",
"# Software is furnished to do so, subject to the following conditions:\n",
"#\n",
"# The above copyright notice and this permission notice shall be included in\n",
"# all copies or substantial portions of the Software.\n",
"#\n",
"# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n",
"# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n",
"# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n",
"# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n",
"# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n",
"# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n",
"# DEALINGS IN THE SOFTWARE."
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "jYysdyb-CaWM",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"# Train your first neural network: basic classification"
]
},
{
"metadata": {
"id": "-VrEyagzFU63",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"This file has moved."
]
},
{
"metadata": {
"id": "S5Uhzt6vVIB2",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://www.tensorflow.org/tutorials/keras/basic_classification\"><img src=\"https://www.tensorflow.org/images/tf_logo_32px.png\" />View on TensorFlow.org</a>\n",
" </td>\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://colab.research.google.com/github/tensorflow/docs/blob/master/site/en/tutorials/keras/basic_classification.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
" </td>\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://github.com/tensorflow/docs/blob/master/site/en/tutorials/keras/basic_classification.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View source on GitHub</a>\n",
" </td>\n",
"</table>"
]
}
]
}
\ No newline at end of file
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "basic-regression.ipynb",
"version": "0.3.2",
"provenance": [],
"private_outputs": true,
"collapsed_sections": [
"FhGuhbZ6M5tl"
],
"toc_visible": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
}
},
"cells": [
{
"metadata": {
"id": "FhGuhbZ6M5tl",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"##### Copyright 2018 The TensorFlow Authors."
]
},
{
"metadata": {
"id": "AwOEIRJC6Une",
"colab_type": "code",
"colab": {}
},
"cell_type": "code",
"source": [
"#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"# you may not use this file except in compliance with the License.\n",
"# You may obtain a copy of the License at\n",
"#\n",
"# https://www.apache.org/licenses/LICENSE-2.0\n",
"#\n",
"# Unless required by applicable law or agreed to in writing, software\n",
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"# See the License for the specific language governing permissions and\n",
"# limitations under the License."
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "KyPEtTqk6VdG",
"colab_type": "code",
"colab": {}
},
"cell_type": "code",
"source": [
"#@title MIT License\n",
"#\n",
"# Copyright (c) 2017 François Chollet\n",
"#\n",
"# Permission is hereby granted, free of charge, to any person obtaining a\n",
"# copy of this software and associated documentation files (the \"Software\"),\n",
"# to deal in the Software without restriction, including without limitation\n",
"# the rights to use, copy, modify, merge, publish, distribute, sublicense,\n",
"# and/or sell copies of the Software, and to permit persons to whom the\n",
"# Software is furnished to do so, subject to the following conditions:\n",
"#\n",
"# The above copyright notice and this permission notice shall be included in\n",
"# all copies or substantial portions of the Software.\n",
"#\n",
"# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n",
"# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n",
"# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n",
"# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n",
"# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n",
"# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n",
"# DEALINGS IN THE SOFTWARE."
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "EIdT9iu_Z4Rb",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"# Predict house prices: regression"
]
},
{
"metadata": {
"id": "dmtJAyM7FwUf",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"This file has moved."
]
},
{
"metadata": {
"id": "bBIlTPscrIT9",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://www.tensorflow.org/tutorials/keras/basic_regression\"><img src=\"https://www.tensorflow.org/images/tf_logo_32px.png\" />View on TensorFlow.org</a>\n",
" </td>\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://colab.research.google.com/github/tensorflow/docs/blob/master/site/en/tutorials/keras/basic_regression.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
" </td>\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://github.com/tensorflow/docs/blob/master/site/en/tutorials/keras/basic_regression.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View source on GitHub</a>\n",
" </td>\n",
"</table>"
]
}
]
}
\ No newline at end of file
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "basic-text-classification.ipynb",
"version": "0.3.2",
"provenance": [],
"private_outputs": true,
"collapsed_sections": [],
"toc_visible": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
}
},
"cells": [
{
"metadata": {
"id": "Ic4_occAAiAT",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"##### Copyright 2018 The TensorFlow Authors."
]
},
{
"metadata": {
"id": "ioaprt5q5US7",
"colab_type": "code",
"colab": {},
"cellView": "form"
},
"cell_type": "code",
"source": [
"#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"# you may not use this file except in compliance with the License.\n",
"# You may obtain a copy of the License at\n",
"#\n",
"# https://www.apache.org/licenses/LICENSE-2.0\n",
"#\n",
"# Unless required by applicable law or agreed to in writing, software\n",
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"# See the License for the specific language governing permissions and\n",
"# limitations under the License."
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "yCl0eTNH5RS3",
"colab_type": "code",
"colab": {},
"cellView": "form"
},
"cell_type": "code",
"source": [
"#@title MIT License\n",
"#\n",
"# Copyright (c) 2017 François Chollet\n",
"#\n",
"# Permission is hereby granted, free of charge, to any person obtaining a\n",
"# copy of this software and associated documentation files (the \"Software\"),\n",
"# to deal in the Software without restriction, including without limitation\n",
"# the rights to use, copy, modify, merge, publish, distribute, sublicense,\n",
"# and/or sell copies of the Software, and to permit persons to whom the\n",
"# Software is furnished to do so, subject to the following conditions:\n",
"#\n",
"# The above copyright notice and this permission notice shall be included in\n",
"# all copies or substantial portions of the Software.\n",
"#\n",
"# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n",
"# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n",
"# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n",
"# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n",
"# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n",
"# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n",
"# DEALINGS IN THE SOFTWARE."
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "ItXfxkxvosLH",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"# Text classification with movie reviews"
]
},
{
"metadata": {
"id": "NBM1gMpEGN_d",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"This file has moved."
]
},
{
"metadata": {
"id": "hKY4XMc9o8iB",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://www.tensorflow.org/tutorials/keras/basic_text_classification\"><img src=\"https://www.tensorflow.org/images/tf_logo_32px.png\" />View on TensorFlow.org</a>\n",
" </td>\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://colab.research.google.com/github/tensorflow/docs/blob/master/site/en/tutorials/keras/basic_text_classification.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
" </td>\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://github.com/tensorflow/docs/blob/master/site/en/tutorials/keras/basic_text_classification.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View source on GitHub</a>\n",
" </td>\n",
"</table>"
]
}
]
}
\ No newline at end of file
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "overfit-and-underfit.ipynb",
"version": "0.3.2",
"provenance": [],
"private_outputs": true,
"collapsed_sections": [
"fTFj8ft5dlbS"
],
"toc_visible": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"accelerator": "GPU"
},
"cells": [
{
"metadata": {
"id": "fTFj8ft5dlbS",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"##### Copyright 2018 The TensorFlow Authors."
]
},
{
"metadata": {
"id": "lzyBOpYMdp3F",
"colab_type": "code",
"colab": {},
"cellView": "form"
},
"cell_type": "code",
"source": [
"#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"# you may not use this file except in compliance with the License.\n",
"# You may obtain a copy of the License at\n",
"#\n",
"# https://www.apache.org/licenses/LICENSE-2.0\n",
"#\n",
"# Unless required by applicable law or agreed to in writing, software\n",
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"# See the License for the specific language governing permissions and\n",
"# limitations under the License."
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "m_x4KfSJ7Vt7",
"colab_type": "code",
"colab": {},
"cellView": "form"
},
"cell_type": "code",
"source": [
"#@title MIT License\n",
"#\n",
"# Copyright (c) 2017 François Chollet\n",
"#\n",
"# Permission is hereby granted, free of charge, to any person obtaining a\n",
"# copy of this software and associated documentation files (the \"Software\"),\n",
"# to deal in the Software without restriction, including without limitation\n",
"# the rights to use, copy, modify, merge, publish, distribute, sublicense,\n",
"# and/or sell copies of the Software, and to permit persons to whom the\n",
"# Software is furnished to do so, subject to the following conditions:\n",
"#\n",
"# The above copyright notice and this permission notice shall be included in\n",
"# all copies or substantial portions of the Software.\n",
"#\n",
"# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n",
"# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n",
"# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n",
"# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n",
"# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n",
"# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n",
"# DEALINGS IN THE SOFTWARE."
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "C9HmC2T4ld5B",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"# Explore overfitting and underfitting"
]
},
{
"metadata": {
"id": "Xy5k1IC0GrV9",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"This file has moved."
]
},
{
"metadata": {
"id": "kRTxFhXAlnl1",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://www.tensorflow.org/tutorials/keras/overfit_and_underfit\"><img src=\"https://www.tensorflow.org/images/tf_logo_32px.png\" />View on TensorFlow.org</a>\n",
" </td>\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://colab.research.google.com/github/tensorflow/docs/blob/master/site/en/tutorials/keras/overfit_and_underfit.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
" </td>\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://github.com/tensorflow/docs/blob/master/site/en/tutorials/keras/overfit_and_underfit.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View source on GitHub</a>\n",
" </td>\n",
"</table>"
]
}
]
}
\ No newline at end of file
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "save_and_restore_models.ipynb",
"version": "0.3.2",
"views": {},
"default_view": {},
"provenance": [],
"private_outputs": true,
"collapsed_sections": [],
"toc_visible": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"accelerator": "GPU"
},
"cells": [
{
"metadata": {
"id": "g_nWetWWd_ns",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"##### Copyright 2018 The TensorFlow Authors."
]
},
{
"metadata": {
"id": "2pHVBk_seED1",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
},
"cellView": "form"
},
"cell_type": "code",
"source": [
"#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"# you may not use this file except in compliance with the License.\n",
"# You may obtain a copy of the License at\n",
"#\n",
"# https://www.apache.org/licenses/LICENSE-2.0\n",
"#\n",
"# Unless required by applicable law or agreed to in writing, software\n",
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"# See the License for the specific language governing permissions and\n",
"# limitations under the License."
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "N_fMsQ-N8I7j",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
},
"cellView": "form"
},
"cell_type": "code",
"source": [
"#@title MIT License\n",
"#\n",
"# Copyright (c) 2017 François Chollet\n",
"#\n",
"# Permission is hereby granted, free of charge, to any person obtaining a\n",
"# copy of this software and associated documentation files (the \"Software\"),\n",
"# to deal in the Software without restriction, including without limitation\n",
"# the rights to use, copy, modify, merge, publish, distribute, sublicense,\n",
"# and/or sell copies of the Software, and to permit persons to whom the\n",
"# Software is furnished to do so, subject to the following conditions:\n",
"#\n",
"# The above copyright notice and this permission notice shall be included in\n",
"# all copies or substantial portions of the Software.\n",
"#\n",
"# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n",
"# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n",
"# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n",
"# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n",
"# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n",
"# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n",
"# DEALINGS IN THE SOFTWARE."
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "pZJ3uY9O17VN",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"# Save and restore models"
]
},
{
"metadata": {
"id": "M4Ata7_wMul1",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://www.tensorflow.org/tutorials/keras/save_and_restore_models\"><img src=\"https://www.tensorflow.org/images/tf_logo_32px.png\" />View on TensorFlow.org</a>\n",
" </td>\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://colab.research.google.com/github/tensorflow/models/blob/master/samples/core/tutorials/keras/save_and_restore_models.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
" </td>\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://github.com/tensorflow/models/blob/master/samples/core/tutorials/keras/save_and_restore_models.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View source on GitHub</a>\n",
" </td>\n",
"</table>"
]
},
{
"metadata": {
"id": "mBdde4YJeJKF",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"Model progress can be saved during—and after—training. This means a model can resume where it left off and avoid long training times. Saving also means you can share your model and others can recreate your work. When publishing research models and techniques, most machine learning practitioners share:\n",
"\n",
"* code to create the model, and\n",
"* the trained weights, or parameters, for the model\n",
"\n",
"Sharing this data helps others understand how the model works and try it themselves with new data.\n",
"\n",
"Caution: Be careful with untrusted code—TensorFlow models are code. See [Using TensorFlow Securely](https://github.com/tensorflow/tensorflow/blob/master/SECURITY.md) for details.\n",
"\n",
"### Options\n",
"\n",
"There are different ways to save TensorFlow models—depending on the API you're using. This guide uses [tf.keras](https://www.tensorflow.org/guide/keras), a high-level API to build and train models in TensorFlow. For other approaches, see the TensorFlow [Save and Restore](https://www.tensorflow.org/guide/saved_model) guide or [Saving in eager](https://www.tensorflow.org/guide/eager#object_based_saving).\n"
]
},
{
"metadata": {
"id": "xCUREq7WXgvg",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"## Setup\n",
"\n",
"### Installs and imports"
]
},
{
"metadata": {
"id": "7l0MiTOrXtNv",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"Install and import TensorFlow and dependencies:"
]
},
{
"metadata": {
"id": "RzIOVSdnMYyO",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"!pip install h5py pyyaml "
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "SbGsznErXWt6",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"### Get an example dataset\n",
"\n",
"We'll use the [MNIST dataset](http://yann.lecun.com/exdb/mnist/) to train our model to demonstrate saving weights. To speed up these demonstration runs, only use the first 1000 examples:"
]
},
{
"metadata": {
"id": "7Nm7Tyb-gRt-",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"from __future__ import absolute_import, division, print_function\n",
"\n",
"import os\n",
"\n",
"import tensorflow as tf\n",
"from tensorflow import keras\n",
"\n",
"tf.__version__"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "9rGfFwE9XVwz",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"(train_images, train_labels), (test_images, test_labels) = tf.keras.datasets.mnist.load_data()\n",
"\n",
"train_labels = train_labels[:1000]\n",
"test_labels = test_labels[:1000]\n",
"\n",
"train_images = train_images[:1000].reshape(-1, 28 * 28) / 255.0\n",
"test_images = test_images[:1000].reshape(-1, 28 * 28) / 255.0"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "anG3iVoXyZGI",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"### Define a model"
]
},
{
"metadata": {
"id": "wynsOBfby0Pa",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"Let's build a simple model we'll use to demonstrate saving and loading weights."
]
},
{
"metadata": {
"id": "0HZbJIjxyX1S",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"# Returns a short sequential model\n",
"def create_model():\n",
" model = tf.keras.models.Sequential([\n",
" keras.layers.Dense(512, activation=tf.nn.relu, input_shape=(784,)),\n",
" keras.layers.Dropout(0.2),\n",
" keras.layers.Dense(10, activation=tf.nn.softmax)\n",
" ])\n",
" \n",
" model.compile(optimizer=tf.keras.optimizers.Adam(), \n",
" loss=tf.keras.losses.sparse_categorical_crossentropy,\n",
" metrics=['accuracy'])\n",
" \n",
" return model\n",
"\n",
"\n",
"# Create a basic model instance\n",
"model = create_model()\n",
"model.summary()"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "soDE0W_KH8rG",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"## Save checkpoints during training"
]
},
{
"metadata": {
"id": "mRyd5qQQIXZm",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"The primary use case is to automatically save checkpoints *during* and at *the end* of training. This way you can use a trained model without having to retrain it, or pick-up training where you left of—in case the training process was interrupted.\n",
"\n",
"`tf.keras.callbacks.ModelCheckpoint` is a callback that performs this task. The callback takes a couple of arguments to configure checkpointing.\n",
"\n",
"### Checkpoint callback usage\n",
"\n",
"Train the model and pass it the `ModelCheckpoint` callback:"
]
},
{
"metadata": {
"id": "IFPuhwntH8VH",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"checkpoint_path = \"training_1/cp.ckpt\"\n",
"checkpoint_dir = os.path.dirname(checkpoint_path)\n",
"\n",
"# Create checkpoint callback\n",
"cp_callback = tf.keras.callbacks.ModelCheckpoint(checkpoint_path, \n",
" save_weights_only=True,\n",
" verbose=1)\n",
"\n",
"model = create_model()\n",
"\n",
"model.fit(train_images, train_labels, epochs = 10, \n",
" validation_data = (test_images,test_labels),\n",
" callbacks = [cp_callback]) # pass callback to training"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "rlM-sgyJO084",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"This creates a single collection of TensorFlow checkpoint files that are updated at the end of each epoch:"
]
},
{
"metadata": {
"id": "gXG5FVKFOVQ3",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"!ls {checkpoint_dir}"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "wlRN_f56Pqa9",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"Create a new, untrained model. When restoring a model from only weights, you must have a model with the same architecture as the original model. Since it's the same model architecture, we can share weights despite that it's a different *instance* of the model.\n",
"\n",
"Now rebuild a fresh, untrained model, and evaluate it on the test set. An untrained model will perform at chance levels (~10% accuracy):"
]
},
{
"metadata": {
"id": "Fp5gbuiaPqCT",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"model = create_model()\n",
"\n",
"loss, acc = model.evaluate(test_images, test_labels)\n",
"print(\"Untrained model, accuracy: {:5.2f}%\".format(100*acc))"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "1DTKpZssRSo3",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"Then load the weights from the checkpoint, and re-evaluate:"
]
},
{
"metadata": {
"id": "2IZxbwiRRSD2",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"model.load_weights(checkpoint_path)\n",
"loss,acc = model.evaluate(test_images, test_labels)\n",
"print(\"Restored model, accuracy: {:5.2f}%\".format(100*acc))"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "bpAbKkAyVPV8",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"### Checkpoint callback options\n",
"\n",
"The callback provides several options to give the resulting checkpoints unique names, and adjust the checkpointing frequency.\n",
"\n",
"Train a new model, and save uniquely named checkpoints once every 5-epochs:\n"
]
},
{
"metadata": {
"id": "mQF_dlgIVOvq",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"# include the epoch in the file name. (uses `str.format`)\n",
"checkpoint_path = \"training_2/cp-{epoch:04d}.ckpt\"\n",
"checkpoint_dir = os.path.dirname(checkpoint_path)\n",
"\n",
"cp_callback = tf.keras.callbacks.ModelCheckpoint(\n",
" checkpoint_path, verbose=1, save_weights_only=True,\n",
" # Save weights, every 5-epochs.\n",
" period=5)\n",
"\n",
"model = create_model()\n",
"model.fit(train_images, train_labels,\n",
" epochs = 50, callbacks = [cp_callback],\n",
" validation_data = (test_images,test_labels),\n",
" verbose=0)"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "1zFrKTjjavWI",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"Now, have a look at the resulting checkpoints (sorting by modification date):"
]
},
{
"metadata": {
"id": "1AN_fnuyR41H",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"import pathlib\n",
"\n",
"# Sort the checkpoints by modification time.\n",
"checkpoints = pathlib.Path(checkpoint_dir).glob(\"*.index\")\n",
"checkpoints = sorted(checkpoints, key=lambda cp:cp.stat().st_mtime)\n",
"checkpoints = [cp.with_suffix('') for cp in checkpoints]\n",
"latest = str(checkpoints[-1])\n",
"checkpoints"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "Zk2ciGbKg561",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"Note: the default tensorflow format only saves the 5 most recent checkpoints.\n",
"\n",
"To test, reset the model and load the latest checkpoint:"
]
},
{
"metadata": {
"id": "3M04jyK-H3QK",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"model = create_model()\n",
"model.load_weights(latest)\n",
"loss, acc = model.evaluate(test_images, test_labels)\n",
"print(\"Restored model, accuracy: {:5.2f}%\".format(100*acc))"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "c2OxsJOTHxia",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"## What are these files?"
]
},
{
"metadata": {
"id": "JtdYhvWnH2ib",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"The above code stores the weights to a collection of [checkpoint](https://www.tensorflow.org/guide/saved_model#save_and_restore_variables)-formatted files that contain only the trained weights in a binary format. Checkpoints contain:\n",
"\n",
"* One or more shards that contain your model's weights. \n",
"* An index file that indicates which weights are stored in which shard. \n",
"\n",
"If you are only training a model on a single machine, you'll have one shard with the suffix: `.data-00000-of-00001`"
]
},
{
"metadata": {
"id": "S_FA-ZvxuXQV",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"## Manually save weights\n",
"\n",
"Above you saw how to load the weights into a model.\n",
"\n",
"Manually saving the weights is just as simple, use the `Model.save_weights` method."
]
},
{
"metadata": {
"id": "R7W5plyZ-u9X",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"# Save the weights\n",
"model.save_weights('./checkpoints/my_checkpoint')\n",
"\n",
"# Restore the weights\n",
"model = create_model()\n",
"model.load_weights('./checkpoints/my_checkpoint')\n",
"\n",
"loss,acc = model.evaluate(test_images, test_labels)\n",
"print(\"Restored model, accuracy: {:5.2f}%\".format(100*acc))"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "kOGlxPRBEvV1",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"## Save the entire model\n",
"\n",
"The entire model can be saved to a file that contains the weight values, the model's configuration, and even the optimizer's configuration. This allows you to checkpoint a model and resume training later—from the exact same state—without access to the original code.\n",
"\n",
"Saving a fully-functional model in Keras is very useful—you can load them in [TensorFlow.js](https://js.tensorflow.org/tutorials/import-keras.html) and then train and run them in web browsers.\n",
"\n",
"Keras provides a basic save format using the [HDF5](https://en.wikipedia.org/wiki/Hierarchical_Data_Format) standard. For our purposes, the saved model can be treated as a single binary blob.\n"
]
},
{
"metadata": {
"id": "m2dkmJVCGUia",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"model = create_model()\n",
"\n",
"model.fit(train_images, train_labels, epochs=5)\n",
"\n",
"# Save entire model to a HDF5 file\n",
"model.save('my_model.h5')"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "GWmttMOqS68S",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"Now recreate the model from that file:"
]
},
{
"metadata": {
"id": "5NDMO_7kS6Do",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"# Recreate the exact same model, including weights and optimizer.\n",
"new_model = keras.models.load_model('my_model.h5')\n",
"new_model.summary()\n"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "JXQpbTicTBwt",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"Check its accuracy:"
]
},
{
"metadata": {
"id": "jwEaj9DnTCVA",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"loss, acc = new_model.evaluate(test_images, test_labels)\n",
"print(\"Restored model, accuracy: {:5.2f}%\".format(100*acc))"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "dGXqd4wWJl8O",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"This technique saves everything:\n",
"\n",
"* The weight values\n",
"* The model's configuration(architecture)\n",
"* The optimizer configuration\n",
"\n",
"Keras saves models by inspecting the architecture. Currently, it is not able to save TensorFlow optimizers (from `tf.train`). When using those you will need to re-compile the model after loading, and you will lose the state of the optimizer.\n"
]
},
{
"metadata": {
"id": "eUYTzSz5VxL2",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"## What's Next\n",
"\n",
"That was a quick guide to saving and loading in with `tf.keras`.\n",
"\n",
"* The [tf.keras guide](https://www.tensorflow.org/guide/keras) shows more about saving and loading models with `tf.keras`.\n",
"\n",
"* See [Saving in eager](https://www.tensorflow.org/guide/eager#object_based_saving) for saving during eager execution.\n",
"\n",
"* The [Save and Restore](https://www.tensorflow.org/guide/saved_model) guide has low-level details about TensorFlow saving."
]
}
]
}
# TensorFlow for Java: Examples
These have moved.
See: The [java repository](https://github.com/tensorflow/java), and the [Java models repository](https://github.com/tensorflow/java-models)
# Copyright 2017 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
# This is the complete code for the following blogpost:
# https://developers.googleblog.com/2017/12/creating-custom-estimators-in-tensorflow.html
import tensorflow as tf
import os
import sys
import six.moves.urllib.request as request
from distutils.version import StrictVersion
tf.logging.set_verbosity(tf.logging.INFO)
# Check that we have correct TensorFlow version installed
tf_version = tf.__version__
tf.logging.info("TensorFlow version: {}".format(tf_version))
assert StrictVersion("1.4") <= StrictVersion(tf_version), "TensorFlow r1.4 or later is needed"
# Windows users: You only need to change PATH, rest is platform independent
PATH = "/tmp/tf_custom_estimators"
# Fetch and store Training and Test dataset files
PATH_DATASET = PATH + os.sep + "dataset"
FILE_TRAIN = PATH_DATASET + os.sep + "iris_training.csv"
FILE_TEST = PATH_DATASET + os.sep + "iris_test.csv"
URL_TRAIN = "http://download.tensorflow.org/data/iris_training.csv"
URL_TEST = "http://download.tensorflow.org/data/iris_test.csv"
def downloadDataset(url, file):
if not os.path.exists(PATH_DATASET):
os.makedirs(PATH_DATASET)
if not os.path.exists(file):
data = request.urlopen(url).read()
with open(file, "wb") as f:
f.write(data)
f.close()
downloadDataset(URL_TRAIN, FILE_TRAIN)
downloadDataset(URL_TEST, FILE_TEST)
# The CSV features in our training & test data
feature_names = [
'SepalLength',
'SepalWidth',
'PetalLength',
'PetalWidth']
# Create an input function reading a file using the Dataset API
# Then provide the results to the Estimator API
def my_input_fn(file_path, repeat_count=1, shuffle_count=1):
def decode_csv(line):
parsed_line = tf.decode_csv(line, [[0.], [0.], [0.], [0.], [0]])
label = parsed_line[-1] # Last element is the label
del parsed_line[-1] # Delete last element
features = parsed_line # Everything but last elements are the features
d = dict(zip(feature_names, features)), label
return d
dataset = (tf.data.TextLineDataset(file_path) # Read text file
.skip(1) # Skip header row
.map(decode_csv, num_parallel_calls=4) # Decode each line
.cache() # Warning: Caches entire dataset, can cause out of memory
.shuffle(shuffle_count) # Randomize elems (1 == no operation)
.repeat(repeat_count) # Repeats dataset this # times
.batch(32)
.prefetch(1) # Make sure you always have 1 batch ready to serve
)
iterator = dataset.make_one_shot_iterator()
batch_features, batch_labels = iterator.get_next()
return batch_features, batch_labels
def my_model_fn(
features, # This is batch_features from input_fn
labels, # This is batch_labels from input_fn
mode): # And instance of tf.estimator.ModeKeys, see below
if mode == tf.estimator.ModeKeys.PREDICT:
tf.logging.info("my_model_fn: PREDICT, {}".format(mode))
elif mode == tf.estimator.ModeKeys.EVAL:
tf.logging.info("my_model_fn: EVAL, {}".format(mode))
elif mode == tf.estimator.ModeKeys.TRAIN:
tf.logging.info("my_model_fn: TRAIN, {}".format(mode))
# All our inputs are feature columns of type numeric_column
feature_columns = [
tf.feature_column.numeric_column(feature_names[0]),
tf.feature_column.numeric_column(feature_names[1]),
tf.feature_column.numeric_column(feature_names[2]),
tf.feature_column.numeric_column(feature_names[3])
]
# Create the layer of input
input_layer = tf.feature_column.input_layer(features, feature_columns)
# Definition of hidden layer: h1
# We implement it as a fully-connected layer (tf.layers.dense)
# Has 10 neurons, and uses ReLU as the activation function
# Takes input_layer as input
h1 = tf.layers.Dense(10, activation=tf.nn.relu)(input_layer)
# Definition of hidden layer: h2 (this is the logits layer)
# Similar to h1, but takes h1 as input
h2 = tf.layers.Dense(10, activation=tf.nn.relu)(h1)
# Output 'logits' layer is three number = probability distribution
# between Iris Setosa, Versicolor, and Viginica
logits = tf.layers.Dense(3)(h2)
# class_ids will be the model prediction for the class (Iris flower type)
# The output node with the highest value is our prediction
predictions = { 'class_ids': tf.argmax(input=logits, axis=1) }
# 1. Prediction mode
# Return our prediction
if mode == tf.estimator.ModeKeys.PREDICT:
return tf.estimator.EstimatorSpec(mode, predictions=predictions)
# Evaluation and Training mode
# Calculate the loss
loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)
# Calculate the accuracy between the true labels, and our predictions
accuracy = tf.metrics.accuracy(labels, predictions['class_ids'])
# 2. Evaluation mode
# Return our loss (which is used to evaluate our model)
# Set the TensorBoard scalar my_accurace to the accuracy
# Obs: This function only sets value during mode == ModeKeys.EVAL
# To set values during training, see tf.summary.scalar
if mode == tf.estimator.ModeKeys.EVAL:
return tf.estimator.EstimatorSpec(
mode,
loss=loss,
eval_metric_ops={'my_accuracy': accuracy})
# If mode is not PREDICT nor EVAL, then we must be in TRAIN
assert mode == tf.estimator.ModeKeys.TRAIN, "TRAIN is only ModeKey left"
# 3. Training mode
# Default optimizer for DNNClassifier: Adagrad with learning rate=0.05
# Our objective (train_op) is to minimize loss
# Provide global step counter (used to count gradient updates)
optimizer = tf.train.AdagradOptimizer(0.05)
train_op = optimizer.minimize(
loss,
global_step=tf.train.get_global_step())
# Set the TensorBoard scalar my_accuracy to the accuracy
# Obs: This function only sets the value during mode == ModeKeys.TRAIN
# To set values during evaluation, see eval_metrics_ops
tf.summary.scalar('my_accuracy', accuracy[1])
# Return training operations: loss and train_op
return tf.estimator.EstimatorSpec(
mode,
loss=loss,
train_op=train_op)
# Create a custom estimator using my_model_fn to define the model
tf.logging.info("Before classifier construction")
classifier = tf.estimator.Estimator(
model_fn=my_model_fn,
model_dir=PATH) # Path to where checkpoints etc are stored
tf.logging.info("...done constructing classifier")
# 500 epochs = 500 * 120 records [60000] = (500 * 120) / 32 batches = 1875 batches
# 4 epochs = 4 * 30 records = (4 * 30) / 32 batches = 3.75 batches
# Train our model, use the previously function my_input_fn
# Input to training is a file with training example
# Stop training after 8 iterations of train data (epochs)
tf.logging.info("Before classifier.train")
classifier.train(
input_fn=lambda: my_input_fn(FILE_TRAIN, 500, 256))
tf.logging.info("...done classifier.train")
# Evaluate our model using the examples contained in FILE_TEST
# Return value will contain evaluation_metrics such as: loss & average_loss
tf.logging.info("Before classifier.evaluate")
evaluate_result = classifier.evaluate(
input_fn=lambda: my_input_fn(FILE_TEST, 4))
tf.logging.info("...done classifier.evaluate")
tf.logging.info("Evaluation results")
for key in evaluate_result:
tf.logging.info(" {}, was: {}".format(key, evaluate_result[key]))
# Predict the type of some Iris flowers.
# Let's predict the examples in FILE_TEST, repeat only once.
predict_results = classifier.predict(
input_fn=lambda: my_input_fn(FILE_TEST, 1))
tf.logging.info("Prediction on test file")
for prediction in predict_results:
# Will print the predicted class, i.e: 0, 1, or 2 if the prediction
# is Iris Setosa, Vericolor, Virginica, respectively.
tf.logging.info("...{}".format(prediction["class_ids"]))
# Let create a dataset for prediction
# We've taken the first 3 examples in FILE_TEST
prediction_input = [[5.9, 3.0, 4.2, 1.5], # -> 1, Iris Versicolor
[6.9, 3.1, 5.4, 2.1], # -> 2, Iris Virginica
[5.1, 3.3, 1.7, 0.5]] # -> 0, Iris Setosa
def new_input_fn():
def decode(x):
x = tf.split(x, 4) # Need to split into our 4 features
return dict(zip(feature_names, x)) # To build a dict of them
dataset = tf.data.Dataset.from_tensor_slices(prediction_input)
dataset = dataset.map(decode)
iterator = dataset.make_one_shot_iterator()
next_feature_batch = iterator.get_next()
return next_feature_batch, None # In prediction, we have no labels
# Predict all our prediction_input
predict_results = classifier.predict(input_fn=new_input_fn)
# Print results
tf.logging.info("Predictions on memory")
for idx, prediction in enumerate(predict_results):
type = prediction["class_ids"] # Get the predicted class (index)
if type == 0:
tf.logging.info("...I think: {}, is Iris Setosa".format(prediction_input[idx]))
elif type == 1:
tf.logging.info("...I think: {}, is Iris Versicolor".format(prediction_input[idx]))
else:
tf.logging.info("...I think: {}, is Iris Virginica".format(prediction_input[idx]))
# Copyright 2017 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
# This is the complete code for the following blogpost:
# https://developers.googleblog.com/2017/09/introducing-tensorflow-datasets.html
# (https://goo.gl/Ujm2Ep)
import os
import six.moves.urllib.request as request
import tensorflow as tf
from distutils.version import StrictVersion
# Check that we have correct TensorFlow version installed
tf_version = tf.__version__
print("TensorFlow version: {}".format(tf_version))
assert StrictVersion("1.4") <= StrictVersion(tf_version), "TensorFlow r1.4 or later is needed"
# Windows users: You only need to change PATH, rest is platform independent
PATH = "/tmp/tf_dataset_and_estimator_apis"
# Fetch and store Training and Test dataset files
PATH_DATASET = PATH + os.sep + "dataset"
FILE_TRAIN = PATH_DATASET + os.sep + "iris_training.csv"
FILE_TEST = PATH_DATASET + os.sep + "iris_test.csv"
URL_TRAIN = "http://download.tensorflow.org/data/iris_training.csv"
URL_TEST = "http://download.tensorflow.org/data/iris_test.csv"
def download_dataset(url, file):
if not os.path.exists(PATH_DATASET):
os.makedirs(PATH_DATASET)
if not os.path.exists(file):
data = request.urlopen(url).read()
with open(file, "wb") as f:
f.write(data)
f.close()
download_dataset(URL_TRAIN, FILE_TRAIN)
download_dataset(URL_TEST, FILE_TEST)
tf.logging.set_verbosity(tf.logging.INFO)
# The CSV features in our training & test data
feature_names = [
'SepalLength',
'SepalWidth',
'PetalLength',
'PetalWidth']
# Create an input function reading a file using the Dataset API
# Then provide the results to the Estimator API
def my_input_fn(file_path, perform_shuffle=False, repeat_count=1):
def decode_csv(line):
parsed_line = tf.decode_csv(line, [[0.], [0.], [0.], [0.], [0]])
label = parsed_line[-1] # Last element is the label
del parsed_line[-1] # Delete last element
features = parsed_line # Everything but last elements are the features
d = dict(zip(feature_names, features)), label
return d
dataset = (tf.data.TextLineDataset(file_path) # Read text file
.skip(1) # Skip header row
.map(decode_csv)) # Transform each elem by applying decode_csv fn
if perform_shuffle:
# Randomizes input using a window of 256 elements (read into memory)
dataset = dataset.shuffle(buffer_size=256)
dataset = dataset.repeat(repeat_count) # Repeats dataset this # times
dataset = dataset.batch(32) # Batch size to use
iterator = dataset.make_one_shot_iterator()
batch_features, batch_labels = iterator.get_next()
return batch_features, batch_labels
next_batch = my_input_fn(FILE_TRAIN, True) # Will return 32 random elements
# Create the feature_columns, which specifies the input to our model
# All our input features are numeric, so use numeric_column for each one
feature_columns = [tf.feature_column.numeric_column(k) for k in feature_names]
# Create a deep neural network regression classifier
# Use the DNNClassifier pre-made estimator
classifier = tf.estimator.DNNClassifier(
feature_columns=feature_columns, # The input features to our model
hidden_units=[10, 10], # Two layers, each with 10 neurons
n_classes=3,
model_dir=PATH) # Path to where checkpoints etc are stored
# Train our model, use the previously defined function my_input_fn
# Input to training is a file with training example
# Stop training after 8 iterations of train data (epochs)
classifier.train(
input_fn=lambda: my_input_fn(FILE_TRAIN, True, 8))
# Evaluate our model using the examples contained in FILE_TEST
# Return value will contain evaluation_metrics such as: loss & average_loss
evaluate_result = classifier.evaluate(
input_fn=lambda: my_input_fn(FILE_TEST, False, 4))
print("Evaluation results")
for key in evaluate_result:
print(" {}, was: {}".format(key, evaluate_result[key]))
# Predict the type of some Iris flowers.
# Let's predict the examples in FILE_TEST, repeat only once.
predict_results = classifier.predict(
input_fn=lambda: my_input_fn(FILE_TEST, False, 1))
print("Predictions on test file")
for prediction in predict_results:
# Will print the predicted class, i.e: 0, 1, or 2 if the prediction
# is Iris Sentosa, Vericolor, Virginica, respectively.
print(prediction["class_ids"][0])
# Let create a dataset for prediction
# We've taken the first 3 examples in FILE_TEST
prediction_input = [[5.9, 3.0, 4.2, 1.5], # -> 1, Iris Versicolor
[6.9, 3.1, 5.4, 2.1], # -> 2, Iris Virginica
[5.1, 3.3, 1.7, 0.5]] # -> 0, Iris Sentosa
def new_input_fn():
def decode(x):
x = tf.split(x, 4) # Need to split into our 4 features
return dict(zip(feature_names, x)) # To build a dict of them
dataset = tf.data.Dataset.from_tensor_slices(prediction_input)
dataset = dataset.map(decode)
iterator = dataset.make_one_shot_iterator()
next_feature_batch = iterator.get_next()
return next_feature_batch, None # In prediction, we have no labels
# Predict all our prediction_input
predict_results = classifier.predict(input_fn=new_input_fn)
# Print results
print("Predictions:")
for idx, prediction in enumerate(predict_results):
type = prediction["class_ids"][0] # Get the predicted class (index)
if type == 0:
print(" I think: {}, is Iris Sentosa".format(prediction_input[idx]))
elif type == 1:
print(" I think: {}, is Iris Versicolor".format(prediction_input[idx]))
else:
print(" I think: {}, is Iris Virginica".format(prediction_input[idx]))
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Overview"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This example demonstrates the use `tf.feature_column.crossed_column` on some simulated Atlanta housing price data. \n",
"This spatial data is used primarily so the results can be easily visualized. \n",
"\n",
"These functions are designed primarily for categorical data, not to build interpolation tables. \n",
"\n",
"If you actually want to build smart interpolation tables in TensorFlow you may want to consider [TensorFlow Lattice](https://research.googleblog.com/2017/10/tensorflow-lattice-flexibility.html)."
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "yEHBFimYk-Mu"
},
"source": [
"# Imports"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
},
"colab_type": "code",
"collapsed": true,
"id": "DiAklWTFk-My"
},
"outputs": [],
"source": [
"import os\n",
"import subprocess\n",
"import tempfile\n",
"\n",
"import tensorflow as tf\n",
"import numpy as np\n",
"import matplotlib as mpl\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
},
"colab_type": "code",
"collapsed": true,
"id": "fHqxuCUu8Bvm"
},
"outputs": [],
"source": [
"assert tf.VERSION.split('.') >= ['1','4']"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%matplotlib inline\n",
"mpl.rcParams['figure.figsize'] = 12, 6\n",
"mpl.rcParams['image.cmap'] = 'viridis'"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
},
"colab_type": "code",
"collapsed": true,
"id": "Oj4Jv4Pik-M1"
},
"outputs": [],
"source": [
"logdir = tempfile.mkdtemp()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
},
"output_extras": [
{}
]
},
"colab_type": "code",
"id": "cTrSkk1zmvO0",
"outputId": "41532b3b-2bf8-4abb-bc46-a92c76fe70f8"
},
"outputs": [],
"source": [
"logdir"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "p3me9zPGk-M3"
},
"source": [
"# Start TensorBoard\n",
"The following command will kill all running TensorBoard processes, and start a new one monitoring to the above logdir. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
},
"base_uri": "https://localhost:8080/",
"height": 34,
"output_extras": [
{}
]
},
"colab_type": "code",
"executionInfo": {
"elapsed": 327,
"status": "ok",
"timestamp": 1508962289209,
"user": {
"displayName": "Mark Daoust",
"photoUrl": "//lh5.googleusercontent.com/-2bdrhkqhwhc/AAAAAAAAAAI/AAAAAAAAAYY/WEdKp4OXSFY/s50-c-k-no/photo.jpg",
"userId": "106546680081284977106"
},
"user_tz": 240
},
"id": "umxoWdz9k-M3",
"outputId": "e2d2af2f-e56f-4b5e-aa62-bd9119966b53"
},
"outputs": [],
"source": [
"subprocess.Popen(['pkill','-f','tensorboard'])\n",
"subprocess.Popen(['tensorboard', '--logdir', logdir])"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "WFYz5eg1k-M7"
},
"source": [
"# Build Synthetic Data"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
},
"colab_type": "code",
"collapsed": true,
"id": "F3ouYc9N9zW3"
},
"outputs": [],
"source": [
"# Define the grid\n",
"min_latitude = 33.641336\n",
"max_latitude = 33.887157\n",
"delta_latitude = max_latitude-min_latitude\n",
"\n",
"min_longitude = -84.558798\n",
"max_longitude = -84.287259\n",
"delta_longitude = max_longitude-min_longitude\n",
"\n",
"resolution = 100"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# Use RandomState so the behavior is repeatable. \n",
"R = np.random.RandomState(1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
},
"colab_type": "code",
"collapsed": true,
"id": "JQ7wXpURk-M8"
},
"outputs": [],
"source": [
"# The price data will be a sum of Gaussians, at random locations.\n",
"n_centers = 20\n",
"centers = R.rand(n_centers, 2) # shape: (centers, dimensions)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
},
"colab_type": "code",
"collapsed": true,
"id": "nR1wQiqSk-NA"
},
"outputs": [],
"source": [
"# Each Gaussian has a maximum price contribution, at the center.\n",
"# Price_\n",
"price_delta = 0.5+2*R.rand(n_centers)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
},
"colab_type": "code",
"collapsed": true,
"id": "rGX3j-DOk-NC"
},
"outputs": [],
"source": [
"# Each Gaussian also has a standard-deviation and variance.\n",
"std = 0.2*R.rand(n_centers) # shape: (centers)\n",
"var = std**2"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
},
"colab_type": "code",
"collapsed": true,
"id": "kWu2ba4Tk-NE"
},
"outputs": [],
"source": [
"def price(latitude, longitude):\n",
" # Convert latitude, longitude to x,y in [0,1]\n",
" x = (longitude - min_longitude)/delta_longitude\n",
" y = (latitude - min_latitude)/delta_latitude\n",
" \n",
" # Cache the shape, and flatten the inputs.\n",
" shape = x.shape\n",
" assert y.shape == x.shape\n",
" x = x.flatten()\n",
" y = y.flatten()\n",
" \n",
" # Convert x, y examples into an array with shape (examples, dimensions)\n",
" xy = np.array([x,y]).T\n",
"\n",
" # Calculate the square distance from each example to each center. \n",
" components2 = (xy[:,None,:] - centers[None,:,:])**2 # shape: (examples, centers, dimensions)\n",
" r2 = components2.sum(axis=2) # shape: (examples, centers)\n",
" \n",
" # Calculate the z**2 for each example from each center.\n",
" z2 = r2/var[None,:]\n",
" price = (np.exp(-z2)*price_delta).sum(1) # shape: (examples,)\n",
" \n",
" # Restore the original shape.\n",
" return price.reshape(shape)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
},
"colab_type": "code",
"collapsed": true,
"id": "BPoSndW8k-NG"
},
"outputs": [],
"source": [
"# Build the grid. We want `resolution` cells between `min` and `max` on each dimension\n",
"# so we need `resolution+1` evenly spaced edges. The centers are at the average of the\n",
"# upper and lower edge. \n",
"\n",
"latitude_edges = np.linspace(min_latitude, max_latitude, resolution+1)\n",
"latitude_centers = (latitude_edges[:-1] + latitude_edges[1:])/2\n",
"\n",
"longitude_edges = np.linspace(min_longitude, max_longitude, resolution+1)\n",
"longitude_centers = (longitude_edges[:-1] + longitude_edges[1:])/2\n",
"\n",
"latitude_grid, longitude_grid = np.meshgrid(\n",
" latitude_centers,\n",
" longitude_centers)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
},
"output_extras": [
{}
]
},
"colab_type": "code",
"id": "0Y5fSCpWk-NI",
"outputId": "35737491-93bd-4911-cb6e-8163849983a3"
},
"outputs": [],
"source": [
"# Evaluate the price at each center-point\n",
"actual_price_grid = price(latitude_grid, longitude_grid)\n",
"\n",
"price_min = actual_price_grid.min()\n",
"price_max = actual_price_grid.max()\n",
"price_mean = actual_price_grid.mean()\n",
"price_mean"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
},
"colab_type": "code",
"collapsed": true,
"id": "wN2wMUOck-NK"
},
"outputs": [],
"source": [
"def show_price(price):\n",
" plt.imshow(\n",
" price, \n",
" # The color axis goes from `price_min` to `price_max`.\n",
" vmin=price_min, vmax=price_max,\n",
" # Put the image at the correct latitude and longitude.\n",
" extent=(min_longitude, max_longitude, min_latitude, max_latitude), \n",
" # Make the image square.\n",
" aspect = 1.0*delta_longitude/delta_latitude)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
},
"base_uri": "https://localhost:8080/",
"height": 592,
"output_extras": [
{}
]
},
"colab_type": "code",
"executionInfo": {
"elapsed": 678,
"status": "ok",
"timestamp": 1508962293265,
"user": {
"displayName": "Mark Daoust",
"photoUrl": "//lh5.googleusercontent.com/-2bdrhkqhwhc/AAAAAAAAAAI/AAAAAAAAAYY/WEdKp4OXSFY/s50-c-k-no/photo.jpg",
"userId": "106546680081284977106"
},
"user_tz": 240
},
"id": "FkHXxJGuAsC1",
"outputId": "40bf2c0f-51b0-4026-a275-c3669e5366cc"
},
"outputs": [],
"source": [
"show_price(actual_price_grid)"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "miDtqLRek-NM"
},
"source": [
"# Build Datasets"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
},
"colab_type": "code",
"collapsed": true,
"id": "zqBPKjBvk-NM"
},
"outputs": [],
"source": [
"# For test data we will use the grid centers.\n",
"test_features = {'latitude':latitude_grid.flatten(), 'longitude':longitude_grid.flatten()}\n",
"test_ds = tf.data.Dataset.from_tensor_slices((test_features, \n",
" actual_price_grid.flatten()))\n",
"test_ds = test_ds.cache().batch(512).prefetch(1)\n",
"\n",
"# For training data we will use a set of random points.\n",
"train_latitude = min_latitude + np.random.rand(50000)*delta_latitude\n",
"train_longitude = min_longitude + np.random.rand(50000)*delta_longitude\n",
"train_price = price(train_latitude, train_longitude)\n",
"\n",
"train_features = {'latitude':train_latitude, 'longitude':train_longitude}\n",
"train_ds = tf.data.Dataset.from_tensor_slices((train_features, train_price))\n",
"train_ds = train_ds.cache().repeat().shuffle(100000).batch(512).prefetch(1)\n",
"\n",
"# A shortcut to build an `input_fn` from a `Dataset`\n",
"def in_fn(ds):\n",
" return lambda : ds.make_one_shot_iterator().get_next()\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "i-ToQzSqk-NO"
},
"source": [
"# Generate a plot from an Estimator"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
},
"colab_type": "code",
"collapsed": true,
"id": "N9NmQLUOk-NP"
},
"outputs": [],
"source": [
"def plot_est(est, ds = test_ds):\n",
" # Create two plot axes\n",
" actual, predicted = plt.subplot(1,2,1), plt.subplot(1,2,2)\n",
"\n",
" # Plot the actual price.\n",
" plt.sca(actual)\n",
" show_price(actual_price_grid.reshape(resolution, resolution))\n",
" \n",
" # Generate predictions over the grid from the estimator.\n",
" pred = est.predict(in_fn(ds))\n",
" # Convert them to a numpy array.\n",
" pred = np.fromiter((item['predictions'] for item in pred), np.float32)\n",
" # Plot the predictions on the secodn axis.\n",
" plt.sca(predicted)\n",
" show_price(pred.reshape(resolution, resolution))"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "gfgngu0lk-NQ"
},
"source": [
"# Using `numeric_column` with DNNRegressor\n",
"Important: Pure categorical data doesn't the spatial relationships that make this example possible. Embeddings are a way your model can learn spatial relationships."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
},
"base_uri": "https://localhost:8080/",
"height": 2010,
"output_extras": [
{},
{}
]
},
"colab_type": "code",
"executionInfo": {
"elapsed": 8234,
"status": "ok",
"timestamp": 1508962479411,
"user": {
"displayName": "Mark Daoust",
"photoUrl": "//lh5.googleusercontent.com/-2bdrhkqhwhc/AAAAAAAAAAI/AAAAAAAAAYY/WEdKp4OXSFY/s50-c-k-no/photo.jpg",
"userId": "106546680081284977106"
},
"user_tz": 240
},
"id": "On-_j4Jtk-NR",
"outputId": "1c18ba56-7246-4096-c32d-822c2fe3dd36"
},
"outputs": [],
"source": [
"# Use `normalizer_fn` so that the model only sees values in [0, 1]\n",
"norm_latitude = lambda latitude:(latitude-min_latitude)/delta_latitude - 0.5\n",
"norm_longitude = lambda longitude:(longitude-min_longitude)/delta_longitude - 0.5\n",
"\n",
"fc = [tf.feature_column.numeric_column('latitude', normalizer_fn = norm_latitude), \n",
" tf.feature_column.numeric_column('longitude', normalizer_fn = norm_longitude)]\n",
"\n",
"# Build and train the Estimator\n",
"est = tf.estimator.DNNRegressor(\n",
" hidden_units=[100,100], \n",
" feature_columns=fc, \n",
" model_dir = os.path.join(logdir,'DNN'))\n",
"\n",
"est.train(in_fn(train_ds), steps = 5000)\n",
"est.evaluate(in_fn(test_ds))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
},
"base_uri": "https://localhost:8080/",
"height": 388,
"output_extras": [
{},
{}
]
},
"colab_type": "code",
"executionInfo": {
"elapsed": 1002,
"status": "ok",
"timestamp": 1508962552800,
"user": {
"displayName": "Mark Daoust",
"photoUrl": "//lh5.googleusercontent.com/-2bdrhkqhwhc/AAAAAAAAAAI/AAAAAAAAAYY/WEdKp4OXSFY/s50-c-k-no/photo.jpg",
"userId": "106546680081284977106"
},
"user_tz": 240
},
"id": "WTcIX78Tk-NV",
"outputId": "8d08be57-7c37-4268-e38a-9675978567ff"
},
"outputs": [],
"source": [
"plot_est(est)"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "WIlTd5VEk-NZ"
},
"source": [
"# Using `bucketized_column`"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
},
"base_uri": "https://localhost:8080/",
"height": 2010,
"output_extras": [
{},
{}
]
},
"colab_type": "code",
"executionInfo": {
"elapsed": 9805,
"status": "ok",
"timestamp": 1508962565572,
"user": {
"displayName": "Mark Daoust",
"photoUrl": "//lh5.googleusercontent.com/-2bdrhkqhwhc/AAAAAAAAAAI/AAAAAAAAAYY/WEdKp4OXSFY/s50-c-k-no/photo.jpg",
"userId": "106546680081284977106"
},
"user_tz": 240
},
"id": "NdKt4g2Kk-NZ",
"outputId": "a72e8a55-0239-4b42-e66b-a57ba79fb47b"
},
"outputs": [],
"source": [
"# Bucketize the latitude and longitude usig the `edges`\n",
"latitude_bucket_fc = tf.feature_column.bucketized_column(\n",
" tf.feature_column.numeric_column('latitude'), \n",
" list(latitude_edges))\n",
"\n",
"longitude_bucket_fc = tf.feature_column.bucketized_column(\n",
" tf.feature_column.numeric_column('longitude'),\n",
" list(longitude_edges))\n",
"\n",
"fc = [\n",
" latitude_bucket_fc,\n",
" longitude_bucket_fc]\n",
"\n",
"# Build and train the Estimator.\n",
"est = tf.estimator.LinearRegressor(fc, model_dir = os.path.join(logdir,'separable'))\n",
"est.train(in_fn(train_ds), steps = 5000)\n",
"est.evaluate(in_fn(test_ds))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
},
"base_uri": "https://localhost:8080/",
"height": 388,
"output_extras": [
{},
{}
]
},
"colab_type": "code",
"executionInfo": {
"elapsed": 1152,
"status": "ok",
"timestamp": 1508962568631,
"user": {
"displayName": "Mark Daoust",
"photoUrl": "//lh5.googleusercontent.com/-2bdrhkqhwhc/AAAAAAAAAAI/AAAAAAAAAYY/WEdKp4OXSFY/s50-c-k-no/photo.jpg",
"userId": "106546680081284977106"
},
"user_tz": 240
},
"id": "j4lhsk5rk-Nc",
"outputId": "f12b5ba5-1d28-46b2-b1d6-322a60ba40d9"
},
"outputs": [],
"source": [
"plot_est(est)"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "G-QLbA0hKBbY"
},
"source": [
"# Using `crossed_column` on its own.\n",
"The single-cell \"holes\" in the figure are caused by cells which do not contain examples."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
},
"base_uri": "https://localhost:8080/",
"height": 2010,
"output_extras": [
{},
{}
]
},
"colab_type": "code",
"executionInfo": {
"elapsed": 11707,
"status": "ok",
"timestamp": 1508962619513,
"user": {
"displayName": "Mark Daoust",
"photoUrl": "//lh5.googleusercontent.com/-2bdrhkqhwhc/AAAAAAAAAAI/AAAAAAAAAYY/WEdKp4OXSFY/s50-c-k-no/photo.jpg",
"userId": "106546680081284977106"
},
"user_tz": 240
},
"id": "JoIXtYykKJei",
"outputId": "08e45310-f006-454a-8bb4-4f14466c5013"
},
"outputs": [],
"source": [
"# Cross the bucketized columns, using 5000 hash bins (for an average weight sharing of 2).\n",
"crossed_lat_lon_fc = tf.feature_column.crossed_column(\n",
" [latitude_bucket_fc, longitude_bucket_fc], int(5e3))\n",
"\n",
"fc = [crossed_lat_lon_fc]\n",
"\n",
"# Build and train the Estimator.\n",
"est = tf.estimator.LinearRegressor(fc, model_dir=os.path.join(logdir, 'crossed'))\n",
"\n",
"est.train(in_fn(train_ds), steps = 5000)\n",
"est.evaluate(in_fn(test_ds))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
},
"base_uri": "https://localhost:8080/",
"height": 388,
"output_extras": [
{},
{}
]
},
"colab_type": "code",
"executionInfo": {
"elapsed": 1112,
"status": "ok",
"timestamp": 1508962600110,
"user": {
"displayName": "Mark Daoust",
"photoUrl": "//lh5.googleusercontent.com/-2bdrhkqhwhc/AAAAAAAAAAI/AAAAAAAAAYY/WEdKp4OXSFY/s50-c-k-no/photo.jpg",
"userId": "106546680081284977106"
},
"user_tz": 240
},
"id": "R-itu9itLe0K",
"outputId": "449a6d84-c6f5-4582-f8e3-0f007ae68e8a",
"scrolled": false
},
"outputs": [],
"source": [
"plot_est(est)"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "KHJ_KsRUk-Nj"
},
"source": [
"# Using raw categories with `crossed_column` \n",
"The model generalizes better if it also has access to the raw categories, outside of the cross. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
},
"base_uri": "https://localhost:8080/",
"height": 2010,
"output_extras": [
{},
{}
]
},
"colab_type": "code",
"executionInfo": {
"elapsed": 13233,
"status": "ok",
"timestamp": 1508963622115,
"user": {
"displayName": "Mark Daoust",
"photoUrl": "//lh5.googleusercontent.com/-2bdrhkqhwhc/AAAAAAAAAAI/AAAAAAAAAYY/WEdKp4OXSFY/s50-c-k-no/photo.jpg",
"userId": "106546680081284977106"
},
"user_tz": 240
},
"id": "ukHo6NrTk-Nk",
"outputId": "12fba55e-c496-4007-b7b7-11b1aad38ba8"
},
"outputs": [],
"source": [
"fc = [\n",
" latitude_bucket_fc,\n",
" longitude_bucket_fc,\n",
" crossed_lat_lon_fc]\n",
"\n",
"# Build and train the Estimator.\n",
"est = tf.estimator.LinearRegressor(fc, model_dir=os.path.join(logdir, 'both'))\n",
"est.train(in_fn(train_ds), steps = 5000)\n",
"est.evaluate(in_fn(test_ds))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
},
"base_uri": "https://localhost:8080/",
"height": 388,
"output_extras": [
{},
{}
]
},
"colab_type": "code",
"executionInfo": {
"elapsed": 1307,
"status": "ok",
"timestamp": 1508963623450,
"user": {
"displayName": "Mark Daoust",
"photoUrl": "//lh5.googleusercontent.com/-2bdrhkqhwhc/AAAAAAAAAAI/AAAAAAAAAYY/WEdKp4OXSFY/s50-c-k-no/photo.jpg",
"userId": "106546680081284977106"
},
"user_tz": 240
},
"id": "QjOwalvDk-Nm",
"outputId": "f0a520a1-8253-494e-f3c8-2e6df168100a"
},
"outputs": [],
"source": [
"plot_est(est)"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "Mx66A5ETk-Ns"
},
"source": [
"# Open TensorBoard"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
},
"base_uri": "https://localhost:8080/",
"height": 820,
"output_extras": [
{
"item_id": 1
}
]
},
"colab_type": "code",
"executionInfo": {
"elapsed": 478,
"status": "ok",
"timestamp": 1508986589529,
"user": {
"displayName": "Mark Daoust",
"photoUrl": "//lh5.googleusercontent.com/-2bdrhkqhwhc/AAAAAAAAAAI/AAAAAAAAAYY/WEdKp4OXSFY/s50-c-k-no/photo.jpg",
"userId": "106546680081284977106"
},
"user_tz": 240
},
"id": "fESYrJamm_Z5",
"outputId": "d982a677-a217-491b-ef85-93f932e6afc5"
},
"outputs": [],
"source": [
"%%html\n",
"<iframe width=\"900\" height=\"800\" src=\"http://0.0.0.0:6006#scalars&_smoothingWeight=0.85\" frameborder=\"0\"></iframe>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
},
"colab_type": "code",
"collapsed": true,
"id": "_YHrJneHnA9K"
},
"outputs": [],
"source": []
}
],
"metadata": {
"colab": {
"collapsed_sections": [],
"default_view": {},
"name": "Housing Prices (1).ipynb",
"provenance": [],
"version": "0.3.2",
"views": {}
},
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.10"
}
},
"nbformat": 4,
"nbformat_minor": 1
}
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "ULKtInm7dAMK"
},
"source": [
"# Image Segmentation with `tf.keras`"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "7Plun_k1dAML"
},
"source": [
"<table class=\"tfo-notebook-buttons\" align=\"left\"><td>\n",
"<a target=\"_blank\" href=\"http://colab.research.google.com/github/tensorflow/models/blob/master/samples/outreach/blogs/segmentation_blogpost/image_segmentation.ipynb\">\n",
" <img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a> \n",
"</td><td>\n",
"<a target=\"_blank\" href=\"https://github.com/tensorflow/models/blob/master/samples/outreach/blogs/segmentation_blogpost/image_segmentation.ipynb\"><img width=32px src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View source on GitHub</a></td></table>"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "cl79rk4KKol8"
},
"source": [
"In this tutorial we will learn how to segment images. **Segmentation** is the process of generating pixel-wise segmentations giving the class of the object visible at each pixel. For example, we could be identifying the location and boundaries of people within an image or identifying cell nuclei from an image. Formally, image segmentation refers to the process of partitioning an image into a set of pixels that we desire to identify (our target) and the background. \n",
"\n",
"Specifically, in this tutorial we will be using the [Kaggle Carvana Image Masking Challenge Dataset](https://www.kaggle.com/c/carvana-image-masking-challenge). \n",
"\n",
"This dataset contains a large number of car images, with each car taken from different angles. In addition, for each car image, we have an associated manually cutout mask; our task will be to automatically create these cutout masks for unseen data. \n",
"\n",
"## Specific concepts that will be covered:\n",
"In the process, we will build practical experience and develop intuition around the following concepts:\n",
"* **[Functional API](https://keras.io/getting-started/functional-api-guide/)** - we will be implementing UNet, a convolutional network model classically used for biomedical image segmentation with the Functional API. \n",
" * This model has layers that require multiple input/outputs. This requires the use of the functional API\n",
" * Check out the original [paper](https://arxiv.org/abs/1505.04597), \n",
"U-Net: Convolutional Networks for Biomedical Image Segmentation by Olaf Ronneberger!\n",
"* **Custom Loss Functions and Metrics** - We'll implement a custom loss function using binary [**cross entropy**](https://developers.google.com/machine-learning/glossary/#cross-entropy) and **dice loss**. We'll also implement **dice coefficient** (which is used for our loss) and **mean intersection over union**, that will help us monitor our training process and judge how well we are performing. \n",
"* **Saving and loading keras models** - We'll save our best model to disk. When we want to perform inference/evaluate our model, we'll load in the model from disk. \n",
"\n",
"### We will follow the general workflow:\n",
"1. Visualize data/perform some exploratory data analysis\n",
"2. Set up data pipeline and preprocessing\n",
"3. Build model\n",
"4. Train model\n",
"5. Evaluate model\n",
"6. Repeat\n",
"\n",
"**Audience:** This post is geared towards intermediate users who are comfortable with basic machine learning concepts.\n",
"Note that if you wish to run this notebook, it is highly recommended that you do so with a GPU. \n",
"\n",
"**Time Estimated**: 60 min\n",
"\n",
"By: Raymond Yuan, Software Engineering Intern"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "bJcQiA3OdCY6"
},
"outputs": [],
"source": [
"!pip install kaggle"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "ODNLPGHKKgr-"
},
"outputs": [],
"source": [
"import os\n",
"import glob\n",
"import zipfile\n",
"import functools\n",
"\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"import matplotlib as mpl\n",
"mpl.rcParams['axes.grid'] = False\n",
"mpl.rcParams['figure.figsize'] = (12,12)\n",
"\n",
"from sklearn.model_selection import train_test_split\n",
"import matplotlib.image as mpimg\n",
"import pandas as pd\n",
"from PIL import Image\n"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "YQ9VRReUQxXi"
},
"outputs": [],
"source": [
"import tensorflow as tf\n",
"import tensorflow.contrib as tfcontrib\n",
"from tensorflow.python.keras import layers\n",
"from tensorflow.python.keras import losses\n",
"from tensorflow.python.keras import models\n",
"from tensorflow.python.keras import backend as K "
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "RW9gk331S0KA"
},
"source": [
"# Get all the files \n",
"Since this tutorial will be using a dataset from Kaggle, it requires [creating an API Token](https://github.com/Kaggle/kaggle-api#api-credentials) for your Kaggle account, and uploading it. "
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "sAVM1ZTmdAMR"
},
"outputs": [],
"source": [
"import os\n",
"\n",
"# Upload the API token.\n",
"def get_kaggle_credentials():\n",
" token_dir = os.path.join(os.path.expanduser(\"~\"),\".kaggle\")\n",
" token_file = os.path.join(token_dir, \"kaggle.json\")\n",
" if not os.path.isdir(token_dir):\n",
" os.mkdir(token_dir)\n",
" try:\n",
" with open(token_file,'r') as f:\n",
" pass\n",
" except IOError as no_file:\n",
" try:\n",
" from google.colab import files\n",
" except ImportError:\n",
" raise no_file\n",
" \n",
" uploaded = files.upload()\n",
" \n",
" if \"kaggle.json\" not in uploaded:\n",
" raise ValueError(\"You need an API key! see: \"\n",
" \"https://github.com/Kaggle/kaggle-api#api-credentials\")\n",
" with open(token_file, \"wb\") as f:\n",
" f.write(uploaded[\"kaggle.json\"])\n",
" os.chmod(token_file, 600)\n",
"\n",
"get_kaggle_credentials()\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "gh6jkMp8dN5B"
},
"source": [
"Only import kaggle after adding the credentials."
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "EoWJ1hb9dOV_"
},
"outputs": [],
"source": [
"import kaggle"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "wC-byMdadAMT"
},
"source": [
"### We'll download the data from Kaggle\n",
"Caution, large download ahead - downloading all files will require 14GB of diskspace. "
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "6MOTOyU3dAMU"
},
"outputs": [],
"source": [
"competition_name = 'carvana-image-masking-challenge'"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "3gJSCmWjdAMW"
},
"outputs": [],
"source": [
"# Download data from Kaggle and unzip the files of interest. \n",
"def load_data_from_zip(competition, file):\n",
" with zipfile.ZipFile(os.path.join(competition, file), \"r\") as zip_ref:\n",
" unzipped_file = zip_ref.namelist()[0]\n",
" zip_ref.extractall(competition)\n",
"\n",
"def get_data(competition):\n",
" kaggle.api.competition_download_files(competition, competition)\n",
" load_data_from_zip(competition, 'train.zip')\n",
" load_data_from_zip(competition, 'train_masks.zip')\n",
" load_data_from_zip(competition, 'train_masks.csv.zip')\n",
" \n"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "l5SZJKPRdXNX"
},
"source": [
"You must [accept the competition rules](https://www.kaggle.com/c/carvana-image-masking-challenge/rules) before downloading the data."
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "_SsQjuN2dWmU"
},
"outputs": [],
"source": [
"get_data(competition_name)"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "wT1kb3q0ghhi"
},
"outputs": [],
"source": [
"img_dir = os.path.join(competition_name, \"train\")\n",
"label_dir = os.path.join(competition_name, \"train_masks\")"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "9ej-e6cqmRgd"
},
"outputs": [],
"source": [
"df_train = pd.read_csv(os.path.join(competition_name, 'train_masks.csv'))\n",
"ids_train = df_train['img'].map(lambda s: s.split('.')[0])"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "33i4xFXweztH"
},
"outputs": [],
"source": [
"x_train_filenames = []\n",
"y_train_filenames = []\n",
"for img_id in ids_train:\n",
" x_train_filenames.append(os.path.join(img_dir, \"{}.jpg\".format(img_id)))\n",
" y_train_filenames.append(os.path.join(label_dir, \"{}_mask.gif\".format(img_id)))"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "DtutNudKbf70"
},
"outputs": [],
"source": [
"x_train_filenames, x_val_filenames, y_train_filenames, y_val_filenames = \\\n",
" train_test_split(x_train_filenames, y_train_filenames, test_size=0.2, random_state=42)"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "zDycQekHaMqq"
},
"outputs": [],
"source": [
"num_train_examples = len(x_train_filenames)\n",
"num_val_examples = len(x_val_filenames)\n",
"\n",
"print(\"Number of training examples: {}\".format(num_train_examples))\n",
"print(\"Number of validation examples: {}\".format(num_val_examples))"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "Nhda5fkPS3JD"
},
"source": [
"### Here's what the paths look like "
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "Di1N83ArilzR"
},
"outputs": [],
"source": [
"x_train_filenames[:10]"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "Gc-BDv1Zio1z"
},
"outputs": [],
"source": [
"y_train_filenames[:10]"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "mhvDoZkbcUa1"
},
"source": [
"# Visualize\n",
"Let's take a look at some of the examples of different images in our dataset. "
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "qUA6SDLhozjj"
},
"outputs": [],
"source": [
"display_num = 5\n",
"\n",
"r_choices = np.random.choice(num_train_examples, display_num)\n",
"\n",
"plt.figure(figsize=(10, 15))\n",
"for i in range(0, display_num * 2, 2):\n",
" img_num = r_choices[i // 2]\n",
" x_pathname = x_train_filenames[img_num]\n",
" y_pathname = y_train_filenames[img_num]\n",
" \n",
" plt.subplot(display_num, 2, i + 1)\n",
" plt.imshow(mpimg.imread(x_pathname))\n",
" plt.title(\"Original Image\")\n",
" \n",
" example_labels = Image.open(y_pathname)\n",
" label_vals = np.unique(example_labels)\n",
" \n",
" plt.subplot(display_num, 2, i + 2)\n",
" plt.imshow(example_labels)\n",
" plt.title(\"Masked Image\") \n",
" \n",
"plt.suptitle(\"Examples of Images and their Masks\")\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "d4CPgvPiToB_"
},
"source": [
"# Set up "
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "HfeMRgyoa2n6"
},
"source": [
"Let’s begin by setting up some parameters. We’ll standardize and resize all the shapes of the images. We’ll also set up some training parameters: "
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "oeDoiSFlothe"
},
"outputs": [],
"source": [
"img_shape = (256, 256, 3)\n",
"batch_size = 3\n",
"epochs = 5"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "8_d5ATP21npW"
},
"source": [
"Using these exact same parameters may be too computationally intensive for your hardware, so tweak the parameters accordingly. Also, it is important to note that due to the architecture of our UNet version, the size of the image must be evenly divisible by a factor of 32, as we down sample the spatial resolution by a factor of 2 with each `MaxPooling2Dlayer`.\n",
"\n",
"\n",
"If your machine can support it, you will achieve better performance using a higher resolution input image (e.g. 512 by 512) as this will allow more precise localization and less loss of information during encoding. In addition, you can also make the model deeper.\n",
"\n",
"\n",
"Alternatively, if your machine cannot support it, lower the image resolution and/or batch size. Note that lowering the image resolution will decrease performance and lowering batch size will increase training time.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "_HONB9JbXxDM"
},
"source": [
"# Build our input pipeline with `tf.data`\n",
"Since we begin with filenames, we will need to build a robust and scalable data pipeline that will play nicely with our model. If you are unfamiliar with **tf.data** you should check out my other tutorial introducing the concept! \n",
"\n",
"### Our input pipeline will consist of the following steps:\n",
"1. Read the bytes of the file in from the filename - for both the image and the label. Recall that our labels are actually images with each pixel annotated as car or background (1, 0). \n",
"2. Decode the bytes into an image format\n",
"3. Apply image transformations: (optional, according to input parameters)\n",
" * `resize` - Resize our images to a standard size (as determined by eda or computation/memory restrictions)\n",
" * The reason why this is optional is that U-Net is a fully convolutional network (e.g. with no fully connected units) and is thus not dependent on the input size. However, if you choose to not resize the images, you must use a batch size of 1, since you cannot batch variable image size together\n",
" * Alternatively, you could also bucket your images together and resize them per mini-batch to avoid resizing images as much, as resizing may affect your performance through interpolation, etc.\n",
" * `hue_delta` - Adjusts the hue of an RGB image by a random factor. This is only applied to the actual image (not our label image). The `hue_delta` must be in the interval `[0, 0.5]` \n",
" * `horizontal_flip` - flip the image horizontally along the central axis with a 0.5 probability. This transformation must be applied to both the label and the actual image. \n",
" * `width_shift_range` and `height_shift_range` are ranges (as a fraction of total width or height) within which to randomly translate the image either horizontally or vertically. This transformation must be applied to both the label and the actual image. \n",
" * `rescale` - rescale the image by a certain factor, e.g. 1/ 255.\n",
"4. Shuffle the data, repeat the data (so we can iterate over it multiple times across epochs), batch the data, then prefetch a batch (for efficiency).\n",
"\n",
"It is important to note that these transformations that occur in your data pipeline must be symbolic transformations. "
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "EtRA8vILbx2_"
},
"source": [
"#### Why do we do these image transformations?\n",
"This is known as **data augmentation**. Data augmentation \"increases\" the amount of training data by augmenting them via a number of random transformations. During training time, our model would never see twice the exact same picture. This helps prevent [overfitting](https://developers.google.com/machine-learning/glossary/#overfitting) and helps the model generalize better to unseen data."
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "3aGi28u8Cq9M"
},
"source": [
"## Processing each pathname"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "Fb_psznAggwr"
},
"outputs": [],
"source": [
"def _process_pathnames(fname, label_path):\n",
" # We map this function onto each pathname pair \n",
" img_str = tf.read_file(fname)\n",
" img = tf.image.decode_jpeg(img_str, channels=3)\n",
"\n",
" label_img_str = tf.read_file(label_path)\n",
" # These are gif images so they return as (num_frames, h, w, c)\n",
" label_img = tf.image.decode_gif(label_img_str)[0]\n",
" # The label image should only have values of 1 or 0, indicating pixel wise\n",
" # object (car) or not (background). We take the first channel only. \n",
" label_img = label_img[:, :, 0]\n",
" label_img = tf.expand_dims(label_img, axis=-1)\n",
" return img, label_img"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "Y4UE28JiCuOk"
},
"source": [
"## Shifting the image"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "xdY046OqtGVH"
},
"outputs": [],
"source": [
"def shift_img(output_img, label_img, width_shift_range, height_shift_range):\n",
" \"\"\"This fn will perform the horizontal or vertical shift\"\"\"\n",
" if width_shift_range or height_shift_range:\n",
" if width_shift_range:\n",
" width_shift_range = tf.random_uniform([], \n",
" -width_shift_range * img_shape[1],\n",
" width_shift_range * img_shape[1])\n",
" if height_shift_range:\n",
" height_shift_range = tf.random_uniform([],\n",
" -height_shift_range * img_shape[0],\n",
" height_shift_range * img_shape[0])\n",
" # Translate both \n",
" output_img = tfcontrib.image.translate(output_img,\n",
" [width_shift_range, height_shift_range])\n",
" label_img = tfcontrib.image.translate(label_img,\n",
" [width_shift_range, height_shift_range])\n",
" return output_img, label_img"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "qY253aZfCwd2"
},
"source": [
"## Flipping the image randomly "
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "OogLSplstur9"
},
"outputs": [],
"source": [
"def flip_img(horizontal_flip, tr_img, label_img):\n",
" if horizontal_flip:\n",
" flip_prob = tf.random_uniform([], 0.0, 1.0)\n",
" tr_img, label_img = tf.cond(tf.less(flip_prob, 0.5),\n",
" lambda: (tf.image.flip_left_right(tr_img), tf.image.flip_left_right(label_img)),\n",
" lambda: (tr_img, label_img))\n",
" return tr_img, label_img"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "_YIJLIr5Cyyr"
},
"source": [
"## Assembling our transformations into our augment function"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "18WA0Sl3olyn"
},
"outputs": [],
"source": [
"def _augment(img,\n",
" label_img,\n",
" resize=None, # Resize the image to some size e.g. [256, 256]\n",
" scale=1, # Scale image e.g. 1 / 255.\n",
" hue_delta=0, # Adjust the hue of an RGB image by random factor\n",
" horizontal_flip=False, # Random left right flip,\n",
" width_shift_range=0, # Randomly translate the image horizontally\n",
" height_shift_range=0): # Randomly translate the image vertically \n",
" if resize is not None:\n",
" # Resize both images\n",
" label_img = tf.image.resize_images(label_img, resize)\n",
" img = tf.image.resize_images(img, resize)\n",
" \n",
" if hue_delta:\n",
" img = tf.image.random_hue(img, hue_delta)\n",
" \n",
" img, label_img = flip_img(horizontal_flip, img, label_img)\n",
" img, label_img = shift_img(img, label_img, width_shift_range, height_shift_range)\n",
" label_img = tf.to_float(label_img) * scale\n",
" img = tf.to_float(img) * scale \n",
" return img, label_img"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "tkNqQaR2HQbd"
},
"outputs": [],
"source": [
"def get_baseline_dataset(filenames, \n",
" labels,\n",
" preproc_fn=functools.partial(_augment),\n",
" threads=5, \n",
" batch_size=batch_size,\n",
" shuffle=True): \n",
" num_x = len(filenames)\n",
" # Create a dataset from the filenames and labels\n",
" dataset = tf.data.Dataset.from_tensor_slices((filenames, labels))\n",
" # Map our preprocessing function to every element in our dataset, taking\n",
" # advantage of multithreading\n",
" dataset = dataset.map(_process_pathnames, num_parallel_calls=threads)\n",
" if preproc_fn.keywords is not None and 'resize' not in preproc_fn.keywords:\n",
" assert batch_size == 1, \"Batching images must be of the same size\"\n",
"\n",
" dataset = dataset.map(preproc_fn, num_parallel_calls=threads)\n",
" \n",
" if shuffle:\n",
" dataset = dataset.shuffle(num_x)\n",
" \n",
" \n",
" # It's necessary to repeat our data for all epochs \n",
" dataset = dataset.repeat().batch(batch_size)\n",
" return dataset"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "zwtgius5CRKc"
},
"source": [
"## Set up train and validation datasets\n",
"Note that we apply image augmentation to our training dataset but not our validation dataset. "
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "iu5WmYmOwKrV"
},
"outputs": [],
"source": [
"tr_cfg = {\n",
" 'resize': [img_shape[0], img_shape[1]],\n",
" 'scale': 1 / 255.,\n",
" 'hue_delta': 0.1,\n",
" 'horizontal_flip': True,\n",
" 'width_shift_range': 0.1,\n",
" 'height_shift_range': 0.1\n",
"}\n",
"tr_preprocessing_fn = functools.partial(_augment, **tr_cfg)"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "RtzLkDFMpF0T"
},
"outputs": [],
"source": [
"val_cfg = {\n",
" 'resize': [img_shape[0], img_shape[1]],\n",
" 'scale': 1 / 255.,\n",
"}\n",
"val_preprocessing_fn = functools.partial(_augment, **val_cfg)"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "5cNpECdkaafo"
},
"outputs": [],
"source": [
"train_ds = get_baseline_dataset(x_train_filenames,\n",
" y_train_filenames,\n",
" preproc_fn=tr_preprocessing_fn,\n",
" batch_size=batch_size)\n",
"val_ds = get_baseline_dataset(x_val_filenames,\n",
" y_val_filenames, \n",
" preproc_fn=val_preprocessing_fn,\n",
" batch_size=batch_size)"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "Yasuvr5IbFlM"
},
"source": [
"## Let's see if our image augmentor data pipeline is producing expected results"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "hjoUqbPdHQej"
},
"outputs": [],
"source": [
"temp_ds = get_baseline_dataset(x_train_filenames, \n",
" y_train_filenames,\n",
" preproc_fn=tr_preprocessing_fn,\n",
" batch_size=1,\n",
" shuffle=False)\n",
"# Let's examine some of these augmented images\n",
"data_aug_iter = temp_ds.make_one_shot_iterator()\n",
"next_element = data_aug_iter.get_next()\n",
"with tf.Session() as sess: \n",
" batch_of_imgs, label = sess.run(next_element)\n",
"\n",
" # Running next element in our graph will produce a batch of images\n",
" plt.figure(figsize=(10, 10))\n",
" img = batch_of_imgs[0]\n",
"\n",
" plt.subplot(1, 2, 1)\n",
" plt.imshow(img)\n",
"\n",
" plt.subplot(1, 2, 2)\n",
" plt.imshow(label[0, :, :, 0])\n",
" plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "fvtxCncKsoRd"
},
"source": [
"# Build the model\n",
"We'll build the U-Net model. U-Net is especially good with segmentation tasks because it can localize well to provide high resolution segmentation masks. In addition, it works well with small datasets and is relatively robust against overfitting as the training data is in terms of the number of patches within an image, which is much larger than the number of training images itself. Unlike the original model, we will add batch normalization to each of our blocks. \n",
"\n",
"The Unet is built with an encoder portion and a decoder portion. The encoder portion is composed of a linear stack of [`Conv`](https://developers.google.com/machine-learning/glossary/#convolution), `BatchNorm`, and [`Relu`](https://developers.google.com/machine-learning/glossary/#ReLU) operations followed by a [`MaxPool`](https://developers.google.com/machine-learning/glossary/#pooling). Each `MaxPool` will reduce the spatial resolution of our feature map by a factor of 2. We keep track of the outputs of each block as we feed these high resolution feature maps with the decoder portion. The Decoder portion is comprised of UpSampling2D, Conv, BatchNorm, and Relus. Note that we concatenate the feature map of the same size on the decoder side. Finally, we add a final Conv operation that performs a convolution along the channels for each individual pixel (kernel size of (1, 1)) that outputs our final segmentation mask in grayscale. \n",
"## The Keras Functional API\n",
"The Keras functional API is used when you have multi-input/output models, shared layers, etc. It's a powerful API that allows you to manipulate tensors and build complex graphs with intertwined datastreams easily. In addition it makes **layers** and **models** both callable on tensors. \n",
" * To see more examples check out the [get started guide](https://keras.io/getting-started/functional-api-guide/). \n",
" \n",
" \n",
" We'll build these helper functions that will allow us to ensemble our model block operations easily and simply. "
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "zfew1i1F6bK-"
},
"outputs": [],
"source": [
"def conv_block(input_tensor, num_filters):\n",
" encoder = layers.Conv2D(num_filters, (3, 3), padding='same')(input_tensor)\n",
" encoder = layers.BatchNormalization()(encoder)\n",
" encoder = layers.Activation('relu')(encoder)\n",
" encoder = layers.Conv2D(num_filters, (3, 3), padding='same')(encoder)\n",
" encoder = layers.BatchNormalization()(encoder)\n",
" encoder = layers.Activation('relu')(encoder)\n",
" return encoder\n",
"\n",
"def encoder_block(input_tensor, num_filters):\n",
" encoder = conv_block(input_tensor, num_filters)\n",
" encoder_pool = layers.MaxPooling2D((2, 2), strides=(2, 2))(encoder)\n",
" \n",
" return encoder_pool, encoder\n",
"\n",
"def decoder_block(input_tensor, concat_tensor, num_filters):\n",
" decoder = layers.Conv2DTranspose(num_filters, (2, 2), strides=(2, 2), padding='same')(input_tensor)\n",
" decoder = layers.concatenate([concat_tensor, decoder], axis=-1)\n",
" decoder = layers.BatchNormalization()(decoder)\n",
" decoder = layers.Activation('relu')(decoder)\n",
" decoder = layers.Conv2D(num_filters, (3, 3), padding='same')(decoder)\n",
" decoder = layers.BatchNormalization()(decoder)\n",
" decoder = layers.Activation('relu')(decoder)\n",
" decoder = layers.Conv2D(num_filters, (3, 3), padding='same')(decoder)\n",
" decoder = layers.BatchNormalization()(decoder)\n",
" decoder = layers.Activation('relu')(decoder)\n",
" return decoder"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "xRLp21S_hpTn"
},
"outputs": [],
"source": [
"inputs = layers.Input(shape=img_shape)\n",
"# 256\n",
"\n",
"encoder0_pool, encoder0 = encoder_block(inputs, 32)\n",
"# 128\n",
"\n",
"encoder1_pool, encoder1 = encoder_block(encoder0_pool, 64)\n",
"# 64\n",
"\n",
"encoder2_pool, encoder2 = encoder_block(encoder1_pool, 128)\n",
"# 32\n",
"\n",
"encoder3_pool, encoder3 = encoder_block(encoder2_pool, 256)\n",
"# 16\n",
"\n",
"encoder4_pool, encoder4 = encoder_block(encoder3_pool, 512)\n",
"# 8\n",
"\n",
"center = conv_block(encoder4_pool, 1024)\n",
"# center\n",
"\n",
"decoder4 = decoder_block(center, encoder4, 512)\n",
"# 16\n",
"\n",
"decoder3 = decoder_block(decoder4, encoder3, 256)\n",
"# 32\n",
"\n",
"decoder2 = decoder_block(decoder3, encoder2, 128)\n",
"# 64\n",
"\n",
"decoder1 = decoder_block(decoder2, encoder1, 64)\n",
"# 128\n",
"\n",
"decoder0 = decoder_block(decoder1, encoder0, 32)\n",
"# 256\n",
"\n",
"outputs = layers.Conv2D(1, (1, 1), activation='sigmoid')(decoder0)"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "luDqDqu8c1AX"
},
"source": [
"## Define your model\n",
"Using functional API, you must define your model by specifying the inputs and outputs associated with the model. "
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "76QkTzXVczgc"
},
"outputs": [],
"source": [
"model = models.Model(inputs=[inputs], outputs=[outputs])"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "p0tNnmyOdtyr"
},
"source": [
"# Defining custom metrics and loss functions\n",
"Defining loss and metric functions are simple with Keras. Simply define a function that takes both the True labels for a given example and the Predicted labels for the same given example. "
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "sfuBVut0fogM"
},
"source": [
"Dice loss is a metric that measures overlap. More info on optimizing for Dice coefficient (our dice loss) can be found in the [paper](http://campar.in.tum.de/pub/milletari2016Vnet/milletari2016Vnet.pdf), where it was introduced. \n",
"\n",
"We use dice loss here because it performs better at class imbalanced problems by design. In addition, maximizing the dice coefficient and IoU metrics are the actual objectives and goals of our segmentation task. Using cross entropy is more of a proxy which is easier to maximize. Instead, we maximize our objective directly. "
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "t_8_hbHECUAW"
},
"outputs": [],
"source": [
"def dice_coeff(y_true, y_pred):\n",
" smooth = 1.\n",
" # Flatten\n",
" y_true_f = tf.reshape(y_true, [-1])\n",
" y_pred_f = tf.reshape(y_pred, [-1])\n",
" intersection = tf.reduce_sum(y_true_f * y_pred_f)\n",
" score = (2. * intersection + smooth) / (tf.reduce_sum(y_true_f) + tf.reduce_sum(y_pred_f) + smooth)\n",
" return score"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "4DgINhlpNaxP"
},
"outputs": [],
"source": [
"def dice_loss(y_true, y_pred):\n",
" loss = 1 - dice_coeff(y_true, y_pred)\n",
" return loss"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "qqClGNFJdANU"
},
"source": [
"Here, we'll use a specialized loss function that combines binary cross entropy and our dice loss. This is based on [individuals who competed within this competition obtaining better results empirically](https://www.kaggle.com/c/carvana-image-masking-challenge/discussion/40199). Try out your own custom losses to measure performance (e.g. bce + log(dice_loss), only bce, etc.)!"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "udrfi9JGB-bL"
},
"outputs": [],
"source": [
"def bce_dice_loss(y_true, y_pred):\n",
" loss = losses.binary_crossentropy(y_true, y_pred) + dice_loss(y_true, y_pred)\n",
" return loss"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "LifmpjXNc9Gz"
},
"source": [
"## Compile your model\n",
"We use our custom loss function to minimize. In addition, we specify what metrics we want to keep track of as we train. Note that metrics are not actually used during the training process to tune the parameters, but are instead used to measure performance of the training process. "
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "gflcWk2Cc8Bi"
},
"outputs": [],
"source": [
"model.compile(optimizer='adam', loss=bce_dice_loss, metrics=[dice_loss])\n",
"\n",
"model.summary()"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "8WG_8iZ_dMbK"
},
"source": [
"## Train your model\n",
"Training your model with `tf.data` involves simply providing the model's `fit` function with your training/validation dataset, the number of steps, and epochs. \n",
"\n",
"We also include a Model callback, [`ModelCheckpoint`](https://keras.io/callbacks/#modelcheckpoint) that will save the model to disk after each epoch. We configure it such that it only saves our highest performing model. Note that saving the model capture more than just the weights of the model: by default, it saves the model architecture, weights, as well as information about the training process such as the state of the optimizer, etc."
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "1nHnj6199elZ"
},
"outputs": [],
"source": [
"save_model_path = '/tmp/weights.hdf5'\n",
"cp = tf.keras.callbacks.ModelCheckpoint(filepath=save_model_path, monitor='val_dice_loss', save_best_only=True, verbose=1)"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "vJP_EvuTb4hH"
},
"source": [
"Don't forget to specify our model callback in the `fit` function call. "
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "UMZcOrq5aaj1"
},
"outputs": [],
"source": [
"history = model.fit(train_ds, \n",
" steps_per_epoch=int(np.ceil(num_train_examples / float(batch_size))),\n",
" epochs=epochs,\n",
" validation_data=val_ds,\n",
" validation_steps=int(np.ceil(num_val_examples / float(batch_size))),\n",
" callbacks=[cp])"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "gCAUsoxfTTrh"
},
"source": [
"# Visualize training process"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "AvntxymYn8rM"
},
"outputs": [],
"source": [
"dice = history.history['dice_loss']\n",
"val_dice = history.history['val_dice_loss']\n",
"\n",
"loss = history.history['loss']\n",
"val_loss = history.history['val_loss']\n",
"\n",
"epochs_range = range(epochs)\n",
"\n",
"plt.figure(figsize=(16, 8))\n",
"plt.subplot(1, 2, 1)\n",
"plt.plot(epochs_range, dice, label='Training Dice Loss')\n",
"plt.plot(epochs_range, val_dice, label='Validation Dice Loss')\n",
"plt.legend(loc='upper right')\n",
"plt.title('Training and Validation Dice Loss')\n",
"\n",
"plt.subplot(1, 2, 2)\n",
"plt.plot(epochs_range, loss, label='Training Loss')\n",
"plt.plot(epochs_range, val_loss, label='Validation Loss')\n",
"plt.legend(loc='upper right')\n",
"plt.title('Training and Validation Loss')\n",
"\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "dWPhb87GdhkG"
},
"source": [
"Even with only 5 epochs, we see strong performance."
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "MGFKf8yCTYbw"
},
"source": [
"# Visualize actual performance \n",
"We'll visualize our performance on the validation set.\n",
"\n",
"Note that in an actual setting (competition, deployment, etc.) we'd evaluate on the test set with the full image resolution. "
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "oIddsUcM_KeI"
},
"source": [
"To load our model we have two options:\n",
"1. Since our model architecture is already in memory, we can simply call `load_weights(save_model_path)`\n",
"2. If you wanted to load the model from scratch (in a different setting without already having the model architecture in memory) we simply call \n",
"\n",
"```model = models.load_model(save_model_path, custom_objects={'bce_dice_loss': bce_dice_loss, 'dice_loss': dice_loss})```, specificing the necessary custom objects, loss and metrics, that we used to train our model. \n",
"\n",
"If you want to see more examples, check our the [keras guide](https://keras.io/getting-started/faq/#how-can-i-save-a-keras-model)!"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "5Ph7acmrCXm6"
},
"outputs": [],
"source": [
"# Alternatively, load the weights directly: model.load_weights(save_model_path)\n",
"model = models.load_model(save_model_path, custom_objects={'bce_dice_loss': bce_dice_loss,\n",
" 'dice_loss': dice_loss})"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"colab": {},
"colab_type": "code",
"id": "0GnwZ7CPaamI"
},
"outputs": [],
"source": [
"# Let's visualize some of the outputs \n",
"data_aug_iter = val_ds.make_one_shot_iterator()\n",
"next_element = data_aug_iter.get_next()\n",
"\n",
"# Running next element in our graph will produce a batch of images\n",
"plt.figure(figsize=(10, 20))\n",
"for i in range(5):\n",
" batch_of_imgs, label = tf.keras.backend.get_session().run(next_element)\n",
" img = batch_of_imgs[0]\n",
" predicted_label = model.predict(batch_of_imgs)[0]\n",
"\n",
" plt.subplot(5, 3, 3 * i + 1)\n",
" plt.imshow(img)\n",
" plt.title(\"Input image\")\n",
" \n",
" plt.subplot(5, 3, 3 * i + 2)\n",
" plt.imshow(label[0, :, :, 0])\n",
" plt.title(\"Actual Mask\")\n",
" plt.subplot(5, 3, 3 * i + 3)\n",
" plt.imshow(predicted_label[:, :, 0])\n",
" plt.title(\"Predicted Mask\")\n",
"plt.suptitle(\"Examples of Input Image, Label, and Prediction\")\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "iPV7RMA9TjPC"
},
"source": [
"# Key Takeaways\n",
"In this tutorial we learned how to train a network to automatically detect and create cutouts of cars from images! \n",
"\n",
"## Specific concepts that will we covered:\n",
"In the process, we hopefully built some practical experience and developed intuition around the following concepts\n",
"* [**Functional API**](https://keras.io/getting-started/functional-api-guide/) - we implemented UNet with the Functional API. Functional API gives a lego-like API that allows us to build pretty much any network. \n",
"* **Custom Losses and Metrics** - We implemented custom metrics that allow us to see exactly what we need during training time. In addition, we wrote a custom loss function that is specifically suited to our task. \n",
"* **Save and load our model** - We saved our best model that we encountered according to our specified metric. When we wanted to perform inference with out best model, we loaded it from disk. Note that saving the model capture more than just the weights of the model: by default, it saves the model architecture, weights, as well as information about the training process such as the state of the optimizer, etc. "
]
}
],
"metadata": {
"accelerator": "GPU",
"colab": {
"collapsed_sections": [],
"name": "Image Segmentation",
"private_outputs": true,
"provenance": [],
"version": "0.3.2"
},
"kernelspec": {
"display_name": "Python [default]",
"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.6.4"
}
},
"nbformat": 4,
"nbformat_minor": 1
}
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "Eager Execution: Dev Summit 2018",
"version": "0.3.2",
"views": {},
"default_view": {},
"provenance": [],
"collapsed_sections": []
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
}
},
"cells": [
{
"metadata": {
"id": "p-esxQ2Ah4ab",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"##### Copyright 2018 The TensorFlow Authors.\n",
"\n",
"Licensed under the Apache License, Version 2.0 (the \"License\");"
]
},
{
"metadata": {
"id": "Xqp-XvX5h7Ff",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"# you may not use this file except in compliance with the License.\n",
"# You may obtain a copy of the License at\n",
"#\n",
"# https://www.apache.org/licenses/LICENSE-2.0\n",
"#\n",
"# Unless required by applicable law or agreed to in writing, software\n",
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"# See the License for the specific language governing permissions and\n",
"# limitations under the License."
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "g7nGs4mzVUHP",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"# Eager execution\n",
"\n",
"Note: you can run **[this notebook, live in Google Colab](https://colab.research.google.com/github/tensorflow/models/blob/master/samples/outreach/demos/eager_execution.ipynb)** with zero setup. \n",
"\n",
"**TensorFlow Dev Summit, 2018.**\n",
"\n",
"This interactive notebook demonstrates **eager execution**, TensorFlow's imperative, NumPy-like front-end for machine learning.\n",
"\n",
"> ![alt text](https://lh3.googleusercontent.com/QOvy0clmg7siaVKzwmSPAjicWWNQ0OeyaB16plDjSJMf35WD3vLjF6mz4CGrhSHw60HnlZPJjkyDCBzw5XOI0oBGSewyYw=s688)\n",
"\n",
"**Table of Contents.**\n",
"1. _Enabling eager execution!_\n",
"2. _A NumPy-like library for numerical computation and machine learning. Case study: Fitting a huber regression_.\n",
"3. _Neural networks. Case study: Training a multi-layer RNN._\n",
"4. _Exercises: Batching; debugging._\n",
"5. _Further reading_"
]
},
{
"metadata": {
"id": "ZVKfj5ttVkqz",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"# 1. Enabling eager execution!\n",
"\n",
"A single function call is all you need to enable eager execution: `tf.enable_eager_execution()`. You should invoke this function before calling into any other TensorFlow APIs --- the simplest way to satisfy this requirement is to make `tf.enable_eager_execution()` the first line of your `main` function.\n"
]
},
{
"metadata": {
"id": "C783D4QKVlK1",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"!pip install -q -U tf-nightly\n",
"\n",
"import tensorflow as tf\n",
"\n",
"tf.enable_eager_execution()"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "trrHQBM1VnD0",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"# 2. A NumPy-like library for numerical computation and machine learning\n",
"Enabling eager execution transforms TensorFlow into an **imperative** library for numerical computation, automatic differentiation, and machine learning. When executing eagerly, _TensorFlow no longer behaves like a dataflow graph engine_: Tensors are backed by NumPy arrays (goodbye, placeholders!), and TensorFlow operations execute *immediately* via Python (goodbye, sessions!)."
]
},
{
"metadata": {
"id": "MLUSuZuccgmF",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"### Numpy-like usage\n",
"\n",
"Tensors are backed by numpy arrays, which are accessible via their `.numpy()`\n",
"method."
]
},
{
"metadata": {
"id": "lzrktlC0cPi1",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"A = tf.constant([[2.0, 0.0], [0.0, 3.0]])"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "F5oDeGhYcX6c",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"import numpy as np\n",
"\n",
"print(\"Tensors are backed by NumPy arrays, which are accessible through their \"\n",
" \"`.numpy()` method:\\n\", A)\n",
"assert(type(A.numpy()) == np.ndarray)\n",
"print(\"\\nOperations (like `tf.matmul(A, A)`) execute \"\n",
" \"immediately (no more Sessions!):\\n\", tf.matmul(A, A))"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "SRCTcyCocvBq",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"Tensors behave similarly to NumPy arrays, but they don't behave exactly the\n",
"same. \n",
"\n",
"For example, the equals operator on Tensors compares objects. Use\n",
"`tf.equal` to compare values."
]
},
{
"metadata": {
"id": "OgBX6BJdcZ8w",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"print(\"\\nTensors behave like NumPy arrays: you can iterate over them and \"\n",
" \"supply them as inputs to most functions that expect NumPy arrays:\")\n",
"for i, row in enumerate(A):\n",
" for j, entry in enumerate(row):\n",
" print(\"A[%d, %d]^2 == %d\" % (i, j, np.square(entry)))"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "Q-o-XayRdAEi",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"### Variables and Gradients\n",
"\n",
"Create variables with `tf.contrib.eager.Variable`, and use `tf.GradientTape`\n",
"to compute gradients with respect to them."
]
},
{
"metadata": {
"id": "PGAqOzqzccwd",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"import tensorflow.contrib.eager as tfe\n",
"w = tfe.Variable(3.0)\n",
"with tf.GradientTape() as tape:\n",
" loss = w ** 2\n",
"dw, = tape.gradient(loss, [w])\n",
"print(\"\\nYou can use `tf.GradientTape` to compute the gradient of a \"\n",
" \"computation with respect to a list of `tf.contrib.eager.Variable`s;\\n\"\n",
" \"for example, `tape.gradient(loss, [w])`, where `loss` = w ** 2 and \"\n",
" \"`w` == 3.0, yields`\", dw,\"`.\")"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "gZFXrVTKdFnl",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"### GPU usage\n",
"Eager execution lets you offload computation to hardware accelerators like\n",
"GPUs, if you have any available."
]
},
{
"metadata": {
"id": "ER-Hsk3RVmX9",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
},
"cellView": "both"
},
"cell_type": "code",
"source": [
"if tf.test.is_gpu_available():\n",
" with tf.device(tf.test.gpu_device_name()):\n",
" B = tf.constant([[2.0, 0.0], [0.0, 3.0]])\n",
" print(tf.matmul(B, B))"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "JQ8kQT99VqDk",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"## Fitting a Huber regression\n",
"\n",
"If you come from a scientific or numerical computing background, eager execution should feel natural to you. Not only does it stand on its own as an accelerator-compatible library for numerical computation, it also interoperates with popular Python packages like NumPy and Matplotlib. To demonstrate this fact, in this section, we fit and evaluate a regression using a [Huber regression](https://en.wikipedia.org/wiki/Huber_loss), writing our code in a NumPy-like way and making use of Python control flow."
]
},
{
"metadata": {
"id": "6dXt0WfBK9-7",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"### Data generation\n",
"\n",
"Our dataset for this example has many outliers — least-squares would be a poor choice."
]
},
{
"metadata": {
"id": "Il1zLdgjVslU",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
},
"cellView": "code"
},
"cell_type": "code",
"source": [
"import matplotlib.pyplot as plt\n",
"\n",
"def gen_regression_data(num_examples=1000, p=0.2):\n",
" X = tf.random_uniform(shape=(num_examples,), maxval=50)\n",
" w_star = tf.random_uniform(shape=(), maxval=10)\n",
" b_star = tf.random_uniform(shape=(), maxval=10)\n",
" noise = tf.random_normal(shape=(num_examples,), mean=0.0, stddev=10.0)\n",
" # With probability 1 - p, y := y * -1.\n",
" sign = 2 * np.random.binomial(1, 1 - p, size=(num_examples,)) - 1\n",
" # You can freely mix Tensors and NumPy arrays in your computations:\n",
" # `sign` is a NumPy array, but the other symbols below are Tensors.\n",
" Y = sign * (w_star * X + b_star + noise) \n",
" return X, Y\n",
"\n",
"X, Y = gen_regression_data()\n",
"plt.plot(X, Y, \"go\") # You can plot Tensors!\n",
"plt.title(\"Observed data\")\n",
"plt.show()"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "sYumjOrdMRFM",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"### Huber loss\n",
"The Huber loss function is piecewise function that is quadratic for small inputs and linear otherwise; for that reason, using a Huber loss gives considerably less weight to outliers than least-squares does. When eager execution is enabled, we can implement the Huber function in the natural way, using **Python control flow**."
]
},
{
"metadata": {
"id": "anflUCeaVtK8",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"def huber_loss(y, y_hat, m=1.0):\n",
" # Enabling eager execution lets you use Python control flow.\n",
" delta = tf.abs(y - y_hat)\n",
" return delta ** 2 if delta <= m else m * (2 * delta - m)"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "0_OALYGwM7ma",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"### A simple class for regressions\n",
"\n",
"The next cell encapsulates a linear regression model in a Python class and defines a\n",
"function that fits the model using a stochastic optimizer."
]
},
{
"metadata": {
"id": "-90due2RVuDF",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
},
"cellView": "code"
},
"cell_type": "code",
"source": [
"import time\n",
"\n",
"from google.colab import widgets\n",
"import tensorflow.contrib.eager as tfe # Needed to create tfe.Variable objects.\n",
"\n",
"\n",
"class Regression(object):\n",
" def __init__(self, loss_fn):\n",
" super(Regression, self).__init__()\n",
" self.w = tfe.Variable(0.0)\n",
" self.b = tfe.Variable(0.0)\n",
" self.variables = [self.w, self.b]\n",
" self.loss_fn = loss_fn\n",
" \n",
" def predict(self, x):\n",
" return x * self.w + self.b\n",
" \n",
"def regress(model, optimizer, dataset, epochs=5, log_every=1, num_examples=1000):\n",
" plot = log_every is not None\n",
" if plot:\n",
" # Colab provides several widgets for interactive visualization.\n",
" tb = widgets.TabBar([str(i) for i in range(epochs) if i % log_every == 0])\n",
" X, Y = dataset.batch(num_examples).make_one_shot_iterator().get_next()\n",
" X = tf.reshape(X, (num_examples,))\n",
" Y = tf.reshape(Y, (num_examples,))\n",
" \n",
" for epoch in range(epochs):\n",
" iterator = dataset.make_one_shot_iterator()\n",
" epoch_loss = 0.0\n",
" start = time.time()\n",
" for x_i, y_i in iterator:\n",
" batch_loss_fn = lambda: model.loss_fn(y_i, model.predict(x_i)) \n",
" optimizer.minimize(batch_loss_fn, var_list=model.variables)\n",
" epoch_loss += batch_loss_fn()\n",
" duration = time.time() - start\n",
" if plot and epoch % log_every == 0:\n",
" with tb.output_to(str(epoch)):\n",
" print(\"Epoch %d took %0.2f seconds, resulting in a loss of %0.4f.\" % (\n",
" epoch, duration, epoch_loss))\n",
" plt.plot(X, Y, \"go\", label=\"data\")\n",
" plt.plot(X, model.predict(X), \"b\", label=\"regression\")\n",
" plt.legend()"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "Z8WdS6LQNc5K",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"Run the following cell to fit the model! Note that enabling eager execution makes it\n",
"easy to visualize your model while training it, using familiar tools like Matplotlib."
]
},
{
"metadata": {
"id": "_qRc30945Z3p",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"huber_regression = Regression(huber_loss)\n",
"dataset = tf.data.Dataset.from_tensor_slices((X, Y))\n",
"regress(huber_regression,\n",
" optimizer=tf.train.GradientDescentOptimizer(learning_rate=0.0001),\n",
" dataset=dataset)"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "5icvQghlN8Fd",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"## Debugging and profiling"
]
},
{
"metadata": {
"id": "55qmgvjgQocz",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"### Enabling eager execution lets you debug your code on-the-fly; use `pdb` and print statements to your heart's content.\n",
"\n",
"Check out exercise 2 towards the bottom of this notebook for a hands-on look at how eager simplifies model debugging."
]
},
{
"metadata": {
"id": "DNHJpCyNVwA9",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"import pdb\n",
"\n",
"def buggy_loss(y, y_hat):\n",
" pdb.set_trace()\n",
" huber_loss(y, y_hat)\n",
" \n",
"print(\"Type 'exit' to stop the debugger, or 's' to step into `huber_loss` and \"\n",
" \"'n' to step through it.\")\n",
"try:\n",
" buggy_loss(1.0, 2.0)\n",
"except:\n",
" pass"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "mvI3ljk-vJ_h",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"### Leverage the Python profiler to dig into the relative costs of training your model.\n",
"\n",
"If you run the below cell, you'll see that most of the time is spent computing gradients and binary operations, which is sensible considering our loss function."
]
},
{
"metadata": {
"id": "ZUlywNxYsapf",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"import cProfile\n",
"import pstats\n",
"\n",
"huber_regression = Regression(huber_loss)\n",
"cProfile.run(\n",
" \"regress(model=huber_regression, \"\n",
" \"optimizer=tf.train.GradientDescentOptimizer(learning_rate=0.001), \"\n",
" \"dataset=dataset, log_every=None)\", \"prof\")\n",
"pstats.Stats(\"prof\").strip_dirs().sort_stats(\"cumulative\").print_stats(10)\n",
"print(\"Most of the time is spent during backpropagation and binary operations.\")"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "5AeTwwPobkaJ",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"# 3. Neural networks\n",
"\n",
"While eager execution can certainly be used as a library for numerical computation, it shines as a library for deep learning: TensorFlow provides a suite of tools for deep learning research and development, most of which are compatible with eager execution. In this section, we put some of these tools to use to build _RNNColorbot_, an RNN that takes as input names of colors and predicts their corresponding RGB tuples. "
]
},
{
"metadata": {
"id": "6IcmEQ-jpTMO",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"## Constructing a data pipeline\n",
"\n",
"**[`tf.data`](https://www.tensorflow.org/api_guides/python/reading_data#_tf_data_API) is TensorFlow's canonical API for constructing input pipelines.** `tf.data` lets you easily construct multi-stage pipelines that supply data to your networks during training and inference. The following cells defines methods that download and format the data needed for RNNColorbot; the details aren't important (read them in the privacy of your own home if you so wish), but make sure to run the cells before proceeding."
]
},
{
"metadata": {
"id": "dcUC3Ma8bjgY",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
},
"cellView": "code"
},
"cell_type": "code",
"source": [
"import os\n",
"import six\n",
"from six.moves import urllib\n",
"\n",
"\n",
"def parse(line):\n",
" \"\"\"Parse a line from the colors dataset.\"\"\"\n",
" # `items` is a list [color_name, r, g, b].\n",
" items = tf.string_split([line], \",\").values\n",
" rgb = tf.string_to_number(items[1:], out_type=tf.float32) / 255.\n",
" color_name = items[0]\n",
" chars = tf.one_hot(tf.decode_raw(color_name, tf.uint8), depth=256)\n",
" length = tf.cast(tf.shape(chars)[0], dtype=tf.int64)\n",
" return rgb, chars, length\n",
"\n",
"def load_dataset(data_dir, url, batch_size):\n",
" \"\"\"Loads the colors data at path into a PaddedDataset.\"\"\"\n",
" path = tf.keras.utils.get_file(os.path.basename(url), url, cache_dir=data_dir)\n",
" dataset = tf.data.TextLineDataset(path).skip(1).map(parse).shuffle(\n",
" buffer_size=10000).padded_batch(batch_size,\n",
" padded_shapes=([None], [None, None], []))\n",
" return dataset, path"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "KBPJAQPUlh5M",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"train_url = \"https://raw.githubusercontent.com/random-forests/tensorflow-workshop/master/extras/colorbot/data/train.csv\"\n",
"test_url = \"https://raw.githubusercontent.com/random-forests/tensorflow-workshop/master/extras/colorbot/data/test.csv\"\n",
"data_dir = \"/tmp/rnn/data\"\n",
"\n",
"train_data, train_path = load_dataset(data_dir, train_url, batch_size=64)\n",
"eval_data, _ = load_dataset(data_dir, test_url, batch_size=64)"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "w9ftJ4LUoVYo",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"import pandas\n",
"pandas.read_csv(train_path).head(10)"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "ynzm5mfnlmS8",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"colors, one_hot_chars, lengths = tfe.Iterator(train_data).next()\n",
"colors[:10].numpy()"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "S39jq-2QoA5e",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"## Defining and training a neural network"
]
},
{
"metadata": {
"id": "9fycJOqm8vkt",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"TensorFlow packages several APIs for creating neural networks in a modular fashion. **The canonical way to define neural networks in TensorFlow is to encapsulate your model in a class that inherits from `tf.keras.Model`**. You should think of `tf.keras.Model` as a container of **[object-oriented layers](https://www.tensorflow.org/api_docs/python/tf/layers)**, TensorFlow's building blocks for constructing neural networks (*e.g.*, `tf.layers.Dense`, `tf.layers.Conv2D`). Every `Layer` object that is set as an attribute of a `Model` is automatically tracked by the latter, letting you access `Layer`-contained variables by invoking `Model`'s `.variables()` method. Most important, **inheriting from `tf.keras.Model` makes it easy to checkpoint your model and to subsequently restore it** --- more on that later. \n",
"\n",
"The following cell exemplifies our high-level neural network APIs. Note that `RNNColorbot` encapsulates only the model definition and prediction generation logic. The loss, training, and evaluation functions exist outside the class definition: conceptually, the model doesn't need know how to train and benchmark itself."
]
},
{
"metadata": {
"id": "NlKcdvT9leQ2",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
},
"cellView": "code"
},
"cell_type": "code",
"source": [
"class RNNColorbot(tf.keras.Model):\n",
" \"\"\"Multi-layer RNN that predicts RGB tuples given color names.\n",
" \"\"\"\n",
"\n",
" def __init__(self):\n",
" super(RNNColorbot, self).__init__()\n",
" self.keep_prob = 0.5\n",
" self.lower_cell = tf.contrib.rnn.LSTMBlockCell(256)\n",
" self.upper_cell = tf.contrib.rnn.LSTMBlockCell(128)\n",
" self.relu = tf.layers.Dense(3, activation=tf.nn.relu, name=\"relu\")\n",
"\n",
" def call(self, inputs, training=False):\n",
" \"\"\"Generates RGB tuples from `inputs`, a tuple (`chars`, `sequence_length`).\n",
" \"\"\"\n",
" (chars, sequence_length) = inputs\n",
" chars = tf.transpose(chars, [1, 0, 2]) # make `chars` time-major\n",
" batch_size = int(chars.shape[1])\n",
" for cell in [self.lower_cell, self.upper_cell]:\n",
" outputs = []\n",
" state = cell.zero_state(batch_size, tf.float32)\n",
" for ch in chars:\n",
" output, state = cell(ch, state)\n",
" outputs.append(output)\n",
" chars = outputs\n",
" if training:\n",
" chars = tf.nn.dropout(chars, self.keep_prob)\n",
" batch_range = [i for i in range(batch_size)]\n",
" indices = tf.stack([sequence_length - 1, batch_range], axis=1)\n",
" hidden_states = tf.gather_nd(chars, indices)\n",
" return self.relu(hidden_states)\n",
"\n",
"\n",
"def loss_fn(labels, predictions):\n",
" return tf.reduce_mean((predictions - labels) ** 2)\n",
"\n",
"def train_one_epoch(model, optimizer, train_data, log_every=10):\n",
" iterator = tfe.Iterator(train_data)\n",
" for batch,(labels, chars, sequence_length) in enumerate(iterator):\n",
" with tf.GradientTape() as tape:\n",
" predictions = model((chars, sequence_length), training=True)\n",
" loss = loss_fn(labels, predictions)\n",
" variables = model.variables\n",
" grad = tape.gradient(loss, variables)\n",
" optimizer.apply_gradients([(g, v) for g, v in zip(grad, variables)])\n",
" if log_every and batch % log_every == 0:\n",
" print(\"train/batch #%d\\tloss: %.6f\" % (batch, loss))\n",
" batch += 1\n",
" \n",
"def test(model, eval_data):\n",
" total_loss = 0.0\n",
" iterator = eval_data.make_one_shot_iterator()\n",
" for labels, chars, sequence_length in tfe.Iterator(eval_data):\n",
" predictions = model((chars, sequence_length), training=False)\n",
" total_loss += loss_fn(labels, predictions)\n",
" print(\"eval/loss: %.6f\\n\" % total_loss)"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "xG1FxnhD62N3",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"The next cell **trains** our `RNNColorbot`, **restoring and saving checkpoints** of the learned variables along the way. Thanks to checkpointing, every run of the below cell will resume training from wherever the previous run left off. For more on checkpointing, take a look at our [user guide](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/eager/python/g3doc/guide.md#checkpointing-trained-variables)."
]
},
{
"metadata": {
"id": "W7wLw3nZsqKQ",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"model = RNNColorbot()\n",
"optimizer = tf.train.AdamOptimizer(learning_rate=.01)\n",
"\n",
"# Create a `Checkpoint` for saving and restoring state; the keywords\n",
"# supplied `Checkpoint`'s constructor are the names of the objects to be saved\n",
"# and restored, and their corresponding values are the actual objects. Note\n",
"# that we're saving `optimizer` in addition to `model`, since `AdamOptimizer`\n",
"# maintains state.\n",
"import tensorflow.contrib.eager as tfe\n",
"checkpoint = tfe.Checkpoint(model=model, optimizer=optimizer)\n",
"checkpoint_prefix = \"/tmp/rnn/ckpt\"\n",
"# The next line loads the most recent checkpoint, if any.\n",
"checkpoint.restore(tf.train.latest_checkpoint(\"/tmp/rnn\"))\n",
"for epoch in range(4):\n",
" train_one_epoch(model, optimizer, train_data)\n",
" test(model, eval_data)\n",
" checkpoint.save(checkpoint_prefix)\n",
"print(\"Colorbot is ready to generate colors!\")"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "1HdJk37R1xz9",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"### Paint me a color, Colorbot!\n",
"\n",
"We can interact with RNNColorbot in a natural way; no need to thread NumPy arrays into placeholders through feed dicts.\n",
"So go ahead and ask RNNColorbot to paint you some colors. If they're not to your liking, re-run the previous cell to resume training from where we left off, and then re-run the next one for updated results."
]
},
{
"metadata": {
"id": "LXAYjopasyWr",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"tb = widgets.TabBar([\"RNN Colorbot\"])\n",
"while True:\n",
" with tb.output_to(0):\n",
" try:\n",
" color_name = six.moves.input(\n",
" \"Give me a color name (or press 'enter' to exit): \")\n",
" except (EOFError, KeyboardInterrupt):\n",
" break\n",
" if not color_name:\n",
" break\n",
" _, chars, length = parse(color_name)\n",
" preds, = model((np.expand_dims(chars, 0), np.expand_dims(length, 0)),\n",
" training=False)\n",
" clipped_preds = tuple(min(float(p), 1.0) for p in preds)\n",
" rgb = tuple(int(p * 255) for p in clipped_preds)\n",
" with tb.output_to(0):\n",
" tb.clear_tab()\n",
" print(\"Predicted RGB tuple:\", rgb)\n",
" plt.imshow([[clipped_preds]])\n",
" plt.title(color_name)\n",
" plt.show()"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "aJopbdYiXXQM",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"# 4. Exercises"
]
},
{
"metadata": {
"id": "Nt2bZ3SNq0bl",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"### Exercise 1: Batching\n",
"\n",
"Executing operations eagerly incurs small overheads; these overheads become neglible when amortized over batched operations. In this exercise, we explore the relationship between batching and performance by revisiting our Huber regression example."
]
},
{
"metadata": {
"id": "U5NR8vOY-4Xx",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"# Our original implementation of `huber_loss` is not compatible with non-scalar\n",
"# data. Your task is to fix that. For your convenience, the original\n",
"# implementation is reproduced below.\n",
"#\n",
"# def huber_loss(y, y_hat, m=1.0):\n",
"# delta = tf.abs(y - y_hat)\n",
"# return delta ** 2 if delta <= m else m * (2 * delta - m)\n",
"#\n",
"def batched_huber_loss(y, y_hat, m=1.0):\n",
" # TODO: Uncomment out the below code and replace `...` with your solution.\n",
" # Hint: Tensors are immutable.\n",
" # Hint: `tf.where` might be useful.\n",
" delta = tf.abs(y - y_hat)\n",
" # ...\n",
" # ...\n",
" # return ...\n",
" \n",
"regression = Regression(batched_huber_loss)\n",
"\n",
"num_epochs = 4\n",
"batch_sizes = [1, 10, 20, 100, 200, 500, 1000]\n",
"times = []\n",
"\n",
"X, Y = gen_regression_data(num_examples=1000)\n",
"dataset = tf.data.Dataset.from_tensor_slices((X, Y))\n",
"optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.0001)\n",
"for size in batch_sizes:\n",
" batched_dataset = dataset.batch(size)\n",
" start = time.time()\n",
" regress(model=regression, optimizer=optimizer, dataset=batched_dataset,\n",
" epochs=num_epochs, log_every=None)\n",
" end = time.time()\n",
" times.append((end - start) / num_epochs)\n",
" regression.w.assign(0.0)\n",
" regression.b.assign(0.0)\n",
" \n",
"plt.figure()\n",
"plt.plot(batch_sizes, times, \"bo\")\n",
"plt.xlabel(\"batch size\")\n",
"plt.ylabel(\"time (seconds)\")\n",
"plt.semilogx()\n",
"plt.semilogy()\n",
"plt.title(\"Time per Epoch vs. Batch Size\")\n",
"plt.show()"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "-aH9GM4G-c56",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"#### Solution"
]
},
{
"metadata": {
"id": "MqqhJplCBxNC",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"def batched_huber_loss(y, y_hat, m=1.0):\n",
" delta = tf.abs(y - y_hat)\n",
" quadratic = delta ** 2\n",
" linear = m * (2 * delta - m)\n",
" return tf.reduce_mean(tf.where(delta <= m, quadratic, linear))\n",
" \n",
"regression = Regression(batched_huber_loss)\n",
"\n",
"num_epochs = 4\n",
"batch_sizes = [2, 10, 20, 100, 200, 500, 1000]\n",
"times = []\n",
"\n",
"X, Y = gen_regression_data(num_examples=1000)\n",
"dataset = tf.data.Dataset.from_tensor_slices((X, Y))\n",
"optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.0001)\n",
"for size in batch_sizes:\n",
" batched_dataset = dataset.batch(size)\n",
" start = time.time()\n",
" regress(model=regression, optimizer=optimizer, dataset=batched_dataset,\n",
" epochs=num_epochs, log_every=None)\n",
" end = time.time()\n",
" times.append((end - start) / num_epochs)\n",
" regression.w.assign(0.0)\n",
" regression.b.assign(0.0)\n",
" \n",
"plt.figure()\n",
"plt.plot(batch_sizes, times, \"bo\")\n",
"plt.xlabel(\"batch size\")\n",
"plt.ylabel(\"time (seconds)\")\n",
"plt.semilogx()\n",
"plt.semilogy()\n",
"plt.title(\"Time per Epoch vs. Batch Size\")\n",
"plt.show()"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "YbL8CZNp-pvH",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"### Exercise 2: Model Debugging\n",
"\n",
"We've heard you loud and clear: TensorFlow programs that construct and execute graphs are difficult to debug. By design, enabling eager execution vastly simplifies the process of debugging TensorFlow programs. Once eager execution is enabled, you can step through your models using `pdb` and bisect them with `print` statements. The best way to understand the extent to which eager execution simplifies debugging is to debug a model yourself. `BuggyModel` below has two bugs lurking in it. Execute the following cell, read the error message, and go hunt some bugs!\n",
"\n",
"*Hint: As is often the case with TensorFlow programs, both bugs are related to the shapes of Tensors.*\n",
"\n",
"*Hint: You might find `tf.layers.flatten` useful.*"
]
},
{
"metadata": {
"id": "Aa9HIamW-m3t",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
}
},
"cell_type": "code",
"source": [
"class BuggyModel(tf.keras.Model):\n",
" def __init__(self):\n",
" super(BuggyModel, self).__init__()\n",
" self._input_shape = [-1, 28, 28, 1]\n",
" self.conv = tf.layers.Conv2D(filters=32, kernel_size=5, padding=\"same\",\n",
" data_format=\"channels_last\")\n",
" self.fc = tf.layers.Dense(10)\n",
" self.max_pool2d = tf.layers.MaxPooling2D(\n",
" (2, 2), (2, 2), padding=\"same\", data_format=\"channels_last\")\n",
" \n",
" def call(self, inputs):\n",
" y = inputs\n",
" y = self.conv(y)\n",
" y = self.max_pool2d(y)\n",
" return self.fc(y)\n",
" \n",
"buggy_model = BuggyModel()\n",
"inputs = tf.random_normal(shape=(100, 28, 28))\n",
"outputs = buggy_model(inputs)\n",
"assert outputs.shape == (100, 10), \"invalid output shape: %s\" % outputs.shape"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "ja8aFOnYsKez",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"#### Solution"
]
},
{
"metadata": {
"id": "J7z8JbrRltzV",
"colab_type": "code",
"colab": {
"autoexec": {
"startup": false,
"wait_interval": 0
}
},
"cellView": "code"
},
"cell_type": "code",
"source": [
"class BuggyModel(tf.keras.Model):\n",
" def __init__(self):\n",
" super(BuggyModel, self).__init__()\n",
" self._input_shape = [-1, 28, 28, 1]\n",
" self.conv = tf.layers.Conv2D(filters=32, kernel_size=5, padding=\"same\",\n",
" data_format=\"channels_last\")\n",
" self.fc = tf.layers.Dense(10)\n",
" self.max_pool2d = tf.layers.MaxPooling2D(\n",
" (2, 2), (2, 2), padding=\"same\", data_format=\"channels_last\")\n",
" \n",
" def call(self, inputs):\n",
" y = tf.reshape(inputs, self._input_shape)\n",
" y = self.conv(y)\n",
" y = self.max_pool2d(y)\n",
" y = tf.layers.flatten(y)\n",
" return self.fc(y)\n",
" \n",
"buggy_model = BuggyModel()\n",
"inputs = tf.random_normal(shape=(100, 28, 28))\n",
"outputs = buggy_model(inputs)\n",
"assert outputs.shape == (100, 10), \"invalid output shape: %s\" % outputs.shape"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "G-Ubr-Gfturc",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"# 5. Further reading\n",
"\n",
"If you'd like to learn more about eager execution, consider reading ...\n",
"\n",
"\n",
"\n",
"* our [user guide](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/eager/python/g3doc/guide.md);\n",
"* our [collection of example models](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/eager/python/examples), which includes a convolutional model for [MNIST](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/eager/python/examples/mnist) classification, a [GAN](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/eager/python/examples/gan), a [recursive neural network](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/eager/python/examples/spinn), and more;\n",
"* [this advanced notebook](https://colab.research.google.com/github/tensorflow/tensorflow/blob/master/tensorflow/contrib/autograph/examples/notebooks/dev_summit_2018_demo.ipynb), which explains how to build and execute graphs while eager execution is enabled and how to call into eager execution while constructing a graph, and which also introduces Autograph, a source-code translation tool that automatically generates graph-construction code from dynamic eager code.\n",
"\n",
"\n"
]
}
]
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment