()() = "MyReader!";
+ out_tensors->emplace_back(std::move(record_tensor));
+ ++i_;
+ *end_of_sequence = false;
+ } else {
+ *end_of_sequence = true;
+ }
+ return Status::OK();
+ }
+
+ protected:
+ // Optional: Implementation of iterator state serialization for this
+ // iterator.
+ //
+ // Implement these two methods if you want to be able to save and restore
+ // instances of this iterator.
+ Status SaveInternal(IteratorStateWriter* writer) override {
+ mutex_lock l(mu_);
+ TF_RETURN_IF_ERROR(writer->WriteScalar(full_name("i"), i_));
+ return Status::OK();
+ }
+ Status RestoreInternal(IteratorContext* ctx,
+ IteratorStateReader* reader) override {
+ mutex_lock l(mu_);
+ TF_RETURN_IF_ERROR(reader->ReadScalar(full_name("i"), &i_));
+ return Status::OK();
+ }
+
+ private:
+ mutex mu_;
+ int64 i_ GUARDED_BY(mu_);
+ };
+ };
+};
-```python
-from tensorflow.python.framework import ops
-from tensorflow.python.ops import common_shapes
-from tensorflow.python.ops import io_ops
+// Register the op definition for MyReaderDataset.
+//
+// Dataset ops always have a single output, of type `variant`, which represents
+// the constructed `Dataset` object.
+//
+// Add any attrs and input tensors that define the dataset here.
+REGISTER_OP("MyReaderDataset")
+ .Output("handle: variant")
+ .SetIsStateful()
+ .SetShapeFn(shape_inference::ScalarShape);
-class SomeReader(io_ops.ReaderBase):
+// Register the kernel implementation for MyReaderDataset.
+REGISTER_KERNEL_BUILDER(Name("MyReaderDataset").Device(DEVICE_CPU),
+ MyReaderDatasetOp);
- def __init__(self, name=None):
- rr = gen_user_ops.some_reader(name=name)
- super(SomeReader, self).__init__(rr)
+} // namespace
+} // namespace tensorflow
+```
+The last step is to build the C++ code and add a Python wrapper. The easiest way
+to do this is by @{$adding_an_op#build_the_op_library$compiling a dynamic
+library} (e.g. called `"my_reader_dataset_op.so"`), and adding a Python class
+that subclasses @{tf.data.Dataset} to wrap it. An example Python program is
+given here:
-ops.NotDifferentiable("SomeReader")
+```python
+import tensorflow as tf
+
+# Assumes the file is in the current working directory.
+my_reader_dataset_module = tf.load_op_library("./my_reader_dataset_op.so")
+
+class MyReaderDataset(tf.data.Dataset):
+
+ def __init__(self):
+ super(MyReaderDataset, self).__init__()
+ # Create any input attrs or tensors as members of this class.
+
+ def _as_variant_tensor(self):
+ # Actually construct the graph node for the dataset op.
+ #
+ # This method will be invoked when you create an iterator on this dataset
+ # or a dataset derived from it.
+ return my_reader_dataset_module.my_reader_dataset()
+
+ # The following properties define the structure of each element: a scalar
+ # `tf.string` tensor. Change these properties to match the `output_dtypes()`
+ # and `output_shapes()` methods of `MyReaderDataset::Dataset` if you modify
+ # the structure of each element.
+ @property
+ def output_types(self):
+ return tf.string
+
+ @property
+ def output_shapes(self):
+ return tf.TensorShape([])
+
+ @property
+ def output_classes(self):
+ return tf.Tensor
+
+if __name__ == "__main__":
+ # Create a MyReaderDataset and print its elements.
+ with tf.Session() as sess:
+ iterator = MyReaderDataset().make_one_shot_iterator()
+ next_element = iterator.get_next()
+ try:
+ while True:
+ print(sess.run(next_element)) # Prints "MyReader!" ten times.
+ except tf.errors.OutOfRangeError:
+ pass
```
-You can see some examples in
-[`tensorflow/python/ops/io_ops.py`](https://www.tensorflow.org/code/tensorflow/python/ops/io_ops.py).
+You can see some examples of `Dataset` wrapper classes in
+[`tensorflow/python/data/ops/dataset_ops.py`](https://www.tensorflow.org/code/tensorflow/python/data/ops/dataset_ops.py).
## Writing an Op for a record format
@@ -201,9 +287,7 @@ track down where the bad data came from.
Examples of Ops useful for decoding records:
-* @{tf.parse_single_example}
- (and
- @{tf.parse_example})
+* @{tf.parse_single_example} (and @{tf.parse_example})
* @{tf.decode_csv}
* @{tf.decode_raw}
@@ -211,11 +295,6 @@ Note that it can be useful to use multiple Ops to decode a particular record
format. For example, you may have an image saved as a string in
[a `tf.train.Example` protocol buffer](https://www.tensorflow.org/code/tensorflow/core/example/example.proto).
Depending on the format of that image, you might take the corresponding output
-from a
-@{tf.parse_single_example}
-op and call @{tf.image.decode_jpeg},
-@{tf.image.decode_png}, or
-@{tf.decode_raw}. It is common to
-take the output of `tf.decode_raw` and use
-@{tf.slice} and
-@{tf.reshape} to extract pieces.
+from a @{tf.parse_single_example} op and call @{tf.image.decode_jpeg},
+@{tf.image.decode_png}, or @{tf.decode_raw}. It is common to take the output
+of `tf.decode_raw` and use @{tf.slice} and @{tf.reshape} to extract pieces.
diff --git a/get_started/custom_estimators.md b/get_started/custom_estimators.md
index 941c3e1..275cda1 100644
--- a/get_started/custom_estimators.md
+++ b/get_started/custom_estimators.md
@@ -546,7 +546,7 @@ In brief, here's what the three graphs tell you:
* accuracy: The accuracy is recorded by the following two lines:
- * `eval_metric_ops={'my_accuracy': accuracy})`, during evaluation.
+ * `eval_metric_ops={'my_accuracy': accuracy}`, during evaluation.
* `tf.summary.scalar('accuracy', accuracy[1])`, during training.
These tensorboard graphs are one of the main reasons it's important to pass a
diff --git a/get_started/eager.md b/get_started/eager.md
new file mode 100644
index 0000000..ad89f01
--- /dev/null
+++ b/get_started/eager.md
@@ -0,0 +1,3 @@
+# Get Started with Eager Execution
+
+[Colab notebook](https://colab.research.google.com/github/tensorflow/models/blob/master/samples/core/get_started/eager.ipynb)
diff --git a/get_started/get_started_for_beginners.md b/get_started/get_started_for_beginners.md
index b88483b..fbe0ed7 100644
--- a/get_started/get_started_for_beginners.md
+++ b/get_started/get_started_for_beginners.md
@@ -1,4 +1,4 @@
-# Getting Started for ML Beginners
+# Get Started with Graph Execution
This document explains how to use machine learning to classify (categorize)
Iris flowers by species. This document dives deeply into the TensorFlow
@@ -14,6 +14,11 @@ If you are already familiar with basic machine learning concepts
but are new to TensorFlow, read
@{$premade_estimators$Getting Started with TensorFlow: for ML Experts}.
+If you'd like to learn a lot about the basics of Machine Learning,
+consider taking
+[Machine Learning Crash Course](https://developers.google.com/machine-learning/crash-course/).
+
+
## The Iris classification problem
Imagine you are a botanist seeking an automated way to classify each
@@ -86,6 +91,9 @@ a number. Here's the representation scheme:
* 1 represents versicolor
* 2 represents virginica
+For a look at other examples of labels and examples, see the
+[ML Terminology section of Machine Learning Crash Course](https://developers.google.com/machine-learning/crash-course/framing/ml-terminology).
+
## Models and training
@@ -371,7 +379,7 @@ There are several categories of neural networks.
We'll be using a [**fully connected neural
network**](https://developers.google.com/machine-learning/glossary/#fully_connected_layer),
which means that the neurons in one layer take inputs from *every* neuron in
-the previous layer. For example, the following figure illustrates a
+the previous layer. For example, the following figure illustrates a
fully connected neural network consisting of three hidden layers:
* The first hidden layer contains four neurons.
@@ -385,6 +393,9 @@ fully connected neural network consisting of three hidden layers:
**A neural network with three hidden layers.**
+For a more detailed introduction to neural networks, see the
+[Introduction to Neural Nets section of Machine Learning Crash Course](https://developers.google.com/machine-learning/crash-course/introduction-to-neural-networks/anatomy).
+
To specify a model type, instantiate an
[**Estimator**](https://developers.google.com/machine-learning/glossary/#Estimators)
class. TensorFlow provides two categories of Estimators:
@@ -448,9 +459,9 @@ will become very important.
### Train the model
-Instantiating a `tf.Estimator.DNNClassifier` creates a framework for learning
-the model. Basically, we've wired a network but haven't yet let data flow
-through it. To train the neural network, call the Estimator object's `train`
+Instantiating a `tf.Estimator.DNNClassifier` creates a framework for learning
+the model. Basically, we've wired a network but haven't yet let data flow
+through it. To train the neural network, call the Estimator object's `train`
method. For example:
```python
@@ -559,15 +570,15 @@ of 0.5. The following suggests a more effective model:
Label |
Prediction |
- 5.9 | 3.0 | 4.3 | 1.5 | 1 |
+
5.9 | 3.0 | 4.3 | 1.5 | 1 |
1 |
- 6.9 | 3.1 | 5.4 | 2.1 | 2 |
+
6.9 | 3.1 | 5.4 | 2.1 | 2 |
2 |
- 5.1 | 3.3 | 1.7 | 0.5 | 0 |
+
5.1 | 3.3 | 1.7 | 0.5 | 0 |
0 |
- 6.0 | 3.4 | 4.5 | 1.6 | 1 |
+
6.0 | 3.4 | 4.5 | 1.6 | 1 |
2 |
- 5.5 | 2.5 | 4.0 | 1.3 | 1 |
+
5.5 | 2.5 | 4.0 | 1.3 | 1 |
1 |
@@ -631,6 +642,10 @@ Test set accuracy: 0.967
An accuracy of 0.967 implies that our trained model correctly classified 29
out of the 30 Iris species in the test set.
+To get a deeper understanding of different metrics for evaluating
+models, see the
+[Classification section of Machine Learning Crash Course](https://developers.google.com/machine-learning/crash-course/classification).
+
### Predicting
@@ -723,7 +738,6 @@ Prediction is "Virginica" (97.9%), expected "Virginica"
## Summary
-
This document provides a short introduction to machine learning.
Because `premade_estimators.py` relies on high-level APIs, much of the
diff --git a/get_started/index.md b/get_started/index.md
index b7bd128..b28cb9d 100644
--- a/get_started/index.md
+++ b/get_started/index.md
@@ -1,10 +1,22 @@
-# Getting Started
+# Get Started
+
+If you are new to machine learning, we recommend taking the following online
+course prior to diving into TensorFlow documentation:
+
+ * [Machine Learning Crash Course](https://developers.google.com/machine-learning/crash-course/),
+ which introduces machine learning concepts and encourages experimentation
+ with existing TensorFlow code.
TensorFlow is a tool for machine learning. While it contains a wide range of
functionality, TensorFlow is mainly designed for deep neural network models.
-TensorFlow provides many APIs. This section focuses on the high-level APIs.
-If you are new to TensorFlow, begin by reading one of the following documents:
+The easiest way to get started with tensorflow is using Eager Execution.
+
+ * @{$get_started/eager}, is for anyone new to machine learning or TensorFlow.
+
+TensorFlow provides many APIs. The remainder of this section focuses on the
+Estimator API which provide scalable, high-performance models.
+To get started with Estimators begin by reading one of the following documents:
* @{$get_started/get_started_for_beginners}, which is aimed at readers
new to machine learning.
diff --git a/get_started/leftnav_files b/get_started/leftnav_files
index 437791d..4c12f0d 100644
--- a/get_started/leftnav_files
+++ b/get_started/leftnav_files
@@ -1,10 +1,14 @@
index.md
-### Getting Started
+### Beginners
+eager.md
get_started_for_beginners.md
premade_estimators.md
-### Details
+### Estimators
+get_started_for_beginners.md: For Beginners
+premade_estimators.md: Premade Estimators
+>>>
checkpoints.md
feature_columns.md
datasets_quickstart.md
diff --git a/get_started/premade_estimators.md b/get_started/premade_estimators.md
index 6bffd2e..4be7e50 100644
--- a/get_started/premade_estimators.md
+++ b/get_started/premade_estimators.md
@@ -1,5 +1,4 @@
-
-# Getting Started with TensorFlow
+# Premade Estimators
This document introduces the TensorFlow programming environment and shows you
how to solve the Iris classification problem in TensorFlow.
@@ -397,9 +396,9 @@ predictions and their probabilities:
``` python
-for pred_dict, expec in zip(predictions, expected):
- template = ('\nPrediction is "{}" ({:.1f}%), expected "{}"')
+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]
diff --git a/install/install_c.md b/install/install_c.md
index 0481c97..1abd840 100644
--- a/install/install_c.md
+++ b/install/install_c.md
@@ -38,7 +38,7 @@ enable TensorFlow for C:
OS="linux" # Change to "darwin" for macOS
TARGET_DIRECTORY="/usr/local"
curl -L \
- "https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-$%7BTF_TYPE%7D-$%7BOS%7D-x86_64-1.6.0.tar.gz" |
+ "https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-$%7BTF_TYPE%7D-$%7BOS%7D-x86_64-1.8.0.tar.gz" |
sudo tar -C $TARGET_DIRECTORY -xz
The `tar` command extracts the TensorFlow C library into the `lib`
@@ -113,6 +113,6 @@ If executing `a.out` fails, ask yourself the following questions:
* Did you export those environment variables?
If you are still seeing build or execution error messages, search (or post to)
-[StackOverflow](www.stackoverflow.com/questions/tagged/tensorflow) for
+[StackOverflow](https://stackoverflow.com/questions/tagged/tensorflow) for
possible solutions.
diff --git a/install/install_go.md b/install/install_go.md
index 8f89898..52a2a3f 100644
--- a/install/install_go.md
+++ b/install/install_go.md
@@ -38,7 +38,7 @@ steps to install this library and enable TensorFlow for Go:
TF_TYPE="cpu" # Change to "gpu" for GPU support
TARGET_DIRECTORY='/usr/local'
curl -L \
- "https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-$%7BTF_TYPE%7D-$(go%20env%20GOOS)-x86_64-1.6.0.tar.gz" |
+ "https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-$%7BTF_TYPE%7D-$(go%20env%20GOOS)-x86_64-1.8.0.tar.gz" |
sudo tar -C $TARGET_DIRECTORY -xz
The `tar` command extracts the TensorFlow C library into the `lib`
diff --git a/install/install_java.md b/install/install_java.md
index 0ee9c84..700ae01 100644
--- a/install/install_java.md
+++ b/install/install_java.md
@@ -36,7 +36,7 @@ following to the project's `pom.xml` to use the TensorFlow Java APIs:
org.tensorflow
tensorflow
- 1.6.0
+ 1.8.0
```
@@ -65,7 +65,7 @@ As an example, these steps will create a Maven project that uses TensorFlow:
org.tensorflow
tensorflow
- 1.6.0
+ 1.8.0
@@ -123,12 +123,12 @@ instead:
org.tensorflow
libtensorflow
- 1.6.0
+ 1.8.0
org.tensorflow
libtensorflow_jni_gpu
- 1.6.0
+ 1.8.0
```
@@ -147,7 +147,7 @@ refer to the simpler instructions above instead.
Take the following steps to install TensorFlow for Java on Linux or macOS:
1. Download
- [libtensorflow.jar](https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-1.6.0.jar),
+ [libtensorflow.jar](https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-1.8.0.jar),
which is the TensorFlow Java Archive (JAR).
2. Decide whether you will run TensorFlow for Java on CPU(s) only or with
@@ -166,7 +166,7 @@ Take the following steps to install TensorFlow for Java on Linux or macOS:
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
mkdir -p ./jni
curl -L \
- "https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow_jni-$%7BTF_TYPE%7D-$%7BOS%7D-x86_64-1.6.0.tar.gz" |
+ "https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow_jni-$%7BTF_TYPE%7D-$%7BOS%7D-x86_64-1.8.0.tar.gz" |
tar -xz -C ./jni
### Install on Windows
@@ -174,10 +174,10 @@ Take the following steps to install TensorFlow for Java on Linux or macOS:
Take the following steps to install TensorFlow for Java on Windows:
1. Download
- [libtensorflow.jar](https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-1.6.0.jar),
+ [libtensorflow.jar](https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-1.8.0.jar),
which is the TensorFlow Java Archive (JAR).
2. Download the following Java Native Interface (JNI) file appropriate for
- [TensorFlow for Java on Windows](https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow_jni-cpu-windows-x86_64-1.6.0.zip).
+ [TensorFlow for Java on Windows](https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow_jni-cpu-windows-x86_64-1.8.0.zip).
3. Extract this .zip file.
@@ -225,7 +225,7 @@ must be part of your `classpath`. For example, you can include the
downloaded `.jar` in your `classpath` by using the `-cp` compilation flag
as follows:
-javac -cp libtensorflow-1.6.0.jar HelloTF.java
+javac -cp libtensorflow-1.8.0.jar HelloTF.java
### Running
@@ -239,11 +239,11 @@ two files are available to the JVM:
For example, the following command line executes the `HelloTF` program on Linux
and macOS X:
-java -cp libtensorflow-1.6.0.jar:. -Djava.library.path=./jni HelloTF
+java -cp libtensorflow-1.8.0.jar:. -Djava.library.path=./jni HelloTF
And the following command line executes the `HelloTF` program on Windows:
-java -cp libtensorflow-1.6.0.jar;. -Djava.library.path=jni HelloTF
+java -cp libtensorflow-1.8.0.jar;. -Djava.library.path=jni HelloTF
If the program prints Hello from version, you've successfully
installed TensorFlow for Java and are ready to use the API. If the program
diff --git a/install/install_linux.md b/install/install_linux.md
index 3e8744b..16a232e 100644
--- a/install/install_linux.md
+++ b/install/install_linux.md
@@ -31,23 +31,24 @@ If you are installing TensorFlow with GPU support using one of the
mechanisms described in this guide, then the following NVIDIA software
must be installed on your system:
- * CUDA® Toolkit 9.0. For details, see
- [NVIDIA's documentation](http://docs.nvidia.com/cuda/cuda-installation-guide-linux/#axzz4VZnqTJ2A).
- Ensure that you append the relevant Cuda pathnames to the
+ * [CUDA Toolkit 9.0](http://nvidia.com/cuda). For details, see
+ [NVIDIA's documentation](http://docs.nvidia.com/cuda/cuda-installation-guide-linux/).
+ Ensure that you append the relevant CUDA pathnames to the
`LD_LIBRARY_PATH` environment variable as described in the
NVIDIA documentation.
- * The NVIDIA drivers associated with CUDA Toolkit 9.0.
- * cuDNN v7.0. For details, see
- [NVIDIA's documentation](https://developer.nvidia.com/cudnn).
+ * [cuDNN SDK v7](http://developer.nvidia.com/cudnn). For details, see
+ [NVIDIA's documentation](http://docs.nvidia.com/deeplearning/sdk/cudnn-install/).
Ensure that you create the `CUDA_HOME` environment variable as
described in the NVIDIA documentation.
* GPU card with CUDA Compute Capability 3.0 or higher for building
from source and 3.5 or higher for our binaries. See
[NVIDIA documentation](https://developer.nvidia.com/cuda-gpus) for
a list of supported GPU cards.
+ * [GPU drivers](http://nvidia.com/driver) supporting your version of the CUDA
+ Toolkit.
* The libcupti-dev library, which is the NVIDIA CUDA Profile Tools Interface.
This library provides advanced profiling support. To install this library,
- issue the following command for CUDA Toolkit >= 8.0:
+ issue the following command for CUDA Toolkit >= 9.0:
$ sudo apt-get install cuda-command-line-tools
@@ -56,7 +57,7 @@ must be installed on your system:
and add its path to your `LD_LIBRARY_PATH` environment variable:
- $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/extras/CUPTI/lib64
+ $ export LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+${LD_LIBRARY_PATH}:}/usr/local/cuda/extras/CUPTI/lib64
For CUDA Toolkit <= 7.5 do:
@@ -65,16 +66,41 @@ must be installed on your system:
$ sudo apt-get install libcupti-dev
+ * **[OPTIONAL]** For optimized inferencing performance, you can also install
+ **NVIDIA TensorRT 3.0**. The minimal set of TensorRT runtime components needed
+ for use with the pre-built `tensorflow-gpu` package can be installed as follows:
+
+
+ $ wget https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1404/x86_64/nvinfer-runtime-trt-repo-ubuntu1404-3.0.4-ga-cuda9.0_1.0-1_amd64.deb
+ $ sudo dpkg -i nvinfer-runtime-trt-repo-ubuntu1404-3.0.4-ga-cuda9.0_1.0-1_amd64.deb
+ $ sudo apt-get update
+ $ sudo apt-get install -y --allow-downgrades libnvinfer-dev libcudnn7-dev=7.0.5.15-1+cuda9.0 libcudnn7=7.0.5.15-1+cuda9.0
+
+
+ **IMPORTANT:** For compatibility with the pre-built `tensorflow-gpu`
+ package, please use the Ubuntu **14.04** package of TensorRT as shown above,
+ even when installing onto an Ubuntu 16.04 system.
+
+ To build the TensorFlow-TensorRT integration module from source rather than
+ using pre-built binaries, see the [module documentation](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/tensorrt#using-tensorrt-in-tensorflow).
+ For detailed TensorRT installation instructions, see [NVIDIA's TensorRT documentation](http://docs.nvidia.com/deeplearning/sdk/tensorrt-install-guide/index.html).
+
+ To avoid cuDNN version conflicts during later system upgrades, you can hold
+ the cuDNN version at 7.0.5:
+
+
+ $ sudo apt-mark hold libcudnn7 libcudnn7-dev
+
+
+ To later allow upgrades, you can remove the hold:
+
+
+ $ sudo apt-mark unhold libcudnn7 libcudnn7-dev
+
+
If you have an earlier version of the preceding packages, please upgrade to
the specified versions. If upgrading is not possible, then you may still run
-TensorFlow with GPU support, but only if you do the following:
-
- * Install TensorFlow from sources as documented in
- @{$install_sources$Installing TensorFlow from Sources}.
- * Install or upgrade to at least the following NVIDIA versions:
- * CUDA toolkit 7.0 or greater
- * cuDNN v3 or greater
- * GPU card with CUDA Compute Capability 3.0 or higher.
+TensorFlow with GPU support, if you @{$install_sources$install TensorFlow from Sources}.
## Determine how to install TensorFlow
@@ -149,7 +175,8 @@ Take the following steps to install TensorFlow with Virtualenv:
commands:
$ source ~/tensorflow/bin/activate # bash, sh, ksh, or zsh
- $ source ~/tensorflow/bin/activate.csh # csh or tcsh
+ $ source ~/tensorflow/bin/activate.csh # csh or tcsh
+ $ . ~/tensorflow/bin/activate.fish # fish
The preceding source command should change your prompt
to the following:
@@ -189,7 +216,7 @@ Take the following steps to install TensorFlow with Virtualenv:
Virtualenv environment:
(tensorflow)$ pip3 install --upgrade \
- https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-1.6.0-cp34-cp34m-linux_x86_64.whl
+ https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-1.8.0-cp34-cp34m-linux_x86_64.whl
If you encounter installation problems, see
[Common Installation Problems](#common_installation_problems).
@@ -294,7 +321,7 @@ take the following steps:
$ sudo pip3 install --upgrade \
- https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-1.6.0-cp34-cp34m-linux_x86_64.whl
+ https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-1.8.0-cp34-cp34m-linux_x86_64.whl
If this step fails, see
@@ -480,7 +507,7 @@ Take the following steps to install TensorFlow in an Anaconda environment:
(tensorflow)$ pip install --ignore-installed --upgrade \
- https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-1.6.0-cp34-cp34m-linux_x86_64.whl
+ https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-1.8.0-cp34-cp34m-linux_x86_64.whl
## Validate your installation
@@ -530,11 +557,18 @@ TensorFlow programs:
Hello, TensorFlow!
-If you are new to TensorFlow, see @{$get_started/premade_estimators$Getting Started with TensorFlow}.
-
If the system outputs an error message instead of a greeting, see [Common
installation problems](#common_installation_problems).
+If you are new to machine learning, we recommend the following:
+
+* [Machine Learning Crash Course](https://developers.google.com/machine-learning/crash-course)
+* @{$get_started/get_started_for_beginners$Getting Started for ML Beginners}
+
+If you are experienced with machine learning but new to TensorFlow, see
+@{$get_started/premade_estimators$Getting Started with TensorFlow}.
+
+
## Common installation problems
We are relying on Stack Overflow to document TensorFlow installation problems
@@ -647,14 +681,14 @@ This section documents the relevant values for Linux installations.
CPU only:
-https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-1.6.0-cp27-none-linux_x86_64.whl
+https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-1.8.0-cp27-none-linux_x86_64.whl
GPU support:
-https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow_gpu-1.6.0-cp27-none-linux_x86_64.whl
+https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow_gpu-1.8.0-cp27-none-linux_x86_64.whl
Note that GPU support requires the NVIDIA hardware and software described in
@@ -666,14 +700,14 @@ Note that GPU support requires the NVIDIA hardware and software described in
CPU only:
-https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-1.6.0-cp34-cp34m-linux_x86_64.whl
+https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-1.8.0-cp34-cp34m-linux_x86_64.whl
GPU support:
-https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow_gpu-1.6.0-cp34-cp34m-linux_x86_64.whl
+https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow_gpu-1.8.0-cp34-cp34m-linux_x86_64.whl
Note that GPU support requires the NVIDIA hardware and software described in
@@ -685,14 +719,14 @@ Note that GPU support requires the NVIDIA hardware and software described in
CPU only:
-https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-1.6.0-cp35-cp35m-linux_x86_64.whl
+https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-1.8.0-cp35-cp35m-linux_x86_64.whl
GPU support:
-https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow_gpu-1.6.0-cp35-cp35m-linux_x86_64.whl
+https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow_gpu-1.8.0-cp35-cp35m-linux_x86_64.whl
@@ -704,14 +738,14 @@ Note that GPU support requires the NVIDIA hardware and software described in
CPU only:
-https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-1.6.0-cp36-cp36m-linux_x86_64.whl
+https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-1.8.0-cp36-cp36m-linux_x86_64.whl
GPU support:
-https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow_gpu-1.6.0-cp36-cp36m-linux_x86_64.whl
+https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow_gpu-1.8.0-cp36-cp36m-linux_x86_64.whl
diff --git a/install/install_mac.md b/install/install_mac.md
index 94defcd..c79075b 100644
--- a/install/install_mac.md
+++ b/install/install_mac.md
@@ -119,7 +119,7 @@ Take the following steps to install TensorFlow with Virtualenv:
TensorFlow in the active Virtualenv is as follows:
$ pip3 install --upgrade \
- https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-1.6.0-py3-none-any.whl
+ https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-1.8.0-py3-none-any.whl
If you encounter installation problems, see
[Common Installation Problems](#common-installation-problems).
@@ -238,11 +238,11 @@ take the following steps:
operating system and Python version. Find the appropriate
value for tfBinaryURL
[here](#the_url_of_the_tensorflow_python_package). For example, if
- you are installing TensorFlow for Mac OS and Python 2.7
+ you are installing TensorFlow for macOS and Python 2.7
issue the following command:
$ sudo pip3 install --upgrade \
- https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-1.6.0-py3-none-any.whl
+ https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-1.8.0-py3-none-any.whl
If the preceding command fails, see
[installation problems](#common-installation-problems).
@@ -350,7 +350,7 @@ Take the following steps to install TensorFlow in an Anaconda environment:
TensorFlow for Python 2.7:
(targetDirectory)$ pip install --ignore-installed --upgrade \
- https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-1.6.0-py2-none-any.whl
+ https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-1.8.0-py2-none-any.whl
@@ -400,12 +400,18 @@ writing TensorFlow programs:
Hello, TensorFlow!
-If you are new to TensorFlow, see
-@{$get_started/premade_estimators$Getting Started with TensorFlow}.
-
If the system outputs an error message instead of a greeting, see
[Common installation problems](#common_installation_problems).
+If you are new to machine learning, we recommend the following:
+
+* [Machine Learning Crash Course](https://developers.google.com/machine-learning/crash-course)
+* @{$get_started/get_started_for_beginners$Getting Started for ML Beginners}
+
+If you are experienced with machine learning but new to TensorFlow, see
+@{$get_started/premade_estimators$Getting Started with TensorFlow}.
+
+
## Common installation problems
We are relying on Stack Overflow to document TensorFlow installation problems
@@ -512,18 +518,13 @@ RuntimeError: Broken toolchain: cannot link a simple C program
## The URL of the TensorFlow Python package
A few installation mechanisms require the URL of the TensorFlow Python package.
-The value you specify depends on three factors:
-
- * operating system
- * Python version
-
-This section documents the relevant values for Mac OS installations.
+The value you specify depends on your Python version.
### Python 2.7
-https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-1.6.0-py2-none-any.whl
+https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-1.8.0-py2-none-any.whl
@@ -531,5 +532,5 @@ https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-1.6.0-py2-none-any.
-https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-1.6.0-py3-none-any.whl
+https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-1.8.0-py3-none-any.whl
diff --git a/install/install_sources.md b/install/install_sources.md
index c09c9c2..3d93736 100644
--- a/install/install_sources.md
+++ b/install/install_sources.md
@@ -133,30 +133,21 @@ The following NVIDIA hardware must be installed on your system:
The following NVIDIA software must be installed on your system:
- * NVIDIA's Cuda Toolkit (>= 7.0). We recommend version 9.0.
+ * [CUDA Toolkit](http://nvidia.com/cuda) (>= 7.0). We recommend version 9.0.
For details, see
- [NVIDIA's documentation](http://docs.nvidia.com/cuda/cuda-installation-guide-linux/#axzz4VZnqTJ2A).
- Ensure that you append the relevant Cuda pathnames to the
+ [NVIDIA's documentation](http://docs.nvidia.com/cuda/cuda-installation-guide-linux/).
+ Ensure that you append the relevant CUDA pathnames to the
`LD_LIBRARY_PATH` environment variable as described in the
NVIDIA documentation.
- * The NVIDIA drivers associated with NVIDIA's Cuda Toolkit.
- * cuDNN (>= v3). We recommend version 6.0. For details, see
- [NVIDIA's documentation](https://developer.nvidia.com/cudnn),
- particularly the description of appending the appropriate pathname
- to your `LD_LIBRARY_PATH` environment variable.
-
-Finally, you must also install `libcupti` which for Cuda Toolkit >= 8.0 you do via
-
- $ sudo apt-get install cuda-command-line-tools
-
-and add its path to your `LD_LIBRARY_PATH` environment variable:
-
- $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/extras/CUPTI/lib64
-
-For Cuda Toolkit <= 7.5, you install `libcupti-dev` by invoking the following command:
-
- $ sudo apt-get install libcupti-dev
+ * [GPU drivers](http://nvidia.com/driver) supporting your version of the CUDA
+ Toolkit.
+ * [cuDNN SDK](http://developer.nvidia.com/cudnn) (>= v3). We recommend version 7.0. For details, see
+ [NVIDIA's documentation](http://docs.nvidia.com/deeplearning/sdk/cudnn-install/).
+ * [CUPTI](http://docs.nvidia.com/cuda/cupti/) ships with the CUDA Toolkit, but
+ you also need to append its path to the `LD_LIBRARY_PATH` environment
+ variable:
+ $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/extras/CUPTI/lib64
### Next
@@ -240,8 +231,8 @@ such as compiler flags. You must run this script *prior* to
creating the pip package and installing TensorFlow.
If you wish to build TensorFlow with GPU, `configure` will ask
-you to specify the version numbers of Cuda and cuDNN. If several
-versions of Cuda or cuDNN are installed on your system, explicitly select
+you to specify the version numbers of CUDA and cuDNN. If several
+versions of CUDA or cuDNN are installed on your system, explicitly select
the desired version instead of relying on the default.
One of the questions that `configure` will ask is as follows:
@@ -289,12 +280,12 @@ Do you wish to build TensorFlow with CUDA support? [y/N] Y
CUDA support will be enabled for TensorFlow
Do you want to use clang as CUDA compiler? [y/N]
nvcc will be used as CUDA compiler
-Please specify the Cuda SDK version you want to use, e.g. 7.0. [Leave empty to default to CUDA 9.0]: 9.0
+Please specify the CUDA SDK version you want to use, e.g. 7.0. [Leave empty to default to CUDA 9.0]: 9.0
Please specify the location where CUDA 9.0 toolkit is installed. Refer to README.md for more details. [Default is /usr/local/cuda]:
Please specify which gcc should be used by nvcc as the host compiler. [Default is /usr/bin/gcc]:
Please specify the cuDNN version you want to use. [Leave empty to default to cuDNN 7.0]: 7
Please specify the location where cuDNN 7 library is installed. Refer to README.md for more details. [Default is /usr/local/cuda]:
-Please specify a list of comma-separated Cuda compute capabilities you want to build with.
+Please specify a list of comma-separated CUDA compute capabilities you want to build with.
You can find the compute capability of your device at: https://developer.nvidia.com/cuda-gpus.
Please note that each additional compute capability significantly increases your build time and binary size.
[Default is: "3.5,5.2"]: 3.0
@@ -304,14 +295,14 @@ Configuration finished
If you told `configure` to build for GPU support, then `configure`
-will create a canonical set of symbolic links to the Cuda libraries
-on your system. Therefore, every time you change the Cuda library paths,
+will create a canonical set of symbolic links to the CUDA libraries
+on your system. Therefore, every time you change the CUDA library paths,
you must rerun the `configure` script before re-invoking
the bazel build
command.
Note the following:
- * Although it is possible to build both Cuda and non-Cuda configs
+ * Although it is possible to build both CUDA and non-CUDA configs
under the same source tree, we recommend running `bazel clean` when
switching between these two configurations in the same source tree.
* If you don't run the `configure` script *before* running the
@@ -359,10 +350,10 @@ Invoke `pip install` to install that pip package.
The filename of the `.whl` file depends on your platform.
For example, the following command will install the pip package
-for TensorFlow 1.6.0 on Linux:
+for TensorFlow 1.8.0 on Linux:
-$ sudo pip install /tmp/tensorflow_pkg/tensorflow-1.6.0-py2-none-any.whl
+$ sudo pip install /tmp/tensorflow_pkg/tensorflow-1.8.0-py2-none-any.whl
## Validate your installation
@@ -459,6 +450,10 @@ Stack Overflow and specify the `tensorflow` tag.
**Linux**
Version: | CPU/GPU: | Python Version: | Compiler: | Build Tools: | cuDNN: | CUDA: |
+tensorflow-1.8.0 | CPU | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.10.0 | N/A | N/A |
+tensorflow_gpu-1.8.0 | GPU | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.9.0 | 7 | 9 |
+tensorflow-1.7.0 | CPU | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.10.0 | N/A | N/A |
+tensorflow_gpu-1.7.0 | GPU | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.9.0 | 7 | 9 |
tensorflow-1.6.0 | CPU | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.9.0 | N/A | N/A |
tensorflow_gpu-1.6.0 | GPU | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.9.0 | 7 | 9 |
tensorflow-1.5.0 | CPU | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.8.0 | N/A | N/A |
@@ -478,6 +473,8 @@ Stack Overflow and specify the `tensorflow` tag.
**Mac**
Version: | CPU/GPU: | Python Version: | Compiler: | Build Tools: | cuDNN: | CUDA: |
+tensorflow-1.8.0 | CPU | 2.7, 3.3-3.6 | Clang from xcode | Bazel 0.10.1 | N/A | N/A |
+tensorflow-1.7.0 | CPU | 2.7, 3.3-3.6 | Clang from xcode | Bazel 0.10.1 | N/A | N/A |
tensorflow-1.6.0 | CPU | 2.7, 3.3-3.6 | Clang from xcode | Bazel 0.8.1 | N/A | N/A |
tensorflow-1.5.0 | CPU | 2.7, 3.3-3.6 | Clang from xcode | Bazel 0.8.1 | N/A | N/A |
tensorflow-1.4.0 | CPU | 2.7, 3.3-3.6 | Clang from xcode | Bazel 0.5.4 | N/A | N/A |
@@ -492,6 +489,10 @@ Stack Overflow and specify the `tensorflow` tag.
**Windows**
Version: | CPU/GPU: | Python Version: | Compiler: | Build Tools: | cuDNN: | CUDA: |
+tensorflow-1.8.0 | CPU | 3.5-3.6 | MSVC 2015 update 3 | Cmake v3.6.3 | N/A | N/A |
+tensorflow_gpu-1.8.0 | GPU | 3.5-3.6 | MSVC 2015 update 3 | Cmake v3.6.3 | 7 | 9 |
+tensorflow-1.7.0 | CPU | 3.5-3.6 | MSVC 2015 update 3 | Cmake v3.6.3 | N/A | N/A |
+tensorflow_gpu-1.7.0 | GPU | 3.5-3.6 | MSVC 2015 update 3 | Cmake v3.6.3 | 7 | 9 |
tensorflow-1.6.0 | CPU | 3.5-3.6 | MSVC 2015 update 3 | Cmake v3.6.3 | N/A | N/A |
tensorflow_gpu-1.6.0 | GPU | 3.5-3.6 | MSVC 2015 update 3 | Cmake v3.6.3 | 7 | 9 |
tensorflow-1.5.0 | CPU | 3.5-3.6 | MSVC 2015 update 3 | Cmake v3.6.3 | N/A | N/A |
diff --git a/install/install_windows.md b/install/install_windows.md
index 2413bc9..86add74 100644
--- a/install/install_windows.md
+++ b/install/install_windows.md
@@ -17,7 +17,7 @@ You must choose one of the following types of TensorFlow to install:
NVIDIA® GPU, you must install this version. Note that this version of
TensorFlow is typically much easier to install (typically,
in 5 or 10 minutes), so even if you have an NVIDIA GPU, we recommend
- installing this version first. Prebuilt binaries will use AVX instructions.
+ installing this version first. Prebuilt binaries will use AVX instructions.
* **TensorFlow with GPU support**. TensorFlow programs typically run
significantly faster on a GPU than on a CPU. Therefore, if your
system has a NVIDIA® GPU meeting the prerequisites shown below
@@ -154,13 +154,17 @@ TensorFlow programs:
Hello, TensorFlow!
-If you are new to TensorFlow, see @{$get_started/premade_estimators$Getting Started with TensorFlow}.
-
If the system outputs an error message instead of a greeting, see [Common
installation problems](#common_installation_problems).
-There is also a helpful [script](https://gist.github.com/mrry/ee5dbcfdd045fa48a27d56664411d41c)
-for Windows TensorFlow installation issues.
+If you are new to machine learning, we recommend the following:
+
+* [Machine Learning Crash Course](https://developers.google.com/machine-learning/crash-course)
+* @{$get_started/get_started_for_beginners$Getting Started for ML Beginners}
+
+If you are experienced with machine learning but new to TensorFlow, see
+@{$get_started/premade_estimators$Getting Started with TensorFlow}.
+
## Common installation problems
diff --git a/javascript/index.md b/javascript/index.md
new file mode 100644
index 0000000..ad63eeb
--- /dev/null
+++ b/javascript/index.md
@@ -0,0 +1,5 @@
+# JavaScript
+
+You may develop TensorFlow programs in JavaScript, training and deploying
+models right in your browser. For details, see
+[js.tensorflow.org](https://js.tensorflow.org).
diff --git a/javascript/leftnav_files b/javascript/leftnav_files
new file mode 100644
index 0000000..fc0ab8a
--- /dev/null
+++ b/javascript/leftnav_files
@@ -0,0 +1 @@
+index.md
diff --git a/mobile/leftnav_files b/mobile/leftnav_files
index 4cf134c..585470d 100644
--- a/mobile/leftnav_files
+++ b/mobile/leftnav_files
@@ -1,6 +1,7 @@
index.md
### TensorFlow Lite
tflite/index.md
+tflite/devguide.md
tflite/demo_android.md
tflite/demo_ios.md
>>>
diff --git a/mobile/optimizing.md b/mobile/optimizing.md
index ca9cb04..778e4d3 100644
--- a/mobile/optimizing.md
+++ b/mobile/optimizing.md
@@ -233,6 +233,8 @@ order by how long they took. From left to right, the columns are:
- The cumulative total time of this and the previous ops in the table. This is
handy for understanding what the distribution of work is across the layers, to
see if just a few of the nodes are taking up most of the time.
+
+- The amount of memory consumed by outputs of this type of op.
- Name of the node.
diff --git a/mobile/prepare_models.md b/mobile/prepare_models.md
index 360ee30..8b22c04 100644
--- a/mobile/prepare_models.md
+++ b/mobile/prepare_models.md
@@ -60,7 +60,7 @@ and serialized as protocol buffers:
the `NodeDef`, so if all the `Variable` weights are converted to `Const` nodes,
then we only need a single `GraphDef` file to hold the model architecture and
the weights. Freezing the graph handles the process of loading the
- checkpoints, and then converts all Consts to Variables. You can then load the
+ checkpoints, and then converts all Variables to Consts. You can then load the
resulting file in a single call, without having to restore variable values
from checkpoints. One thing to watch out for with `GraphDef` files is that
sometimes they’re stored in text format for easy inspection. These versions
diff --git a/mobile/tflite/demo_android.md b/mobile/tflite/demo_android.md
index c94b559..7f2f888 100644
--- a/mobile/tflite/demo_android.md
+++ b/mobile/tflite/demo_android.md
@@ -1,42 +1,144 @@
-# TensorFlow Lite Demo for Android
+# Android Demo App
-The TensorFlow Lite demo is a camera app that continuously classifies whatever
-it sees from your device's back camera, using a quantized MobileNet model.
+An example Android application using TensorFLow Lite is available
+[on GitHub](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/lite/java/demo/app).
+The demo is a sample camera app that classifies images continuously
+using either a quantized Mobilenet model or a floating point Inception-v3 model.
+To run the demo, a device running Android 5.0 ( API 21) or higher is required.
-You'll need an Android device running Android 5.0 or higher to run the demo.
+In the demo app, inference is done using the TensorFlow Lite Java API. The demo
+app classifies frames in real-time, displaying the top most probable
+classifications. It also displays the time taken to detect the object.
-To get you started working with TensorFlow Lite on Android, we'll walk you
-through building and deploying our TensorFlow demo app in Android Studio.
+There are three ways to get the demo app to your device:
-Note: For a more detailed guide see the
-[TFLite Codelab](https://codelabs.developers.google.com/codelabs/tensorflow-for-poets-2-tflite/index.html#0)
+* Download the [prebuilt binary APK](http://download.tensorflow.org/deps/tflite/TfLiteCameraDemo.apk).
+* Use Android Studio to build the application.
+* Download the source code for TensorFlow Lite and the demo and build it using
+ bazel.
-It's also possible to build the demo app with Bazel, but we only recommend
-this for advanced users who are very familiar with the Bazel build
-environment. For more information on that, see our page [on Github](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/lite#building-tensorflow-lite-and-the-demo-app-from-source).
-## Build and deploy with Android Studio
+## Download the pre-built binary
-1. Clone the TensorFlow repository from GitHub if you haven't already:
+The easiest way to try the demo is to download the
+[pre-built binary APK](https://storage.googleapis.com/download.tensorflow.org/deps/tflite/TfLiteCameraDemo.apk)
- git clone https://github.com/tensorflow/tensorflow
+Once the APK is installed, click the app icon to start the program. The first
+time the app is opened, it asks for runtime permissions to access the device
+camera. The demo app opens the back-camera of the device and recognizes objects
+in the camera's field of view. At the bottom of the image (or at the left
+of the image if the device is in landscape mode), it displays top three objects
+classified and the classification latency.
-2. Install the latest version of Android Studio from [here](https://developer.android.com/studio/index.html).
-3. From the **Welcome to Android Studio** screen, use the **Import Project
- (Gradle, Eclipse ADT, etc)** option to import the
- `tensorflow/contrib/lite/java/demo` directory as an existing Android Studio
- Project.
+## Build in Android Studio with TensorFlow Lite AAR from JCenter
- Android Studio may prompt you to install Gradle upgrades and other tool
- versions; you should accept these upgrades.
+Use Android Studio to try out changes in the project code and compile the demo
+app:
-4. Download the TensorFlow Lite MobileNet model from [here](https://storage.googleapis.com/download.tensorflow.org/models/tflite/mobilenet_v1_224_android_quant_2017_11_08.zip).
+* Install the latest version of
+ [Android Studio](https://developer.android.com/studio/index.html).
+* Make sure the Android SDK version is greater than 26 and NDK version is greater
+ than 14 (in the Android Studio settings).
+* Import the `tensorflow/contrib/lite/java/demo` directory as a new
+ Android Studio project.
+* Install all the Gradle extensions it requests.
- Unzip this and copy the `mobilenet_quant_v1_224.tflite` file to the assets
- directory: `tensorflow/contrib/lite/java/demo/app/src/main/assets/`
+To get a model, either:
-5. Build and run the app in Android Studio.
+* Download the quantized [Mobilenet TensorFlow Lite model](https://storage.googleapis.com/download.tensorflow.org/models/tflite/mobilenet_v1_224_android_quant_2017_11_08.zip)
+ and unzip and copy `mobilenet_quant_v1_224.tflite` to the assets directory:
+ `tensorflow/contrib/lite/java/demo/app/src/main/assets/`.
+* Or, download the floating point [Inception-v3 model](https://storage.googleapis.com/download.tensorflow.org/models/tflite/inception_v3_slim_2016_android_2017_11_10.zip)
+ and unzip and copy `inceptionv3_non_slim_2015.tflite` to the assets
+ directory. Change the chosen classifier in
+ [Camera2BasicFragment.java](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/lite/java/demo/app/src/main/java/com/example/android/tflitecamerademo/Camera2BasicFragment.java)
+ from: `classifier = new ImageClassifierQuantizedMobileNet(getActivity());`
+ to: `classifier = new ImageClassifierFloatInception(getActivity());`.
-You'll have to grant permissions for the app to use the device's camera. Point
-the camera at various objects and enjoy seeing how the model classifies things!
+Now you can build and run the demo app.
+
+
+## Build TensorFlow Lite and the demo app from source
+
+### Clone the TensorFlow repo
+
+```sh
+git clone https://github.com/tensorflow/tensorflow
+```
+
+### Install Bazel
+
+If `bazel` is not installed on your system, see
+[Installing Bazel](https://bazel.build/versions/master/docs/install.html).
+
+Note: Bazel does not currently support Android builds on Windows. Windows users
+should download the
+[prebuilt binary](https://storage.googleapis.com/download.tensorflow.org/deps/tflite/TfLiteCameraDemo.apk).
+
+### Install Android NDK and SDK
+
+The Android NDK is required to build the native (C/C++) TensorFlow Lite code. The
+current recommended version is *14b* and can be found on the
+[NDK Archives](https://developer.android.com/ndk/downloads/older_releases.html#ndk-14b-downloads)
+page.
+
+The Android SDK and build tools can be
+[downloaded separately](https://developer.android.com/tools/revisions/build-tools.html)
+or used as part of
+[Android Studio](https://developer.android.com/studio/index.html). To build the
+TensorFlow Lite Android demo, build tools require API >= 23 (but it will run on
+devices with API >= 21).
+
+In the root of the TensorFlow repository, update the `WORKSPACE` file with the
+`api_level` and location of the SDK and NDK. If you installed it with
+Android Studio, the SDK path can be found in the SDK manager. The default NDK
+path is:`{SDK path}/ndk-bundle.` For example:
+
+```
+android_sdk_repository (
+ name = "androidsdk",
+ api_level = 23,
+ build_tools_version = "23.0.2",
+ path = "/home/xxxx/android-sdk-linux/",
+)
+
+android_ndk_repository(
+ name = "androidndk",
+ path = "/home/xxxx/android-ndk-r10e/",
+ api_level = 19,
+)
+```
+
+Some additional details are available on the
+[TF Lite Android App page](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/lite/java/demo/README.md).
+
+### Build the source code
+
+To build the demo app, run `bazel`:
+
+```
+bazel build --cxxopt=--std=c++11 //tensorflow/contrib/lite/java/demo/app/src/main:TfLiteCameraDemo
+```
+
+Caution: Because of an bazel bug, we only support building the Android demo app
+within a Python 2 environment.
+
+
+## About the demo
+
+The demo app is resizing each camera image frame (224 width * 224 height) to
+match the quantized MobileNets model (299 * 299 for Inception-v3). The resized
+image is converted—row by row—into a
+[ByteBuffer](https://developer.android.com/reference/java/nio/ByteBuffer.html).
+Its size is 1 * 224 * 224 * 3 bytes, where 1 is the number of images in a batch.
+224 * 224 (299 * 299) is the width and height of the image. 3 bytes represents
+the 3 colors of a pixel.
+
+This demo uses the TensorFlow Lite Java inference API
+for models which take a single input and provide a single output. This outputs a
+two-dimensional array, with the first dimension being the category index and the
+second dimension being the confidence of classification. Both models have 1001
+unique categories and the app sorts the probabilities of all the categories and
+displays the top three. The model file must be downloaded and bundled within the
+assets directory of the app.
diff --git a/mobile/tflite/demo_ios.md b/mobile/tflite/demo_ios.md
index 3ee9b1c..3be21da 100644
--- a/mobile/tflite/demo_ios.md
+++ b/mobile/tflite/demo_ios.md
@@ -1,4 +1,4 @@
-# TensorFlow Lite Demo for iOS
+# iOS Demo App
The TensorFlow Lite demo is a camera app that continuously classifies whatever
it sees from your device's back camera, using a quantized MobileNet model. These
diff --git a/mobile/tflite/devguide.md b/mobile/tflite/devguide.md
new file mode 100644
index 0000000..4133bc1
--- /dev/null
+++ b/mobile/tflite/devguide.md
@@ -0,0 +1,231 @@
+# Developer Guide
+
+Using a TensorFlow Lite model in your mobile app requires multiple
+considerations: you must choose a pre-trained or custom model, convert the model
+to a TensorFLow Lite format, and finally, integrate the model in your app.
+
+## 1. Choose a model
+
+Depending on the use case, you can choose one of the popular open-sourced models,
+such as *InceptionV3* or *MobileNets*, and re-train these models with a custom
+data set or even build your own custom model.
+
+### Use a pre-trained model
+
+[MobileNets](https://research.googleblog.com/2017/06/mobilenets-open-source-models-for.html)
+is a family of mobile-first computer vision models for TensorFlow designed to
+effectively maximize accuracy, while taking into consideration the restricted
+resources for on-device or embedded applications. MobileNets are small,
+low-latency, low-power models parameterized to meet the resource constraints for
+a variety of uses. They can be used for classification, detection, embeddings, and
+segmentation—similar to other popular large scale models, such as
+[Inception](https://arxiv.org/pdf/1602.07261.pdf). Google provides 16 pre-trained
+[ImageNet](http://www.image-net.org/challenges/LSVRC/) classification checkpoints
+for MobileNets that can be used in mobile projects of all sizes.
+
+[Inception-v3](https://arxiv.org/abs/1512.00567) is an image recognition model
+that achieves fairly high accuracy recognizing general objects with 1000 classes,
+for example, "Zebra", "Dalmatian", and "Dishwasher". The model extracts general
+features from input images using a convolutional neural network and classifies
+them based on those features with fully-connected and softmax layers.
+
+[On Device Smart Reply](https://research.googleblog.com/2017/02/on-device-machine-intelligence.html)
+is an on-device model that provides one-touch replies for incoming text messages
+by suggesting contextually relevant messages. The model is built specifically for
+memory constrained devices, such as watches and phones, and has been successfully
+used in Smart Replies on Android Wear. Currently, this model is Android-specific.
+
+These pre-trained models are [available for download](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/lite/g3doc/models.md)
+
+### Re-train Inception-V3 or MobileNet for a custom data set
+
+These pre-trained models were trained on the *ImageNet* data set which contains
+1000 predefined classes. If these classes are not sufficient for your use case,
+the model will need to be re-trained. This technique is called
+*transfer learning* and starts with a model that has been already trained on a
+problem, then retrains the model on a similar problem. Deep learning from
+scratch can take days, but transfer learning is fairly quick. In order to do
+this, you need to generate a custom data set labeled with the relevant classes.
+
+The [TensorFlow for Poets](https://codelabs.developers.google.com/codelabs/tensorflow-for-poets/)
+codelab walks through the re-training process step-by-step. The code supports
+both floating point and quantized inference.
+
+### Train a custom model
+
+A developer may choose to train a custom model using Tensorflow (see the
+@{$tutorials} for examples of building and training models). If you have already
+written a model, the first step is to export this to a @{tf.GraphDef} file. This
+is required because some formats do not store the model structure outside the
+code, and we must communicate with other parts of the framework. See
+[Exporting the Inference Graph](https://github.com/tensorflow/models/blob/master/research/slim/README.md)
+to create .pb file for the custom model.
+
+TensorFlow Lite currently supports a subset of TensorFlow operators. Refer to the
+[TensorFlow Lite & TensorFlow Compatibility Guide](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/lite/g3doc/tf_ops_compatibility.md)
+for supported operators and their usage. This set of operators will continue to
+grow in future Tensorflow Lite releases.
+
+
+## 2. Convert the model format
+
+The model generated (or downloaded) in the previous step is a *standard*
+Tensorflow model and you should now have a .pb or .pbtxt @{tf.GraphDef} file.
+Models generated with transfer learning (re-training) or custom models must be
+converted—but, we must first freeze the graph to convert the model to the
+Tensorflow Lite format. This process uses several model formats:
+
+* @{tf.GraphDef} (.pb) —A protobuf that represents the TensorFlow training or
+ computation graph. It contains operators, tensors, and variables definitions.
+* *CheckPoint* (.ckpt) —Serialized variables from a TensorFlow graph. Since this
+ does not contain a graph structure, it cannot be interpreted by itself.
+* `FrozenGraphDef` —A subclass of `GraphDef` that does not contain
+ variables. A `GraphDef` can be converted to a `FrozenGraphDef` by taking a
+ CheckPoint and a `GraphDef`, and converting each variable into a constant
+ using the value retrieved from the CheckPoint.
+* `SavedModel` —A `GraphDef` and CheckPoint with a signature that labels
+ input and output arguments to a model. A `GraphDef` and CheckPoint can be
+ extracted from a `SavedModel`.
+* *TensorFlow Lite model* (.tflite) —A serialized
+ [FlatBuffer](https://google.github.io/flatbuffers/) that contains TensorFlow
+ Lite operators and tensors for the TensorFlow Lite interpreter, similar to a
+ `FrozenGraphDef`.
+
+### Freeze Graph
+
+To use the `GraphDef` .pb file with TensorFlow Lite, you must have checkpoints
+that contain trained weight parameters. The .pb file only contains the structure
+of the graph. The process of merging the checkpoint values with the graph
+structure is called *freezing the graph*.
+
+You should have a checkpoints folder or download them for a pre-trained model
+(for example,
+[MobileNets](https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet_v1.md)).
+
+To freeze the graph, use the following command (changing the arguments):
+
+```
+freeze_graph --input_graph=/tmp/mobilenet_v1_224.pb \
+ --input_checkpoint=/tmp/checkpoints/mobilenet-10202.ckpt \
+ --input_binary=true \
+ --output_graph=/tmp/frozen_mobilenet_v1_224.pb \
+ --output_node_names=MobileNetV1/Predictions/Reshape_1
+```
+
+The `input_binary` flag must be enabled so the protobuf is read and written in
+a binary format. Set the `input_graph` and `input_checkpoint` files.
+
+The `output_node_names` may not be obvious outside of the code that built the
+model. The easiest way to find them is to visualize the graph, either with
+[TensorBoard](https://codelabs.developers.google.com/codelabs/tensorflow-for-poets-2/#3)
+or `graphviz`.
+
+The frozen `GraphDef` is now ready for conversion to the `FlatBuffer` format
+(.tflite) for use on Android or iOS devices. For Android, the Tensorflow
+Optimizing Converter tool supports both float and quantized models. To convert
+the frozen `GraphDef` to the .tflite format:
+
+```
+toco --input_file=$(pwd)/mobilenet_v1_1.0_224/frozen_graph.pb \
+ --input_format=TENSORFLOW_GRAPHDEF \
+ --output_format=TFLITE \
+ --output_file=/tmp/mobilenet_v1_1.0_224.tflite \
+ --inference_type=FLOAT \
+ --input_type=FLOAT \
+ --input_arrays=input \
+ --output_arrays=MobilenetV1/Predictions/Reshape_1 \
+ --input_shapes=1,224,224,3
+```
+
+The `input_file` argument should reference the frozen `GraphDef` file
+containing the model architecture. The [frozen_graph.pb](https://storage.googleapis.com/download.tensorflow.org/models/mobilenet_v1_1.0_224_frozen.tgz)
+file used here is available for download. `output_file` is where the TensorFlow
+Lite model will get generated. The `input_type` and `inference_type`
+arguments should be set to `FLOAT`, unless converting a
+@{$performance/quantization$quantized model}. Setting the `input_array`,
+`output_array`, and `input_shape` arguments are not as straightforward. The
+easiest way to find these values is to explore the graph using Tensorboard. Reuse
+the arguments for specifying the output nodes for inference in the
+`freeze_graph` step.
+
+It is also possible to use the Tensorflow Optimizing Converter with protobufs
+from either Python or from the command line (see the
+[toco_from_protos.py](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/lite/toco/python/toco_from_protos.py)
+example). This allows you to integrate the conversion step into the model design
+workflow, ensuring the model is easily convertible to a mobile inference graph.
+For example:
+
+```python
+import tensorflow as tf
+
+img = tf.placeholder(name="img", dtype=tf.float32, shape=(1, 64, 64, 3))
+val = img + tf.constant([1., 2., 3.]) + tf.constant([1., 4., 4.])
+out = tf.identity(val, name="out")
+
+with tf.Session() as sess:
+ tflite_model = tf.contrib.lite.toco_convert(sess.graph_def, [img], [out])
+ open("converteds_model.tflite", "wb").write(tflite_model)
+```
+
+For usage, see the Tensorflow Optimizing Converter
+[command-line examples](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/lite/toco/g3doc/cmdline_examples.md).
+
+Refer to the
+[Ops compatibility guide](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/lite/g3doc/tf_ops_compatibility.md)
+for troubleshooting help, and if that doesn't help, please
+[file an issue](https://github.com/tensorflow/tensorflow/issues).
+
+The [development repo](https://github.com/tensorflow/tensorflow) contains a tool
+to visualize TensorFlow Lite models after conversion. To build the
+[visualize.py](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/lite/tools/visualize.py)
+tool:
+
+```sh
+bazel run tensorflow/contrib/lite/tools:visualize -- model.tflite model_viz.html
+```
+
+This generates an interactive HTML page listing subgraphs, operations, and a
+graph visualization.
+
+
+## 3. Use the TensorFlow Lite model for inference in a mobile app
+
+After completing the prior steps, you should now have a `.tflite` model file.
+
+### Android
+
+Since Android apps are written in Java and the core TensorFlow library is in C++,
+a JNI library is provided as an interface. This is only meant for inference—it
+provides the ability to load a graph, set up inputs, and run the model to
+calculate outputs.
+
+The open source Android demo app uses the JNI interface and is available
+[on GitHub](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/lite/java/demo/app).
+You can also download a
+[prebuilt APK](http://download.tensorflow.org/deps/tflite/TfLiteCameraDemo.apk).
+See the @{$tflite/demo_android} guide for details.
+
+The @{$mobile/android_build} guide has instructions for installing TensorFlow on
+Android and setting up `bazel` and Android Studio.
+
+### iOS
+
+To integrate a TensorFlow model in an iOS app, see the
+[TensorFlow Lite for iOS](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/lite/g3doc/ios.md)
+guide and @{$tflite/demo_ios} guide.
+
+#### Core ML support
+
+Core ML is a machine learning framework used in Apple products. In addition to
+using Tensorflow Lite models directly in your applications, you can convert
+trained Tensorflow models to the
+[CoreML](https://developer.apple.com/machine-learning/) format for use on Apple
+devices. To use the converter, refer to the
+[Tensorflow-CoreML converter documentation](https://github.com/tf-coreml/tf-coreml).
+
+### Raspberry Pi
+
+Compile Tensorflow Lite for a Raspberry Pi by following the
+[RPi build instructions](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/lite/g3doc/rpi.md)
+This compiles a static library file (`.a`) used to build your app. There are
+plans for Python bindings and a demo app.
diff --git a/mobile/tflite/index.md b/mobile/tflite/index.md
index beb2479..11f11ea 100644
--- a/mobile/tflite/index.md
+++ b/mobile/tflite/index.md
@@ -155,7 +155,9 @@ retraining for both floating point and quantized inference.
The following diagram shows the architectural design of TensorFlow Lite:
-
+
Starting with a trained TensorFlow model on disk, you'll convert that model to
the TensorFlow Lite file format (`.tflite`) using the TensorFlow Lite
diff --git a/performance/leftnav_files b/performance/leftnav_files
index d11a7e5..1f894c3 100644
--- a/performance/leftnav_files
+++ b/performance/leftnav_files
@@ -1,3 +1,4 @@
+index.md
performance_guide.md
datasets_performance.md
performance_models.md
diff --git a/performance/performance_guide.md b/performance/performance_guide.md
index cd47fc2..580a899 100644
--- a/performance/performance_guide.md
+++ b/performance/performance_guide.md
@@ -78,7 +78,7 @@ training CIFAR-10 illustrates the use of the `tf.data` API along with
The `tf.data` API utilizes C++ multi-threading and has a much lower overhead
than the Python-based `queue_runner` that is limited by Python's multi-threading
performance. A detailed performance guide for the `tf.data` API can be found
-[here](#datasets_performance).
+[here](@{$datasets_performance}).
While feeding data using a `feed_dict` offers a high level of flexibility, in
general `feed_dict` does not provide a scalable solution. If only a single GPU
diff --git a/performance/xla/jit.md b/performance/xla/jit.md
index d4dc3e5..d9a979c 100644
--- a/performance/xla/jit.md
+++ b/performance/xla/jit.md
@@ -157,7 +157,7 @@ to fuse Ops is visible by starting at `hlo_graph_0.dot` and viewing each diagram
in succession.
To Render the .dot file into a png, install
-[GraphViz](http://www.graphviz.org/Download..php) and run:
+[GraphViz](https://www.graphviz.org/download/) and run:
```shell
dot -Tpng hlo_graph_80.dot -o hlo_graph_80.png
diff --git a/performance/xla/operation_semantics.md b/performance/xla/operation_semantics.md
index 712d425..217ab59 100644
--- a/performance/xla/operation_semantics.md
+++ b/performance/xla/operation_semantics.md
@@ -241,13 +241,10 @@ See also
Clamps an operand to within the range between a minimum and maximum value.
- `Clamp(computation, args...)`
+ `Clamp(min, operand, max)`
| Arguments | Type | Semantics |
| ------------- | ----------------------- | -------------------------------- |
-| `computation` | `Computation` | computation of type `T_0, T_1, |
-: : : ..., T_N -> S` with N parameters :
-: : : of arbitrary type :
| `min` | `ComputationDataHandle` | array of type T |
| `operand` | `ComputationDataHandle` | array of type T |
| `max` | `ComputationDataHandle` | array of type T |
@@ -257,7 +254,7 @@ the range between the minimum and maximum, else returns the minimum value if the
operand is below this range or the maximum value if the operand is above this
range. That is, `clamp(a, x, b) = min(max(a, x), b)`.
-All three arrays must be the same shape. Alternately, as a restricted form of
+All three arrays must be the same shape. Alternatively, as a restricted form of
[broadcasting](broadcasting.md), `min` and/or `max` can be a scalar of type `T`.
Example with scalar `min` and `max`:
@@ -791,9 +788,7 @@ DynamicSlice extracts a sub-array from the input array at dynamic
dimension: [start, start + size). The shape of `start_indices` must be rank ==
1, with dimension size equal to the rank of `operand`.
Note: handling of out-of-bounds slice indices (generated by incorrect runtime
-calculation of 'start_indices') is currently implementation-defined. Currently,
-slice indices are computed modulo input dimension sizes to prevent out-of-bound
-array accesses, but this behavior may change in future implementations.
+calculation of 'start_indices') is currently implementation-defined.
`DynamicSlice(operand, start_indices, size_indices)`
@@ -850,9 +845,7 @@ is updated.
The shape of `start_indices` must be rank == 1, with dimension size equal to
the rank of `operand`.
Note: handling of out-of-bounds slice indices (generated by incorrect runtime
-calculation of 'start_indices') is currently implementation-defined. Currently,
-slice indices are computed modulo update dimension sizes to prevent out-of-bound
-array accesses, but this behavior may change in future implementations.
+calculation of 'start_indices') is currently implementation-defined.
`DynamicUpdateSlice(operand, update, start_indices)`
diff --git a/programmers_guide/debugger.md b/programmers_guide/debugger.md
index 5fb1c2d..f5a0eb0 100644
--- a/programmers_guide/debugger.md
+++ b/programmers_guide/debugger.md
@@ -4,29 +4,28 @@
[TOC]
-TensorFlow debugger (**tfdbg**) is a specialized debugger for TensorFlow. It
-lets you view the internal structure and states of running TensorFlow graphs
-during training and inference, which is difficult to debug with general-purpose
-debuggers such as Python's `pdb` due to TensorFlow's computation-graph paradigm.
-
-> NOTE: TensorFlow debugger uses a
-> [curses](https://en.wikipedia.org/wiki/Curses_\(programming_library\))-based
-> text user interface. On Mac OS X, the `ncurses` library is required and can
-> be installed with `brew install homebrew/dupes/ncurses`. On Windows, curses
-> isn't as well supported, so a
-> [readline](https://en.wikipedia.org/wiki/GNU_Readline)-based interface can
-> be used with tfdbg by installing `pyreadline` with pip.
-> If you use Anaconda3, you can install it with a command
-> such as `"C:\Program Files\Anaconda3\Scripts\pip.exe" install pyreadline`.
-> Unofficial Windows curses packages can be downloaded
-> [here](https://www.lfd.uci.edu/~gohlke/pythonlibs/#curses), then subsequently
-> installed using `pip install .whl`, however curses on Windows
-> may not work as reliably as curses on Linux or Mac.
-
-> NOTE: This guide focuses on the command-line interface (CLI) of tfdbg. For
-> guide on how to use the graphical user interface (GUI) of tfdbg, i.e., the
-> **TensorBoard Debugger Plugin**, please visit
-> [its README](https://github.com/tensorflow/tensorboard/blob/master/tensorboard/plugins/debugger/README.md).
+`tfdbg` is a specialized debugger for TensorFlow. It lets you view the internal
+structure and states of running TensorFlow graphs during training and inference,
+which is difficult to debug with general-purpose debuggers such as Python's `pdb`
+due to TensorFlow's computation-graph paradigm.
+
+This guide focuses on the command-line interface (CLI) of `tfdbg`. For guide on
+how to use the graphical user interface (GUI) of tfdbg, i.e., the
+**TensorBoard Debugger Plugin**, please visit
+[its README](https://github.com/tensorflow/tensorboard/blob/master/tensorboard/plugins/debugger/README.md).
+
+Note: The TensorFlow debugger uses a
+[curses](https://en.wikipedia.org/wiki/Curses_\(programming_library\))-based text
+user interface. On Mac OS X, the `ncurses` library is required and can be
+installed with `brew install homebrew/dupes/ncurses`. On Windows, curses isn't as
+well supported, so a [readline](https://en.wikipedia.org/wiki/GNU_Readline)-based
+interface can be used with tfdbg by installing `pyreadline` with `pip`. If you
+use Anaconda3, you can install it with a command such as
+`"C:\Program Files\Anaconda3\Scripts\pip.exe" install pyreadline`. Unofficial
+Windows curses packages can be downloaded
+[here](https://www.lfd.uci.edu/~gohlke/pythonlibs/#curses), then subsequently
+installed using `pip install .whl`, however curses on Windows may
+not work as reliably as curses on Linux or Mac.
This tutorial demonstrates how to use the **tfdbg** CLI to debug the appearance
of [`nan`s](https://en.wikipedia.org/wiki/NaN)
@@ -155,6 +154,7 @@ Try the following commands at the `tfdbg>` prompt (referencing the code at
| | `-n ` | List dumped tensors with names matching given regular-expression pattern. | `lt -n Softmax.*` |
| | `-t ` | List dumped tensors with op types matching given regular-expression pattern. | `lt -t MatMul` |
| | `-f ` | List only the tensors that pass a registered tensor filter. | `lt -f has_inf_or_nan` |
+| | `-f -fenn ` | List only the tensors that pass a registered tensor filter, excluding nodes with names matching the regular expression. | `lt -f has_inf_or_nan` `-fenn .*Sqrt.*` |
| | `-s ` | Sort the output by given `sort_key`, whose possible values are `timestamp` (default), `dump_size`, `op_type` and `tensor_name`. | `lt -s dump_size` |
| | `-r` | Sort in reverse order. | `lt -r -s dump_size` |
| **`pt`** | | **Print value of a dumped tensor.** | |
@@ -200,6 +200,7 @@ Try the following commands at the `tfdbg>` prompt (referencing the code at
| | `-n` | Execute through the next `Session.run` without debugging, and drop to CLI right before the run after that. | `run -n` |
| | `-t ` | Execute `Session.run` `T - 1` times without debugging, followed by a run with debugging. Then drop to CLI right after the debugged run. | `run -t 10` |
| | `-f ` | Continue executing `Session.run` until any intermediate tensor triggers the specified Tensor filter (causes the filter to return `True`). | `run -f has_inf_or_nan` |
+| | `-f -fenn ` | Continue executing `Session.run` until any intermediate tensor whose node names doesn't match the regular expression triggers the specified Tensor filter (causes the filter to return `True`). | `run -f has_inf_or_nan -fenn .*Sqrt.*` |
| | `--node_name_filter ` | Execute the next `Session.run`, watching only nodes with names matching the given regular-expression pattern. | `run --node_name_filter Softmax.*` |
| | `--op_type_filter ` | Execute the next `Session.run`, watching only nodes with op types matching the given regular-expression pattern. | `run --op_type_filter Variable.*` |
| | `--tensor_dtype_filter ` | Execute the next `Session.run`, dumping only Tensors with data types (`dtype`s) matching the given regular-expression pattern. | `run --tensor_dtype_filter int.*` |
@@ -459,7 +460,7 @@ accuracy_score = classifier.evaluate(x=test_set.data,
[debug_tflearn_iris.py](https://www.tensorflow.org/code/tensorflow/python/debug/examples/debug_tflearn_iris.py),
-based on {$tflearn$tf-learn's iris tutorial}, contains a full example of how to
+based on [tf-learn's iris tutorial](https://www.tensorflow.org/versions/r1.2/get_started/tflearn), contains a full example of how to
use the tfdbg with `Estimator`s. To run this example, do:
```none
@@ -746,15 +747,16 @@ There are three possible workarounds or solutions:
to which tfdbg dumps the debug data. You can use it to let tfdbg dump the
debug data on a disk with larger free space. For example:
- ``` python
- # For LocalCLIDebugWrapperSession
- sess = tf_debug.LocalCLIDebugWrapperSession(dump_root="/with/lots/of/space")
+```python
+# For LocalCLIDebugWrapperSession
+sess = tf_debug.LocalCLIDebugWrapperSession(dump_root="/with/lots/of/space")
- # For LocalCLIDebugHook
- hooks = [tf_debug.LocalCLIDebugHook(dump_root="/with/lots/of/space")]
- ```
+# For LocalCLIDebugHook
+hooks = [tf_debug.LocalCLIDebugHook(dump_root="/with/lots/of/space")]
+```
Make sure that the directory pointed to by dump_root is empty or nonexistent.
- tfdbg cleans up the dump directories before exiting.
+ `tfdbg` cleans up the dump directories before exiting.
+
* Reduce the batch size used during the runs.
* Use the filtering options of tfdbg's `run` command to watch only specific
nodes in the graph. For example:
@@ -812,6 +814,20 @@ sess.run(b)
the constant-folding would not occur and `tfdbg` should show the intermediate
tensor dumps.
+
+**Q**: I am debugging a model that generates unwanted infinities or NaNs. But
+ there are some nodes in my model that are known to generate infinities
+ or NaNs in their output tensors even under completely normal conditions.
+ How can I skip those nodes during my `run -f has_inf_or_nan` actions?
+
+**A**: Use the `--filter_exclude_node_names` (`-fenn` for short) flag. For
+ example, if you known you have a node with name matching the regular
+ expression `.*Sqrt.*` that generates infinities or NaNs regardless
+ of whether the model is behaving correctly, you can exclude the nodes
+ from the infinity/NaN-finding runs with the command
+ `run -f has_inf_or_nan -fenn .*Sqrt.*`.
+
+
**Q**: Is there a GUI for tfdbg?
**A**: Yes, the **TensorBoard Debugger Plugin** is the GUI of tfdbg.
diff --git a/programmers_guide/eager.md b/programmers_guide/eager.md
new file mode 100644
index 0000000..595e6be
--- /dev/null
+++ b/programmers_guide/eager.md
@@ -0,0 +1,848 @@
+# Eager Execution
+
+TensorFlow's eager execution is an imperative programming environment that
+evaluates operations immediately, without building graphs: operations return
+concrete values instead of constructing a computational graph to run later. This
+makes it easy to get started with TensorFlow and debug models, and it
+reduces boilerplate as well. To follow along with this guide, run the code
+samples below in an interactive `python` interpreter.
+
+Eager execution is a flexible machine learning platform for research and
+experimentation, providing:
+
+* *An intuitive interface*—Structure your code naturally and use Python data
+ structures. Quickly iterate on small models and small data.
+* *Easier debugging*—Call ops directly to inspect running models and test
+ changes. Use standard Python debugging tools for immediate error reporting.
+* *Natural control flow*—Use Python control flow instead of graph control
+ flow, simplifying the specification of dynamic models.
+
+Eager execution supports most TensorFlow operations and GPU acceleration. For a
+collection of examples running in eager execution, see:
+[tensorflow/contrib/eager/python/examples](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/eager/python/examples).
+
+Note: Some models may experience increased overhead with eager execution
+enabled. Performance improvements are ongoing, but please
+[file a bug](https://github.com/tensorflow/tensorflow/issues) if you find a
+problem and share your benchmarks.
+
+## Setup and basic usage
+
+Upgrade to the latest version of TensorFlow:
+
+```
+$ pip install --upgrade tensorflow
+```
+
+To start eager execution, add `tf.enable_eager_execution()` to the beginning of
+the program or console session. Do not add this operation to other modules that
+the program calls.
+
+```py
+from __future__ import absolute_import, division, print_function
+
+import tensorflow as tf
+
+tf.enable_eager_execution()
+```
+
+Now you can run TensorFlow operations and the results will return immediately:
+
+```py
+tf.executing_eagerly() # => True
+
+x = [[2.]]
+m = tf.matmul(x, x)
+print("hello, {}".format(m)) # => "hello, [[4.]]"
+```
+
+Enabling eager execution changes how TensorFlow operations behave—now they
+immediately evaluate and return their values to Python. `tf.Tensor` objects
+reference concrete values instead of symbolic handles to nodes in a computational
+graph. Since there isn't a computational graph to build and run later in a
+session, it's easy to inspect results using `print()` or a debugger. Evaluating,
+printing, and checking tensor values does not break the flow for computing
+gradients.
+
+Eager execution works nicely with [NumPy](http://www.numpy.org/). NumPy
+operations accept `tf.Tensor` arguments. TensorFlow
+[math operations](https://www.tensorflow.org/api_guides/python/math_ops) convert
+Python objects and NumPy arrays to `tf.Tensor` objects. The
+`tf.Tensor.numpy` method returns the object's value as a NumPy `ndarray`.
+
+```py
+a = tf.constant([[1, 2],
+ [3, 4]])
+print(a)
+# => tf.Tensor([[1 2]
+# [3 4]], shape=(2, 2), dtype=int32)
+
+# Broadcasting support
+b = tf.add(a, 1)
+print(b)
+# => tf.Tensor([[2 3]
+# [4 5]], shape=(2, 2), dtype=int32)
+
+# Operator overloading is supported
+print(a * b)
+# => tf.Tensor([[ 2 6]
+# [12 20]], shape=(2, 2), dtype=int32)
+
+# Use NumPy values
+import numpy as np
+
+c = np.multiply(a, b)
+print(c)
+# => [[ 2 6]
+# [12 20]]
+
+# Obtain numpy value from a tensor:
+print(a.numpy())
+# => [[1 2]
+# [3 4]]
+```
+
+The `tf.contrib.eager` module contains symbols available to both eager and graph execution
+environments and is useful for writing code to [work with graphs](#work_with_graphs):
+
+```py
+tfe = tf.contrib.eager
+```
+
+## Dynamic control flow
+
+A major benefit of eager execution is that all the functionality of the host
+language is available while your model is executing. So, for example,
+it is easy to write [fizzbuzz](https://en.wikipedia.org/wiki/Fizz_buzz):
+
+```py
+def fizzbuzz(max_num):
+ counter = tf.constant(0)
+ for num in range(max_num):
+ num = tf.constant(num)
+ if num % 3 == 0 and num % 5 == 0:
+ print('FizzBuzz')
+ elif num % 3 == 0:
+ print('Fizz')
+ elif num % 5 == 0:
+ print('Buzz')
+ else:
+ print(num)
+ counter += 1
+ return counter
+```
+
+This has conditionals that depend on tensor values and it prints these values
+at runtime.
+
+## Build a model
+
+Many machine learning models are represented by composing layers. When
+using TensorFlow with eager execution you can either write your own layers or
+use a layer provided in the `tf.keras.layers` package.
+
+While you can use any Python object to represent a layer,
+TensorFlow has `tf.keras.layers.Layer` as a convenient base class. Inherit from
+it to implement your own layer:
+
+```py
+class MySimpleLayer(tf.keras.layers.Layer):
+ def __init__(self, output_units):
+ self.output_units = output_units
+
+ def build(self, input):
+ # The build method gets called the first time your layer is used.
+ # Creating variables on build() allows you to make their shape depend
+ # on the input shape and hence remove the need for the user to specify
+ # full shapes. It is possible to create variables during __init__() if
+ # you already know their full shapes.
+ self.kernel = self.add_variable(
+ "kernel", [input.shape[-1], self.output_units])
+
+ def call(self, input):
+ # Override call() instead of __call__ so we can perform some bookkeeping.
+ return tf.matmul(input, self.kernel)
+```
+
+Use `tf.keras.layers.Dense` layer instead of `MySimpleLayer` above as it has
+a superset of its functionality (it can also add a bias).
+
+When composing layers into models you can use `tf.keras.Sequential` to represent
+models which are a linear stack of layers. It is easy to use for basic models:
+
+```py
+model = tf.keras.Sequential([
+ tf.keras.layers.Dense(10, input_shape=(784,)), # must declare input shape
+ tf.keras.layers.Dense(10)
+])
+```
+
+Alternatively, organize models in classes by inheriting from `tf.keras.Model`.
+This is a container for layers that is a layer itself, allowing `tf.keras.Model`
+objects to contain other `tf.keras.Model` objects.
+
+```py
+class MNISTModel(tf.keras.Model):
+ def __init__(self):
+ super(MNISTModel, self).__init__()
+ self.dense1 = tf.keras.layers.Dense(units=10)
+ self.dense2 = tf.keras.layers.Dense(units=10)
+
+ def call(self, input):
+ """Run the model."""
+ result = self.dense1(input)
+ result = self.dense2(result)
+ result = self.dense2(result) # reuse variables from dense2 layer
+ return result
+
+model = MNISTModel()
+```
+
+It's not required to set an input shape for the `tf.keras.Model` class since
+the parameters are set the first time input is passed to the layer.
+
+`tf.keras.layers` classes create and contain their own model variables that
+are tied to the lifetime of their layer objects. To share layer variables, share
+their objects.
+
+
+## Eager training
+
+### Computing gradients
+
+[Automatic differentiation](https://en.wikipedia.org/wiki/Automatic_differentiation)
+is useful for implementing machine learning algorithms such as
+[backpropagation](https://en.wikipedia.org/wiki/Backpropagation) for training
+neural networks. During eager execution, use `tf.GradientTape` to trace
+operations for computing gradients later.
+
+`tf.GradientTape` is an opt-in feature to provide maximal performance when
+not tracing. Since different operations can occur during each call, all
+forward-pass operations get recorded to a "tape". To compute the gradient, play
+the tape backwards and then discard. A particular `tf.GradientTape` can only
+compute one gradient; subsequent calls throw a runtime error.
+
+```py
+w = tfe.Variable([[1.0]])
+with tf.GradientTape() as tape:
+ loss = w * w
+
+grad = tape.gradient(loss, [w])
+print(grad) # => [tf.Tensor([[ 2.]], shape=(1, 1), dtype=float32)]
+```
+
+Here's an example of `tf.GradientTape` that records forward-pass operations
+to train a simple model:
+
+```py
+# A toy dataset of points around 3 * x + 2
+NUM_EXAMPLES = 1000
+training_inputs = tf.random_normal([NUM_EXAMPLES])
+noise = tf.random_normal([NUM_EXAMPLES])
+training_outputs = training_inputs * 3 + 2 + noise
+
+def prediction(input, weight, bias):
+ return input * weight + bias
+
+# A loss function using mean-squared error
+def loss(weights, biases):
+ error = prediction(training_inputs, weights, biases) - training_outputs
+ return tf.reduce_mean(tf.square(error))
+
+# Return the derivative of loss with respect to weight and bias
+def grad(weights, biases):
+ with tf.GradientTape() as tape:
+ loss_value = loss(weights, biases)
+ return tape.gradient(loss_value, [weights, biases])
+
+train_steps = 200
+learning_rate = 0.01
+# Start with arbitrary values for W and B on the same batch of data
+W = tfe.Variable(5.)
+B = tfe.Variable(10.)
+
+print("Initial loss: {:.3f}".format(loss(W, B)))
+
+for i in range(train_steps):
+ dW, dB = grad(W, B)
+ W.assign_sub(dW * learning_rate)
+ B.assign_sub(dB * learning_rate)
+ if i % 20 == 0:
+ print("Loss at step {:03d}: {:.3f}".format(i, loss(W, B)))
+
+print("Final loss: {:.3f}".format(loss(W, B)))
+print("W = {}, B = {}".format(W.numpy(), B.numpy()))
+```
+
+Output (exact numbers may vary):
+
+```
+Initial loss: 71.204
+Loss at step 000: 68.333
+Loss at step 020: 30.222
+Loss at step 040: 13.691
+Loss at step 060: 6.508
+Loss at step 080: 3.382
+Loss at step 100: 2.018
+Loss at step 120: 1.422
+Loss at step 140: 1.161
+Loss at step 160: 1.046
+Loss at step 180: 0.996
+Final loss: 0.974
+W = 3.01582956314, B = 2.1191945076
+```
+
+Replay the `tf.GradientTape` to compute the gradients and apply them in a
+training loop. This is demonstrated in an excerpt from the
+[mnist_eager.py](https://github.com/tensorflow/models/blob/master/official/mnist/mnist_eager.py)
+example:
+
+```py
+dataset = tf.data.Dataset.from_tensor_slices((data.train.images,
+ data.train.labels))
+...
+for (batch, (images, labels)) in enumerate(dataset):
+ ...
+ with tf.GradientTape() as tape:
+ logits = model(images, training=True)
+ loss_value = loss(logits, labels)
+ ...
+ grads = tape.gradient(loss_value, model.variables)
+ optimizer.apply_gradients(zip(grads, model.variables),
+ global_step=tf.train.get_or_create_global_step())
+```
+
+
+The following example creates a multi-layer model that classifies the standard
+[MNIST handwritten digits](https://www.tensorflow.org/tutorials/layers). It
+demonstrates the optimizer and layer APIs to build trainable graphs in an eager
+execution environment.
+
+### Train a model
+
+Even without training, call the model and inspect the output in eager execution:
+
+```py
+# Create a tensor representing a blank image
+batch = tf.zeros([1, 1, 784])
+print(batch.shape) # => (1, 1, 784)
+
+result = model(batch)
+# => tf.Tensor([[[ 0. 0., ..., 0.]]], shape=(1, 1, 10), dtype=float32)
+```
+
+This example uses the
+[dataset.py module](https://github.com/tensorflow/models/blob/master/official/mnist/dataset.py)
+from the
+[TensorFlow MNIST example](https://github.com/tensorflow/models/tree/master/official/mnist);
+download this file to your local directory. Run the following to download the
+MNIST data files to your working directory and prepare a `tf.data.Dataset`
+for training:
+
+```py
+import dataset # download dataset.py file
+dataset_train = dataset.train('./datasets').shuffle(60000).repeat(4).batch(32)
+```
+
+To train a model, define a loss function to optimize and then calculate
+gradients. Use an optimizer to update the variables:
+
+```py
+def loss(model, x, y):
+ prediction = model(x)
+ return tf.losses.sparse_softmax_cross_entropy(labels=y, logits=prediction)
+
+def grad(model, inputs, targets):
+ with tf.GradientTape() as tape:
+ loss_value = loss(model, inputs, targets)
+ return tape.gradient(loss_value, model.variables)
+
+optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001)
+
+x, y = iter(dataset_train).next()
+print("Initial loss: {:.3f}".format(loss(model, x, y)))
+
+# Training loop
+for (i, (x, y)) in enumerate(dataset_train):
+ # Calculate derivatives of the input function with respect to its parameters.
+ grads = grad(model, x, y)
+ # Apply the gradient to the model
+ optimizer.apply_gradients(zip(grads, model.variables),
+ global_step=tf.train.get_or_create_global_step())
+ if i % 200 == 0:
+ print("Loss at step {:04d}: {:.3f}".format(i, loss(model, x, y)))
+
+print("Final loss: {:.3f}".format(loss(model, x, y)))
+```
+
+Output (exact numbers may vary):
+
+```
+Initial loss: 2.674
+Loss at step 0000: 2.593
+Loss at step 0200: 2.143
+Loss at step 0400: 2.009
+Loss at step 0600: 2.103
+Loss at step 0800: 1.621
+Loss at step 1000: 1.695
+...
+Loss at step 6600: 0.602
+Loss at step 6800: 0.557
+Loss at step 7000: 0.499
+Loss at step 7200: 0.744
+Loss at step 7400: 0.681
+Final loss: 0.670
+```
+
+And for faster training, move the computation to a GPU:
+
+```py
+with tf.device("/gpu:0"):
+ for (i, (x, y)) in enumerate(dataset_train):
+ # minimize() is equivalent to the grad() and apply_gradients() calls.
+ optimizer.minimize(lambda: loss(model, x, y),
+ global_step=tf.train.get_or_create_global_step())
+```
+
+### Variables and optimizers
+
+`tfe.Variable` objects store mutable `tf.Tensor` values accessed during
+training to make automatic differentiation easier. The parameters of a model can
+be encapsulated in classes as variables.
+
+Better encapsulate model parameters by using `tfe.Variable` with
+`tf.GradientTape`. For example, the automatic differentiation example above
+can be rewritten:
+
+```py
+class Model(tf.keras.Model):
+ def __init__(self):
+ super(Model, self).__init__()
+ self.W = tfe.Variable(5., name='weight')
+ self.B = tfe.Variable(10., name='bias')
+ def predict(self, inputs):
+ return inputs * self.W + self.B
+
+# A toy dataset of points around 3 * x + 2
+NUM_EXAMPLES = 2000
+training_inputs = tf.random_normal([NUM_EXAMPLES])
+noise = tf.random_normal([NUM_EXAMPLES])
+training_outputs = training_inputs * 3 + 2 + noise
+
+# The loss function to be optimized
+def loss(model, inputs, targets):
+ error = model.predict(inputs) - targets
+ return tf.reduce_mean(tf.square(error))
+
+def grad(model, inputs, targets):
+ with tf.GradientTape() as tape:
+ loss_value = loss(model, inputs, targets)
+ return tape.gradient(loss_value, [model.W, model.B])
+
+# Define:
+# 1. A model.
+# 2. Derivatives of a loss function with respect to model parameters.
+# 3. A strategy for updating the variables based on the derivatives.
+model = Model()
+optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)
+
+print("Initial loss: {:.3f}".format(loss(model, training_inputs, training_outputs)))
+
+# Training loop
+for i in range(300):
+ grads = grad(model, training_inputs, training_outputs)
+ optimizer.apply_gradients(zip(grads, [model.W, model.B]),
+ global_step=tf.train.get_or_create_global_step())
+ if i % 20 == 0:
+ print("Loss at step {:03d}: {:.3f}".format(i, loss(model, training_inputs, training_outputs)))
+
+print("Final loss: {:.3f}".format(loss(model, training_inputs, training_outputs)))
+print("W = {}, B = {}".format(model.W.numpy(), model.B.numpy()))
+```
+
+Output (exact numbers may vary):
+
+```
+Initial loss: 69.066
+Loss at step 000: 66.368
+Loss at step 020: 30.107
+Loss at step 040: 13.959
+Loss at step 060: 6.769
+Loss at step 080: 3.567
+Loss at step 100: 2.141
+Loss at step 120: 1.506
+Loss at step 140: 1.223
+Loss at step 160: 1.097
+Loss at step 180: 1.041
+Loss at step 200: 1.016
+Loss at step 220: 1.005
+Loss at step 240: 1.000
+Loss at step 260: 0.998
+Loss at step 280: 0.997
+Final loss: 0.996
+W = 2.99431324005, B = 2.02129220963
+```
+
+## Use objects for state during eager execution
+
+With graph execution, program state (such as the variables) is stored in global
+collections and their lifetime is managed by the `tf.Session` object. In
+contrast, during eager execution the lifetime of state objects is determined by
+the lifetime of their corresponding Python object.
+
+### Variables are objects
+
+During eager execution, variables persist until the last reference to the object
+is removed, and is then deleted.
+
+```py
+with tf.device("gpu:0"):
+ v = tfe.Variable(tf.random_normal([1000, 1000]))
+ v = None # v no longer takes up GPU memory
+```
+
+### Object-based saving
+
+`tfe.Checkpoint` can save and restore `tfe.Variable`s to and from
+checkpoints:
+
+```py
+x = tfe.Variable(10.)
+
+checkpoint = tfe.Checkpoint(x=x) # save as "x"
+
+x.assign(2.) # Assign a new value to the variables and save.
+save_path = checkpoint.save('./ckpt/')
+
+x.assign(11.) # Change the variable after saving.
+
+# Restore values from the checkpoint
+checkpoint.restore(save_path)
+
+print(x) # => 2.0
+```
+
+To save and load models, `tfe.Checkpoint` stores the internal state of objects,
+without requiring hidden variables. To record the state of a `model`,
+an `optimizer`, and a global step, pass them to a `tfe.Checkpoint`:
+
+```py
+model = MyModel()
+optimizer = tf.train.AdamOptimizer(learning_rate=0.001)
+checkpoint_dir = ‘/path/to/model_dir’
+checkpoint_prefix = os.path.join(checkpoint_dir, "ckpt")
+root = tfe.Checkpoint(optimizer=optimizer,
+ model=model,
+ optimizer_step=tf.train.get_or_create_global_step())
+
+root.save(file_prefix=checkpoint_prefix)
+# or
+root.restore(tf.train.latest_checkpoint(checkpoint_dir))
+```
+
+### Object-oriented metrics
+
+`tfe.metrics` are stored as objects. Update a metric by passing the new data to
+the callable, and retrieve the result using the `tfe.metrics.result` method,
+for example:
+
+```py
+m = tfe.metrics.Mean("loss")
+m(0)
+m(5)
+m.result() # => 2.5
+m([8, 9])
+m.result() # => 5.5
+```
+
+#### Summaries and TensorBoard
+
+@{$summaries_and_tensorboard$TensorBoard} is a visualization tool for
+understanding, debugging and optimizing the model training process. It uses
+summary events that are written while executing the program.
+
+`tf.contrib.summary` is compatible with both eager and graph execution
+environments. Summary operations, such as `tf.contrib.summary.scalar`, are
+inserted during model construction. For example, to record summaries once every
+100 global steps:
+
+```py
+writer = tf.contrib.summary.create_file_writer(logdir)
+global_step=tf.train.get_or_create_global_step() # return global step var
+
+writer.set_as_default()
+
+for _ in range(iterations):
+ global_step.assign_add(1)
+ # Must include a record_summaries method
+ with tf.contrib.summary.record_summaries_every_n_global_steps(100):
+ # your model code goes here
+ tf.contrib.summary.scalar('loss', loss)
+ ...
+```
+
+## Advanced automatic differentiation topics
+
+### Dynamic models
+
+`tf.GradientTape` can also be used in dynamic models. This example for a
+[backtracking line search](https://wikipedia.org/wiki/Backtracking_line_search)
+algorithm looks like normal NumPy code, except there are gradients and is
+differentiable, despite the complex control flow:
+
+```py
+def line_search_step(fn, init_x, rate=1.0):
+ with tf.GradientTape() as tape:
+ # Variables are automatically recorded, but manually watch a tensor
+ tape.watch(init_x)
+ value = fn(init_x)
+ grad, = tape.gradient(value, [init_x])
+ grad_norm = tf.reduce_sum(grad * grad)
+ init_value = value
+ while value > init_value - rate * grad_norm:
+ x = init_x - rate * grad
+ value = fn(x)
+ rate /= 2.0
+ return x, value
+```
+
+### Additional functions to compute gradients
+
+`tf.GradientTape` is a powerful interface for computing gradients, but there
+is another [Autograd](https://github.com/HIPS/autograd)-style API available for
+automatic differentiation. These functions are useful if writing math code with
+only tensors and gradient functions, and without `tfe.Variables`:
+
+* `tfe.gradients_function` —Returns a function that computes the derivatives
+ of its input function parameter with respect to its arguments. The input
+ function parameter must return a scalar value. When the returned function is
+ invoked, it returns a list of `tf.Tensor` objects: one element for each
+ argument of the input function. Since anything of interest must be passed as a
+ function parameter, this becomes unwieldy if there's a dependency on many
+ trainable parameters.
+* `tfe.value_and_gradients_function` —Similar to
+ `tfe.gradients_function`, but when the returned function is invoked, it
+ returns the value from the input function in addition to the list of
+ derivatives of the input function with respect to its arguments.
+
+In the following example, `tfe.gradients_function` takes the `square`
+function as an argument and returns a function that computes the partial
+derivatives of `square` with respect to its inputs. To calculate the derivative
+of `square` at `3`, `grad(3.0)` returns `6`.
+
+```py
+def square(x):
+ return tf.multiply(x, x)
+
+grad = tfe.gradients_function(square)
+
+square(3.) # => 9.0
+grad(3.) # => [6.0]
+
+# The second-order derivative of square:
+gradgrad = tfe.gradients_function(lambda x: grad(x)[0])
+gradgrad(3.) # => [2.0]
+
+# The third-order derivative is None:
+gradgradgrad = tfe.gradients_function(lambda x: gradgrad(x)[0])
+gradgradgrad(3.) # => [None]
+
+
+# With flow control:
+def abs(x):
+ return x if x > 0. else -x
+
+grad = tfe.gradients_function(abs)
+
+grad(3.) # => [1.0]
+grad(-3.) # => [-1.0]
+```
+
+### Custom gradients
+
+Custom gradients are an easy way to override gradients in eager and graph
+execution. Within the forward function, define the gradient with respect to the
+inputs, outputs, or intermediate results. For example, here's an easy way to clip
+the norm of the gradients in the backward pass:
+
+```py
+@tf.custom_gradient
+def clip_gradient_by_norm(x, norm):
+ y = tf.identity(x)
+ def grad_fn(dresult):
+ return [tf.clip_by_norm(dresult, norm), None]
+ return y, grad_fn
+```
+
+Custom gradients are commonly used to provide a numerically stable gradient for a
+sequence of operations:
+
+```py
+def log1pexp(x):
+ return tf.log(1 + tf.exp(x))
+grad_log1pexp = tfe.gradients_function(log1pexp)
+
+# The gradient computation works fine at x = 0.
+grad_log1pexp(0.) # => [0.5]
+
+# However, x = 100 fails because of numerical instability.
+grad_log1pexp(100.) # => [nan]
+```
+
+Here, the `log1pexp` function can be analytically simplified with a custom
+gradient. The implementation below reuses the value for `tf.exp(x)` that is
+computed during the forward pass—making it more efficient by eliminating
+redundant calculations:
+
+```py
+@tf.custom_gradient
+def log1pexp(x):
+ e = tf.exp(x)
+ def grad(dy):
+ return dy * (1 - 1 / (1 + e))
+ return tf.log(1 + e), grad
+
+grad_log1pexp = tfe.gradients_function(log1pexp)
+
+# As before, the gradient computation works fine at x = 0.
+grad_log1pexp(0.) # => [0.5]
+
+# And the gradient computation also works at x = 100.
+grad_log1pexp(100.) # => [1.0]
+```
+
+## Performance
+
+Computation is automatically offloaded to GPUs during eager execution. If you
+want control over where a computation runs you can enclose it in a
+`tf.device('/gpu:0')` block (or the CPU equivalent):
+
+```py
+import time
+
+def measure(x, steps):
+ # TensorFlow initializes a GPU the first time it's used, exclude from timing.
+ tf.matmul(x, x)
+ start = time.time()
+ for i in range(steps):
+ x = tf.matmul(x, x)
+ _ = x.numpy() # Make sure to execute op and not just enqueue it
+ end = time.time()
+ return end - start
+
+shape = (1000, 1000)
+steps = 200
+print("Time to multiply a {} matrix by itself {} times:".format(shape, steps))
+
+# Run on CPU:
+with tf.device("/cpu:0"):
+ print("CPU: {} secs".format(measure(tf.random_normal(shape), steps)))
+
+# Run on GPU, if available:
+if tfe.num_gpus() > 0:
+ with tf.device("/gpu:0"):
+ print("GPU: {} secs".format(measure(tf.random_normal(shape), steps)))
+else:
+ print("GPU: not found")
+```
+
+Output (exact numbers depend on hardware):
+
+```
+Time to multiply a (1000, 1000) matrix by itself 200 times:
+CPU: 4.614904403686523 secs
+GPU: 0.5581181049346924 secs
+```
+
+A `tf.Tensor` object can be copied to a different device to execute its
+operations:
+
+```py
+x = tf.random_normal([10, 10])
+
+x_gpu0 = x.gpu()
+x_cpu = x.cpu()
+
+_ = tf.matmul(x_cpu, x_cpu) # Runs on CPU
+_ = tf.matmul(x_gpu0, x_gpu0) # Runs on GPU:0
+
+if tfe.num_gpus() > 1:
+ x_gpu1 = x.gpu(1)
+ _ = tf.matmul(x_gpu1, x_gpu1) # Runs on GPU:1
+```
+
+### Benchmarks
+
+For compute-heavy models, such as
+[ResNet50](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/eager/python/examples/resnet50)
+training on a GPU, eager execution performance is comparable to graph execution.
+But this gap grows larger for models with less computation and there is work to
+be done for optimizing hot code paths for models with lots of small operations.
+
+
+## Work with graphs
+
+While eager execution makes development and debugging more interactive,
+TensorFlow graph execution has advantages for distributed training, performance
+optimizations, and production deployment. However, writing graph code can feel
+different than writing regular Python code and more difficult to debug.
+
+For building and training graph-constructed models, the Python program first
+builds a graph representing the computation, then invokes `Session.run` to send
+the graph for execution on the C++-based runtime. This provides:
+
+* Automatic differentiation using static autodiff.
+* Simple deployment to a platform independent server.
+* Graph-based optimizations (common subexpression elimination, constant-folding, etc.).
+* Compilation and kernel fusion.
+* Automatic distribution and replication (placing nodes on the distributed system).
+
+Deploying code written for eager execution is more difficult: either generate a
+graph from the model, or run the Python runtime and code directly on the server.
+
+### Write compatible code
+
+The same code written for eager execution will also build a graph during graph
+execution. Do this by simply running the same code in a new Python session where
+eager execution is not enabled.
+
+Most TensorFlow operations work during eager execution, but there are some things
+to keep in mind:
+
+* Use `tf.data` for input processing instead of queues. It's faster and easier.
+* Use object-oriented layer APIs—like `tf.keras.layers` and
+ `tf.keras.Model`—since they have explicit storage for variables.
+* Most model code works the same during eager and graph execution, but there are
+ exceptions. (For example, dynamic models using Python control flow to change the
+ computation based on inputs.)
+* Once eager execution is enabled with `tf.enable_eager_execution`, it
+ cannot be turned off. Start a new Python session to return to graph execution.
+
+It's best to write code for both eager execution *and* graph execution. This
+gives you eager's interactive experimentation and debuggability with the
+distributed performance benefits of graph execution.
+
+Write, debug, and iterate in eager execution, then import the model graph for
+production deployment. Use `tfe.Checkpoint` to save and restore model
+variables, this allows movement between eager and graph execution environments.
+See the examples in:
+[tensorflow/contrib/eager/python/examples](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/eager/python/examples).
+
+### Use eager execution in a graph environment
+
+Selectively enable eager execution in a TensorFlow graph environment using
+`tfe.py_func`. This is used when `tf.enable_eager_execution()` has *not*
+been called.
+
+```py
+def my_py_func(x):
+ x = tf.matmul(x, x) # You can use tf ops
+ print(x) # but it's eager!
+ return x
+
+with tf.Session() as sess:
+ x = tf.placeholder(dtype=tf.float32)
+ # Call eager function in graph!
+ pf = tfe.py_func(my_py_func, [x], tf.float32)
+ sess.run(pf, feed_dict={x: [[2.0]]}) # [[4.0]]
+```
diff --git a/programmers_guide/embedding.md b/programmers_guide/embedding.md
index e8027fc..d5703e0 100644
--- a/programmers_guide/embedding.md
+++ b/programmers_guide/embedding.md
@@ -7,6 +7,9 @@ with the TensorBoard Embedding Projector
newcomers to machine learning or TensorFlow, and the Embedding Projector how-to
is for users at all levels.
+An alternative tutorial on these concepts is available in the
+[Embeddings section of Machine Learning Crash Course](https://developers.google.com/machine-learning/crash-course/embeddings/video-lecture).
+
[TOC]
An **embedding** is a mapping from discrete objects, such as words, to vectors
diff --git a/programmers_guide/faq.md b/programmers_guide/faq.md
index 1548d43..392ac6f 100644
--- a/programmers_guide/faq.md
+++ b/programmers_guide/faq.md
@@ -159,7 +159,7 @@ available. These operations allow you to build sophisticated
@{$reading_data$input pipelines}, at the cost of making the
TensorFlow computation somewhat more complicated. See the how-to documentation
for
-@{$reading_data#creating-threads-to-prefetch-using-queuerunner-objects$using `QueueRunner` objects to drive queues and readers}
+@{$reading_data#creating_threads_to_prefetch_using_queuerunner_objects$using `QueueRunner` objects to drive queues and readers}
for more information on how to use them.
## Variables
@@ -272,7 +272,7 @@ Prefer predefined TensorFlow operations such as @{tf.decode_raw},
If your data is not easily parsable with the built-in TensorFlow operations,
consider converting it, offline, to a format that is easily parsable, such
-as ${tf.python_io.TFRecordWriter$`TFRecord`} format.
+as @{tf.python_io.TFRecordWriter$`TFRecord`} format.
The more efficient method to customize the parsing behavior is to
@{$adding_an_op$add a new op written in C++} that parses your
diff --git a/programmers_guide/index.md b/programmers_guide/index.md
index e8c2fa6..017db0e 100644
--- a/programmers_guide/index.md
+++ b/programmers_guide/index.md
@@ -5,6 +5,7 @@ works. The units are as follows:
## High Level APIs
+ * @{$programmers_guide/eager}, which is the easiest way to use tensorflow.
* @{$programmers_guide/estimators}, which introduces a high-level
TensorFlow API that greatly simplifies ML programming.
* @{$programmers_guide/datasets}, which explains how to
diff --git a/programmers_guide/leftnav_files b/programmers_guide/leftnav_files
index 3fe4cb2..7ac63bf 100644
--- a/programmers_guide/leftnav_files
+++ b/programmers_guide/leftnav_files
@@ -1,8 +1,9 @@
index.md
### High Level APIs
-estimators.md
+eager.md
datasets.md
+estimators.md
### Low Level APIs
low_level_intro.md
diff --git a/programmers_guide/saved_model.md b/programmers_guide/saved_model.md
index 5dfe6ef..55ee42d 100644
--- a/programmers_guide/saved_model.md
+++ b/programmers_guide/saved_model.md
@@ -3,7 +3,7 @@
The @{tf.train.Saver} class provides methods to save and restore models. The
@{tf.saved_model.simple_save} function is an easy way to build a
@{tf.saved_model$saved model} suitable for serving.
-[Estimators](/programmers_guide/estimators) automatically save and restore
+[Estimators](@{$programmers_guide/estimators}) automatically save and restore
variables in the `model_dir`.
## Save and restore variables
@@ -256,18 +256,53 @@ with tf.Session(graph=tf.Graph()) as sess:
builder.add_meta_graph_and_variables(sess,
[tag_constants.TRAINING],
signature_def_map=foo_signatures,
- assets_collection=foo_assets)
+ assets_collection=foo_assets,
+ strip_default_attrs=True)
...
# Add a second MetaGraphDef for inference.
with tf.Session(graph=tf.Graph()) as sess:
...
- builder.add_meta_graph([tag_constants.SERVING])
+ builder.add_meta_graph([tag_constants.SERVING], strip_default_attrs=True)
...
builder.save()
```
+
+#### Forward compatibility via `strip_default_attrs=True`
-### Load a SavedModel in Python
+Following the guidance below gives you forward compatibility only if the set of
+Ops has not changed.
+
+The @{tf.saved_model.builder.SavedModelBuilder$`SavedModelBuilder`} class allows
+users to control whether default-valued attributes must be stripped from the
+@{$extend/tool_developers#nodes$`NodeDefs`}
+while adding a meta graph to the SavedModel bundle. Both
+@{tf.saved_model.builder.SavedModelBuilder.add_meta_graph_and_variables$`SavedModelBuilder.add_meta_graph_and_variables`}
+and @{tf.saved_model.builder.SavedModelBuilder.add_meta_graph$`SavedModelBuilder.add_meta_graph`}
+methods accept a Boolean flag `strip_default_attrs` that controls this behavior.
+
+If `strip_default_attrs` is `False`, the exported @{tf.MetaGraphDef} will have
+the default valued attributes in all its @{tf.NodeDef} instances.
+This can break forward compatibility with a sequence of events such as the
+following:
+
+* An existing Op (`Foo`) is updated to include a new attribute (`T`) with a
+ default (`bool`) at version 101.
+* A model producer such as a "trainer binary" picks up this change (version 101)
+ to the `OpDef` and re-exports an existing model that uses Op `Foo`.
+* A model consumer (such as [Tensorflow Serving](/serving)) running an older
+ binary (version 100) doesn't have attribute `T` for Op `Foo`, but tries to
+ import this model. The model consumer doesn't recognize attribute `T` in a
+ `NodeDef` that uses Op `Foo` and therefore fails to load the model.
+* By setting `strip_default_attrs` to True, the model producers can strip away
+ any default valued attributes in the `NodeDefs`. This helps ensure that newly
+ added attributes with defaults don't cause older model consumers to fail
+ loading models regenerated with newer training binaries.
+
+See [compatibility guidance](https://www.tensorflow.org/programmers_guide/version_compat)
+for more information.
+
+### Loading a SavedModel in Python
The Python version of the SavedModel
@{tf.saved_model.loader$loader}
@@ -365,7 +400,7 @@ defined in:
After training an `Estimator` model, you may want to create a service
from that model that takes requests and returns a result. You can run such a
-service locally on your machine or deploy it scalably in the cloud.
+service locally on your machine or deploy it in the cloud.
To prepare a trained Estimator for serving, you must export it in the standard
SavedModel format. This section explains how to:
@@ -458,7 +493,8 @@ To export your trained Estimator, call
the `serving_input_receiver_fn`.
```py
-estimator.export_savedmodel(export_dir_base, serving_input_receiver_fn)
+estimator.export_savedmodel(export_dir_base, serving_input_receiver_fn,
+ strip_default_attrs=True)
```
This method builds a new graph by first calling the
diff --git a/programmers_guide/summaries_and_tensorboard.md b/programmers_guide/summaries_and_tensorboard.md
index 79280d2..fadfa03 100644
--- a/programmers_guide/summaries_and_tensorboard.md
+++ b/programmers_guide/summaries_and_tensorboard.md
@@ -83,7 +83,7 @@ data than you need, though. Instead, consider running the merged summary op
every `n` steps.
The code example below is a modification of the
-@{$layers$simple MNIST tutorial},
+[simple MNIST tutorial](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/mnist/mnist.py),
in which we have added some summary ops, and run them every ten steps. If you
run this and then launch `tensorboard --logdir=/tmp/tensorflow/mnist`, you'll be able
to visualize statistics, such as how the weights or accuracy varied during
diff --git a/programmers_guide/using_tpu.md b/programmers_guide/using_tpu.md
index d74d7f3..cb0d86f 100644
--- a/programmers_guide/using_tpu.md
+++ b/programmers_guide/using_tpu.md
@@ -11,7 +11,7 @@ This doc is aimed at users who:
using an existing model.
* Have, perhaps, skimmed the code of an example TPU model
[[1]](https://github.com/tensorflow/models/blob/master/official/mnist/mnist_tpu.py)
- [[2]](https://github.com/tensorflow/tpu-demos/tree/master/cloud_tpu/models).
+ [[2]](https://github.com/tensorflow/tpu/tree/master/models).
* Are interested in porting an existing `Estimator` model to
run on Cloud TPUs
@@ -129,10 +129,9 @@ my_tpu_estimator = tf.contrib.tpu.TPUEstimator(
Typically the `FLAGS` would be set by command line arguments. To switch from
training locally to training on a cloud TPU you would need to:
- 1) Set `FLAGS.use_tpu` to `True`
- 1) Set `FLAGS.tpu_name` so the
- `tf.contrib.cluster_resolver.TPUClusterResolver` can find it
- 1) Set `FLAGS.model_dir` to a Google Cloud Storage bucket url (`gs://`).
+* Set `FLAGS.use_tpu` to `True`
+* Set `FLAGS.tpu_name` so the `tf.contrib.cluster_resolver.TPUClusterResolver` can find it
+* Set `FLAGS.model_dir` to a Google Cloud Storage bucket url (`gs://`).
## Optimizer
@@ -289,7 +288,7 @@ If shape inference has failed, but the shape is known it is possible to
impose the correct shape using `tf.set_shape()`.
In the example below the shape
-inference algorithm fails, but it is corrected using `set_shape`:
+inference algorithm fails, but it is correctly using `set_shape`:
```
>>> x = tf.zeros(tf.constant([1,2,3])+1)
@@ -372,10 +371,10 @@ in bytes. A minimum of a few MB (`buffer_size=8*1024*1024`) is recommended so
that data is available when needed.
The TPU-demos repo includes
-[a script](https://github.com/tensorflow/tpu-demos/blob/master/cloud_tpu/datasets/imagenet_to_gcs.py)
+[a script](https://github.com/tensorflow/tpu/blob/master/tools/datasets/imagenet_to_gcs.py)
for downloading the imagenet dataset and converting it to an appropriate format.
This together with the imagenet
-[models](https://github.com/tensorflow/tpu-demos/tree/master/cloud_tpu/models)
+[models](https://github.com/tensorflow/tpu/tree/master/models)
included in the repo demonstrate all of these best-practices.
@@ -388,7 +387,7 @@ For details on how to actually set up and run a Cloud TPU see:
This document is by no means exhaustive. The best source of more detail on how
to make a Cloud TPU compatible model are the example models published in:
- * The [TPU Demos Repository.](https://github.com/tensorflow/tpu-demos/)
+ * The [TPU Demos Repository.](https://github.com/tensorflow/tpu)
For more information about tuning TensorFlow code for performance see:
diff --git a/programmers_guide/version_compat.md b/programmers_guide/version_compat.md
index e6613cc..72e427c 100644
--- a/programmers_guide/version_compat.md
+++ b/programmers_guide/version_compat.md
@@ -183,7 +183,7 @@ Our versioning scheme has three requirements:
* **Forward compatibility** to support scenarios where the producer of a
graph or checkpoint is upgraded to a newer version of TensorFlow before
the consumer.
-* Enable evolving TensorFlow in incompatible ways. For example, removing Ops,
+* Enable evolving TensorFlow in incompatible ways. For example, removing ops,
adding attributes, and removing attributes.
Note that while the `GraphDef` version mechanism is separate from the TensorFlow
@@ -245,32 +245,51 @@ contains a main data version which is treated as either `producer` or
`TF_CHECKPOINT_VERSION_MIN_CONSUMER`, and
`TF_CHECKPOINT_VERSION_MIN_PRODUCER`.
+### Add a new attribute with default to an existing op
+
+Following the guidance below gives you forward compatibility only if the set of
+ops has not changed:
+
+1. If forward compatibility is desired, set `strip_default_attrs` to `True`
+ while exporting the model using either the
+ @{tf.saved_model.builder.SavedModelBuilder.add_meta_graph_and_variables$`add_meta_graph_and_variables`}
+ and @{tf.saved_model.builder.SavedModelBuilder.add_meta_graph$`add_meta_graph`}
+ methods of the `SavedModelBuilder` class, or
+ @{tf.estimator.Estimator.export_savedmodel$`Estimator.export_savedmodel`}
+2. This strips off the default valued attributes at the time of
+ producing/exporting the models. This makes sure that the exported
+ @{tf.MetaGraphDef} does not contain the new op-attribute when the default
+ value is used.
+3. Having this control could allow out-of-date consumers (for example, serving
+ binaries that lag behind training binaries) to continue loading the models
+ and prevent interruptions in model serving.
+
### Evolving GraphDef versions
This section explains how to use this versioning mechanism to make different
types of changes to the `GraphDef` format.
-#### Add an Op
+#### Add an op
-Add the new Op to both consumers and producers at the same time, and do not
+Add the new op to both consumers and producers at the same time, and do not
change any `GraphDef` versions. This type of change is automatically
backward compatible, and does not impact forward compatibility plan since
existing producer scripts will not suddenly use the new functionality.
-#### Add an Op and switch existing Python wrappers to use it
+#### Add an op and switch existing Python wrappers to use it
1. Implement new consumer functionality and increment the `GraphDef` version.
2. If it is possible to make the wrappers use the new functionality only in
cases that did not work before, the wrappers can be updated now.
3. Change Python wrappers to use the new functionality. Do not increment
- `min_consumer`, since models that do not use this Op should not break.
+ `min_consumer`, since models that do not use this op should not break.
-#### Remove or restrict an Op's functionality
+#### Remove or restrict an op's functionality
-1. Fix all producer scripts (not TensorFlow itself) to not use the banned Op or
+1. Fix all producer scripts (not TensorFlow itself) to not use the banned op or
functionality.
2. Increment the `GraphDef` version and implement new consumer functionality
- that bans the removed Op or functionality for GraphDefs at the new version
+ that bans the removed op or functionality for GraphDefs at the new version
and above. If possible, make TensorFlow stop producing `GraphDefs` with the
banned functionality. To do so, add the
[`REGISTER_OP(...).Deprecated(deprecated_at_version,
@@ -279,15 +298,15 @@ existing producer scripts will not suddenly use the new functionality.
4. Increase `min_producer` to the GraphDef version from (2) and remove the
functionality entirely.
-#### Change an Op's functionality
+#### Change an op's functionality
-1. Add a new similar Op named `SomethingV2` or similar and go through the
+1. Add a new similar op named `SomethingV2` or similar and go through the
process of adding it and switching existing Python wrappers to use it, which
may take three weeks if forward compatibility is desired.
-2. Remove the old Op (Can only take place with a major version change due to
+2. Remove the old op (Can only take place with a major version change due to
backward compatibility).
-3. Increase `min_consumer` to rule out consumers with the old Op, add back the
- old Op as an alias for `SomethingV2`, and go through the process to switch
+3. Increase `min_consumer` to rule out consumers with the old op, add back the
+ old op as an alias for `SomethingV2`, and go through the process to switch
existing Python wrappers to use it.
4. Go through the process to remove `SomethingV2`.
@@ -295,6 +314,6 @@ existing producer scripts will not suddenly use the new functionality.
1. Bump the `GraphDef` version and add the bad version to `bad_consumers` for
all new GraphDefs. If possible, add to `bad_consumers` only for GraphDefs
- which contain a certain Op or similar.
+ which contain a certain op or similar.
2. If existing consumers have the bad version, push them out as soon as
possible.
diff --git a/tutorials/deep_cnn.md b/tutorials/deep_cnn.md
index 6797540..6a4c9a9 100644
--- a/tutorials/deep_cnn.md
+++ b/tutorials/deep_cnn.md
@@ -268,7 +268,7 @@ in `cifar10_input.py`.
`cifar10_train.py` periodically @{tf.train.Saver$saves}
all model parameters in
-@{$variables#saving-and-restoring$checkpoint files}
+@{$programmers_guide/saved_model$checkpoint files}
but it does *not* evaluate the model. The checkpoint file
will be used by `cifar10_eval.py` to measure the predictive
performance (see [Evaluating a Model](#evaluating-a-model) below).
diff --git a/tutorials/image_retraining.md b/tutorials/image_retraining.md
index 246a420..93d7c86 100644
--- a/tutorials/image_retraining.md
+++ b/tutorials/image_retraining.md
@@ -115,7 +115,7 @@ process is progressing. The training's objective is to make the loss as small as
possible, so you can tell if the learning is working by keeping an eye on
whether the loss keeps trending downwards, ignoring the short-term noise.
-By default this script will run 4,000 training steps. Each step chooses ten
+By default this script will run 4,000 training steps. Each step chooses 100
images at random from the training set, finds their bottlenecks from the cache,
and feeds them into the final layer to get predictions. Those predictions are
then compared against the actual labels to update the final layer's weights
diff --git a/tutorials/kernel_methods.md b/tutorials/kernel_methods.md
index 63f408c..73e5c51 100644
--- a/tutorials/kernel_methods.md
+++ b/tutorials/kernel_methods.md
@@ -1,9 +1,9 @@
# Improving Linear Models Using Explicit Kernel Methods
-Note: This document uses a deprecated version of ${tf.estimator},
-which has a ${tf.contrib.learn.estimator$different interface}.
+Note: This document uses a deprecated version of @{tf.estimator},
+which has a @{tf.contrib.learn.Estimator$different interface}.
It also uses other `contrib` methods whose
-${$version_compat#not_covered$API may not be stable}.
+@{$version_compat#not_covered$API may not be stable}.
In this tutorial, we demonstrate how combining (explicit) kernel methods with
linear models can drastically increase the latters' quality of predictions
@@ -53,7 +53,7 @@ In order to feed data to a `tf.contrib.learn Estimator`, it is helpful to conver
it to Tensors. For this, we will use an `input function` which adds Ops to the
TensorFlow graph that, when executed, create mini-batches of Tensors to be used
downstream. For more background on input functions, check
-@{$get_started/premade_estimators#input_fn$this section on input functions}.
+@{$get_started/premade_estimators#create_input_functions$this section on input functions}.
In this example, we will use the `tf.train.shuffle_batch` Op which, besides
converting numpy arrays to Tensors, allows us to specify the batch_size and
whether to randomize the input every time the input_fn Ops are executed
diff --git a/tutorials/layers.md b/tutorials/layers.md
index ee03f44..cadaec3 100644
--- a/tutorials/layers.md
+++ b/tutorials/layers.md
@@ -193,22 +193,28 @@ to calculate loss, configure the training op, and generate predictions. If
you're already experienced with CNNs and @{$get_started/custom_estimators$TensorFlow `Estimator`s},
and find the above code intuitive, you may want to skim these sections or just
skip ahead to ["Training and Evaluating the CNN MNIST
-Classifier"](#training-and-evaluating-the-cnn-mnist-classifier).
+Classifier"](#training_and_evaluating_the_cnn_mnist_classifier).
### Input Layer
The methods in the `layers` module for creating convolutional and pooling layers
for two-dimensional image data expect input tensors to have a shape of
-[batch_size, image_width, image_height,
-channels]
, defined as follows:
+[batch_size, image_height, image_width,
+channels]
by default. This behavior can be changed using the data_format
parameter; defined as follows:
+
* _`batch_size`_. Size of the subset of examples to use when performing
gradient descent during training.
-* _`image_width`_. Width of the example images.
* _`image_height`_. Height of the example images.
+* _`image_width`_. Width of the example images.
* _`channels`_. Number of color channels in the example images. For color
images, the number of channels is 3 (red, green, blue). For monochrome
images, there is just 1 channel (black).
+* _`image_height`_. Height of the example images.
+* _`data_format`_. A string, one of `channels_last` (default) or `channels_first`.
+ `channels_last` corresponds to inputs with shape
+ `(batch, ..., channels)` while `channels_first` corresponds to
+ inputs with shape `(batch, channels, ...)`.
Here, our MNIST dataset is composed of monochrome 28x28 pixel images, so the
desired shape for our input layer is [batch_size, 28, 28,
@@ -247,28 +253,27 @@ conv1 = tf.layers.conv2d(
```
The `inputs` argument specifies our input tensor, which must have the shape
-[batch_size, image_width, image_height,
+[batch_size, image_height, image_width,
channels]
. Here, we're connecting our first convolutional layer
to `input_layer`, which has the shape [batch_size, 28, 28,
1]
.
> Note: conv2d()
will instead accept a shape of
-> [channels, batch_size, image_width,
-> image_height]
when passed the argument
+> [batch_size, channels, image_height, image_width]
when passed the argument
> data_format=channels_first
.
The `filters` argument specifies the number of filters to apply (here, 32), and
-`kernel_size` specifies the dimensions of the filters as [width,
-height]
(here, [5, 5]
).
+`kernel_size` specifies the dimensions of the filters as [height,
+width]
(here, [5, 5]
).
-TIP: If filter width and height have the same value, you can instead specify a
+
TIP: If filter height and width have the same value, you can instead specify a
single integer for kernel_size
—e.g., kernel_size=5
.
The `padding` argument specifies one of two enumerated values
(case-insensitive): `valid` (default value) or `same`. To specify that the
-output tensor should have the same width and height values as the input tensor,
+output tensor should have the same height and width values as the input tensor,
we set `padding=same` here, which instructs TensorFlow to add 0 values to the
-edges of the input tensor to preserve width and height of 28. (Without padding,
+edges of the input tensor to preserve height and width of 28. (Without padding,
a 5x5 convolution over a 28x28 tensor will produce a 24x24 tensor, as there are
24x24 locations to extract a 5x5 tile from a 28x28 grid.)
@@ -277,7 +282,7 @@ output of the convolution. Here, we specify ReLU activation with
@{tf.nn.relu}.
Our output tensor produced by `conv2d()` has a shape of
-[batch_size, 28, 28, 32]
: the same width and height
+[batch_size, 28, 28, 32]
: the same height and width
dimensions as the input, but now with 32 channels holding the output from each
of the filters.
@@ -292,31 +297,30 @@ pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)
```
Again, `inputs` specifies the input tensor, with a shape of
-[batch_size, image_width, image_height,
+[batch_size, image_height, image_width,
channels]
. Here, our input tensor is `conv1`, the output from
the first convolutional layer, which has a shape of [batch_size,
28, 28, 32]
.
> Note: As with conv2d()
, max_pooling2d()
will instead
-> accept a shape of [channels, batch_size,
-> image_width, image_height]
when passed the argument
+> accept a shape of [batch_size, channels,
+> image_height, image_width]
when passed the argument
> data_format=channels_first
.
The `pool_size` argument specifies the size of the max pooling filter as
-[width, height]
(here, `[2, 2]`). If both
+[height, width]
(here, `[2, 2]`). If both
dimensions have the same value, you can instead specify a single integer (e.g.,
`pool_size=2`).
The `strides` argument specifies the size of the stride. Here, we set a stride
of 2, which indicates that the subregions extracted by the filter should be
-separated by 2 pixels in both the width and height dimensions (for a 2x2 filter,
+separated by 2 pixels in both the height and width dimensions (for a 2x2 filter,
this means that none of the regions extracted will overlap). If you want to set
-different stride values for width and height, you can instead specify a tuple or
+different stride values for height and width, you can instead specify a tuple or
list (e.g., `stride=[3, 6]`).
Our output tensor produced by `max_pooling2d()` (`pool1`) has a shape of
-[batch_size, 14, 14, 32]
: the 2x2 filter reduces width and
-height by 50% each.
+[batch_size, 14, 14, 32]
: the 2x2 filter reduces height and width by 50% each.
### Convolutional Layer #2 and Pooling Layer #2
@@ -338,13 +342,11 @@ pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)
Note that convolutional layer #2 takes the output tensor of our first pooling
layer (`pool1`) as input, and produces the tensor `conv2` as output. `conv2`
-has a shape of [batch_size, 14, 14, 64]
, the same width
-and height as `pool1` (due to `padding="same"`), and 64 channels for the 64
+has a shape of [batch_size, 14, 14, 64]
, the same height and width as `pool1` (due to `padding="same"`), and 64 channels for the 64
filters applied.
Pooling layer #2 takes `conv2` as input, producing `pool2` as output. `pool2`
-has shape [batch_size, 7, 7, 64]
(50% reduction of width
-and height from `conv2`).
+has shape [batch_size, 7, 7, 64]
(50% reduction of height and width from `conv2`).
### Dense Layer
@@ -360,7 +362,7 @@ pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 64])
In the `reshape()` operation above, the `-1` signifies that the *`batch_size`*
dimension will be dynamically calculated based on the number of examples in our
-input data. Each example has 7 (`pool2` width) * 7 (`pool2` height) * 64
+input data. Each example has 7 (`pool2` height) * 7 (`pool2` width) * 64
(`pool2` channels) features, so we want the `features` dimension to have a value
of 7 * 7 * 64 (3136 in total). The output tensor, `pool2_flat`, has shape
[batch_size, 3136]
.
@@ -446,7 +448,7 @@ tf.nn.softmax(logits, name="softmax_tensor")
> Note: We use the `name` argument to explicitly name this operation
> `softmax_tensor`, so we can reference it later. (We'll set up logging for the
-> softmax values in ["Set Up a Logging Hook"](#set-up-a-logging-hook).
+> softmax values in ["Set Up a Logging Hook"](#set-up-a-logging-hook)).
We compile our predictions in a dict, and return an `EstimatorSpec` object:
@@ -534,9 +536,8 @@ if mode == tf.estimator.ModeKeys.TRAIN:
```
> Note: For a more in-depth look at configuring training ops for Estimator model
-> functions, see @{$get_started/custom_estimators#defining-the-training-op-for-the-model$"Defining
-> the training op for the model"} in the @{$get_started/custom_estimators$"Creating Estimations in
-> tf.estimator"} tutorial.
+> functions, see @{$get_started/custom_estimators#defining_the_training_op_for_the_model$"Defining the training op for the model"}
+> in the @{$get_started/custom_estimators$"Creating Estimators in tf.estimator."} tutorial.
### Add evaluation metrics
@@ -625,7 +626,8 @@ operation earlier when we generated the probabilities in `cnn_model_fn`.
> Note: If you don't explicitly assign a name to an operation via the `name`
> argument, TensorFlow will assign a default name. A couple easy ways to
> discover the names applied to operations are to visualize your graph on
-> @{$graph_viz$TensorBoard}) or to enable the @{$debugger$TensorFlow Debugger (tfdbg)}.
+> @{$graph_viz$TensorBoard}) or to enable the
+> @{$programmers_guide/debugger$TensorFlow Debugger (tfdbg)}.
Next, we create the `LoggingTensorHook`, passing `tensors_to_log` to the
`tensors` argument. We set `every_n_iter=50`, which specifies that probabilities
diff --git a/tutorials/recurrent_quickdraw.md b/tutorials/recurrent_quickdraw.md
index e22536a..5d83fbe 100644
--- a/tutorials/recurrent_quickdraw.md
+++ b/tutorials/recurrent_quickdraw.md
@@ -38,8 +38,8 @@ To try the code for this tutorial:
1. [Download the data](#download-the-data) in `TFRecord` format from
[here](http://download.tensorflow.org/data/quickdraw_tutorial_dataset_v1.tar.gz) and unzip it. More details about [how to
obtain the original Quick, Draw!
- data](#optional-download-the-full-quick-draw-data) and [how to convert that
- to `TFRecord` files](#optional-converting-the-data) is available below.
+ data](#optional_download_the_full_quick_draw_data) and [how to convert that
+ to `TFRecord` files](#optional_converting_the_data) is available below.
1. Execute the tutorial code with the following command to train the RNN-based
model described in this tutorial. Make sure to adjust the paths to point to
@@ -108,8 +108,9 @@ This download will take a while and download a bit more than 23GB of data.
### Optional: Converting the data
To convert the `ndjson` files to
-@{$python/python_io#tfrecords_format_details$TFRecord} files containing
-${tf.train.Example} protos run the following command.
+@{$python/python_io#TFRecords_Format_Details$TFRecord} files containing
+[`tf.train.Example`](https://www.tensorflow.org/code/tensorflow/core/example/example.proto)
+protos run the following command.
```shell
python create_dataset.py --ndjson_path rnn_tutorial_data \
@@ -117,7 +118,7 @@ ${tf.train.Example} protos run the following command.
```
This will store the data in 10 shards of
-@{$python/python_io#tfrecords_format_details$TFRecord} files with 10000 items
+@{$python/python_io#TFRecords_Format_Details$TFRecord} files with 10000 items
per class for the training data and 1000 items per class as eval data.
This conversion process is described in more detail in the following.
diff --git a/tutorials/wide.md b/tutorials/wide.md
index bf6b9d6..27ce75a 100644
--- a/tutorials/wide.md
+++ b/tutorials/wide.md
@@ -74,8 +74,8 @@ Here's a list of columns available in the Census Income dataset:
| relationship | Categorical | Wife, Own-child, Husband, |
: : : Not-in-family, Other-relative, :
: : : Unmarried. :
-| race | Categorical | White, Asian-Pac-Islander, |
-: : : Amer-Indian-Eskimo, Other, Black. :
+| race | Categorical | Amer-Indian-Eskimo, Asian-Pac- |
+: : : Islander, Black, White, Other. :
| gender | Categorical | Female, Male. |
| capital_gain | Continuous | Capital gains recorded. |
| capital_loss | Continuous | Capital Losses recorded. |