Tensor
Tensors play a central role in TensorFlow development and serve as the primary objects for storing and manipulating data. Optimizers only accept data contained in tensors, and image-processing functions require images to be provided as tensors. All neural network layers, from dense layers to dropout layers, accept tensors as input and return tensors as output.A tensor serves as an N-dimensional array, where N can be zero or more. A tensor’s number of dimensions is called the tensor’s rank, and the size of each dimension is called the tensor’s shape. For example, a 3-x-5 matrix has shape [3, 5], and an RGB image whose size is 200 x 200 would be represented by a tensor with size [200, 200, 3].
TensorFlow provides hundreds of functions for creating, transforming, and processing tensors. You can create a tensor with constant values by calling tf.constant
or create a tensor with random values by calling tf.random_normal
or tf.random_uniform
. You can reshape a tensor with tf.reshape
and extract part of a tensor with tf.slice
.
Operation
When the Python interpreter reaches a function that operates on tensors, it doesn't execute the operation immediately. Instead, it creates an instance of theOperation
class that represents the operation. Every Operation
has a property called inputs
that contains its input tensors and a property called outputs
that contains its output tensors.Every Operation
has a property called type
that is usually set to the function that created it. For example, if you call tf.add
, the corresponding operation will have its type
set to add
.
Other math operations include tf.divide
, tf.round
, and tf.sqrt
. TensorFlow also supports traditional matrix operations, including tf.matmul
, tf.diag
, and tf.matrix_solve
.
Graph
TensorFlow creates aTensor
instance for each tensor in your application and an Operation
for each operation involving tensors. It stores these Tensor
s and Operations
in a data structure called a Graph
. Only one Graph
can be active at a time, and you can make a new Graph active by calling as_default
.The Graph
class provides a number of methods for accessing the data contained in the graph. You can access a particular tensor with get_tensor_by_name
or access all of the graph's operations by calling get_operations
.
Each Graph
stores data in a series of containers called collections. Every collection can be accessed through a particular key, and get_all_collection_keys
provides the full list of keys. For example, a graph stores its global variables in the collection whose key is tf.GraphKeys.GLOBAL_VARIABLES
.
Session
After you add tensors and operations to a graph, you can execute the graph's operations by creating and running a session. You can create a session by callingtf.Session
and then launch the session by calling its run method.The first argument of the run method tells the session what processing to perform. If this argument contains tensors, the session will compute the elements of each tensor and return the elements in a NumPy array. If this argument contains Operations, the session will perform each operation and return the appropriate result.
If the questions on StackOverflow
are any indication, run's feed_dict
confuses many developers. This parameter accepts a dictionary that associates values with tensors (usually placeholders) in the graph. But the dictionary’s values can’t be tensors. For this reason, it’s generally a good idea to store and process input data using NumPy arrays before executing a session.
Variable
Variables resemble tensors in many respects. They store values in N-dimensional arrays and can be operated upon using regular TensorFlow operations. But during training operations, applications rely on variables to store the state of the model. For example, if an application consists of a neural network, the network’s weights and biases will be stored as variables.Another difference is that variables require a different set of methods than tensors. For example, after you create a Variable
, you need to initialize its value by running a special operation in the session. If your application has many variables, you can obtain a combined initialization operation by calling tf.global_variables_initializer
.
At a low level, the goal of training is to set the application's variables to values that will bring the model in line with observed data. These variables are critically important, so it’s a good idea to store them to checkpoint files with Savers.
Optimizer
The disparity between an application’s model and the observed data is called loss. A TensorFlow application reduces loss using an optimizer. In code, you can create an optimizer by instantiating a subclass of theOptimizer
class. Every optimizer has a minimize
method that returns an operation that can be executed in a session.TensorFlow supports a number of different optimization algorithms, and each is represented by a different subclass of Optimizer
. As an example, the simplest optimization algorithm, the gradient descent method, is represented by the GradientDescentOptimizer
. But the simplest algorithm is rarely the most effective, and I recommend optimizing your applications with the AdamOptimizer
or AdagradOptimizer
instead.
Estimator
Estimators dramatically simplify the process of developing and deploying machine learning algorithms. When you use an estimator, you don't have to worry about sessions and graphs. You simply need to know three methods of theEstimator
class: train
, evaluate
, and predict
.Another advantage of using estimators is that TensorFlow provides many subclasses of Estimator. These canned estimators, such as LinearRegressor
and DNNClassifier
, make it easy to train and test machine learning. The DNNLinearCombinedClassifier
is particularly helpful because it lets you take advantage of wide and deep learning.
Dataset
One of the most recent changes to the TensorFlow API is the promotion of thetf.contrib.data
package to tf.data
. This package provides the all-important Dataset
class, which TensorFlow recommends for loading and processing data. This class provides many powerful methods for batching and transforming data, and in many cases, you can perform these operations in a multithreaded manner.The Dataset
class is also important because it's the superclass of TextLineDataset
and TFRecordDataset
. These two classes make it straightforward to read data from text files and TFRecord files.
Iterator
TheDataset
class provides many powerful capabilities, but it doesn't let you access its data directly. To extract tensors from a dataset, you need to create an instance of the Iterator
class.TensorFlow provides four different ways to iterate through a dataset’s content. The simplest is the one-shot iterator, which can iterate through a dataset only once. You can reuse initializable and reinitializable iterators, but you’ll need to run special initialization operations first. Feedable iterators are the most complicated, but you can associate them with multiple datasets and you don’t need to initialize them before each iteration.
Saver
The goal of training is to determine which variables produce the least possible loss. Training can take hours or days, so it’s crucial to store the variable’s values during and after training. TensorFlow makes this possible by providing theSaver
class.Using this class is easy. After you create a Saver
instance, you can call save to store the model's state in numbered checkpoint files. You can load the model’s variables from the checkpoint files by calling the restore
method.