This notebook introduces the basics of using TensorFlow's eager execution capabilities. It covers concepts such as:
This notebook does not cover modeling topics, such as gradients.
In [0]:
# Import TensorFlow.
import tensorflow as tf
# Import TensorFlow eager execution support (subject to future changes).
import tensorflow.contrib.eager as tfe
In [0]:
tfe.enable_eager_execution()
In [0]:
print(tf.add(1, 2))
print(tf.add([1, 2], [3, 4]))
print(tf.square(5))
print(tf.reduce_sum([1, 2, 3]))
print(tf.encode_base64("hello world"))
print("")
x = tf.constant(2)
y = tf.constant(3)
print(x * y + 1)
# Most TensorFlow ops are directly usable with eager execution, giving
# results immediately.
print(tf.contrib.signal.hamming_window(x * y + 1))
Numpy arrays are supported, too:
In [0]:
import numpy as np
ones = np.ones([3, 3])
print("numpy 3x3 matrix of 1s:")
print(ones)
print("")
print("Multiplied by 42:")
print(tf.multiply(ones, 42))
In [0]:
x = tf.get_variable(name="x", shape=[], dtype=tf.float32, initializer=tf.zeros_initializer)
In [0]:
# This does NOT print the Variable's actual value:
print("Printing a TensorFlow Variable:")
print(x)
print("")
# A TensorFlow variable represents a reference to a tensor.
# The `read_value()` method provides access to the current value of the
# variable. Tensorflow Variables are automatically initialized according to the
# semantics defined in tf.get_variable().
print("Printing a TensorFlow Variable's value using .read_value():")
print(x.read_value())
print("")
print("Printing a TensorFlow Variable's value using .read_value().numpy():")
print(x.read_value().numpy())
In [0]:
x.assign(42)
print(x.read_value())
x.assign_add(3)
print(x.read_value())
In [0]:
print(x + 3)
# This code will broadcast the value across the list of numbers:
print(x * [1, 2, 4])
TensorFlow's eager execution helps you identify and debug runtime issues through interactive exploration of code snippets.
Below, we'll define a length-4 vector, and attempt two tf.slice()
operations,
one being legal and the other being illegal, leading to a runtime error that is
raised immediately.
In [0]:
vector = tf.constant([10.0, 20.0, 30.0, 40.0])
In [0]:
# Works, because the values of `begin` and `size` (the 2nd and 3rd input
# arguments) are within the bound of `vector`.
print(tf.slice(vector, [1], [3]))
In [0]:
# The following does NOT work, because the value of `size` (the 3rd
# argument) causes the indices to go out of the bounds of `vector`. The
# error is raised immediately.
try:
print(tf.slice(vector, [1], [4]))
except tf.OpError as e:
print("Caught error: %s" % e)
In [0]:
# The example code from here on will work only if your notebook
# is running on a machine with a functional CUDA GPU. The following
# line checks that.
is_gpu_available = tfe.num_gpus() > 0
# Create some Tensors
SIZE = 1000
cpu_tensor = tf.random_normal([SIZE, SIZE])
if is_gpu_available:
gpu_tensor = cpu_tensor.gpu()
In [0]:
# Time a CPU-based matrix multiplication
print("Time to conduct matmul on CPU:")
%time tf.matmul(cpu_tensor, cpu_tensor)
In [0]:
# Time GPU-based matrix multiplications.
if is_gpu_available:
# First use of the GPU will be slow:
print("Time to conduct first matmul on GPU:")
%time tf.matmul(gpu_tensor, gpu_tensor)
print()
# Subsequent uses are much faster:
print("Time to conduct second matmul on GPU:")
%time tf.matmul(gpu_tensor, gpu_tensor)
In [0]:
# Second timing demo for GPUs, after it has been used once:
cpu_tensor = tf.random_normal([SIZE, SIZE])
print("Time to conduct CPU matmul:")
%time tf.matmul(cpu_tensor, cpu_tensor)
print()
if is_gpu_available:
gpu_tensor = cpu_tensor.gpu()
print("Time to conduct GPU matmul:")
%time tf.matmul(gpu_tensor, gpu_tensor)