Professional Documents
Culture Documents
Some Setup
In [ ]: import random
import tensorflow as tf
import numpy as np
Computation Graphs
The primary construct in the TensorFlow API is the "computation graph", or just "graph" as we'll be calling
it in this class. A computation graph is a useful way to illustrate the flow of data through multiple
operations. Here's a basic example showing the graph for adding two numbers together:
The arrows represent data flowing through through the graph (in this case the numbers 7, 3, and 10) while
the nodes represent some form of computation (in this case addition).
We can chain multiple of these computations together to form a more complex transformation of the data:
Here, the numbers 3 and 7 are sent to an addition operation and a multiplication operation. The outputs of
both of these are then sent to a subtraction operation. There are a few ways to illustrate the above
operations.
We could show this as a one-liner math equation, using parentheses to show the order of operations:
output = (3 + 7) − (3 × 7) = −11
We could also define the separate operations as mathematical functions:
a(x, y) = x + y
b(x, y) = x × y
c(x, y) = a(x, y) − b(x, y)
1 of 23 3/10/18, 6:49 PM
Week1_Tensorflow_Fundamentals_HW http://localhost:8888/notebooks/Desktop/Ai/Inte...
x = 3
y = 7
a = add(x, y)
b = multiply(x, y)
c = subtract(a, b)
The data isn't just one and done, either; it can be reused multiple times throughout the computation:
This graph is similar to the previous model, but now we're reusing the 3 by adding it back in at the end.
The code might look like this:
In [ ]: x = 3
y = 7
a = add(x, y)
b = multiply(x, y)
c = subtract(a, b)
d = add(c, x)
This pattern will be used again and again throughout the course. When working with TensorFlow, your
code will effectively be divided into two parts:
2 of 23 3/10/18, 6:49 PM
Week1_Tensorflow_Fundamentals_HW http://localhost:8888/notebooks/Desktop/Ai/Inte...
3 of 23 3/10/18, 6:49 PM
Week1_Tensorflow_Fundamentals_HW http://localhost:8888/notebooks/Desktop/Ai/Inte...
Python 3
File
Edit
View
Insert
Cell
Kernel
Widgets
Help
import random
import tensorflow as tf
import numpy as np
# Computation Graphs
The primary construct in the TensorFlow API is the "computation graph", or just
The arrows represent data flowing through through the graph (in this case the
Here, the numbers 3 and 7 are sent to an addition operation and a multiplication
output=(3+7)−(3×7)=−11
output=(3+7)−(3×7)=−11
a(x,y)b(x,y)c(x,y)c(3,7)=x+y=x×y=a(x,y)−b(x,y)=a(3,7)−b(3,7)=−11
a(x,y)=x+yb(x,y)=x×yc(x,y)=a(x,y)−b(x,y)c(3,7)=a(3,7)−b(3,7)=−11
return x + y
4 of 23 3/10/18, 6:49 PM
Week1_Tensorflow_Fundamentals_HW http://localhost:8888/notebooks/Desktop/Ai/Inte...
tf.Tensor
tf.Operation
tf.Graph
tf.Session
tf.Variable
Tensor Objects
What is a Tensor?
Tensors, for our purposes, are n-dimensional matrices (or tables of numbers).
Higher dimensional tensors are simply referred to as an n-D tensor. Every value that is passed through a
TensorFlow model is a Tensor object - the TensorFlow representation of a tensor.
5 of 23 3/10/18, 6:49 PM
Week1_Tensorflow_Fundamentals_HW http://localhost:8888/notebooks/Desktop/Ai/Inte...
# 3-D tensor
t_3d_py = [[[0, 0], [0, 1], [0, 2]],
[[1, 0], [1, 1], [1, 2]],
[[2, 0], [2, 1], [2, 2]]]
Interestingly, we haven't run this constant tensor yet. We've only defined it. And, it knows a little bit about
itself: its shape. We'll get into these details in just a bit.
NumPy Arrays
Pretty much the same as native Python, but with the numpy.array function wrapping it:
6 of 23 3/10/18, 6:49 PM
Week1_Tensorflow_Fundamentals_HW http://localhost:8888/notebooks/Desktop/Ai/Inte...
# 3-D tensor
t_3d_np = np.array([[[0, 0], [0, 1], [0, 2]],
[[1, 0], [1, 1], [1, 2]],
[[2, 0], [2, 1], [2, 2]]],
dtype=np.int32)
7 of 23 3/10/18, 6:49 PM
Week1_Tensorflow_Fundamentals_HW http://localhost:8888/notebooks/Desktop/Ai/Inte...
Data Types
In general, using np.array (or np.asarray ) is the recommended way of defining values for tensors
by hand in TensorFlow. The primary reason for this is that you can specify the exact data type ( dtype )
you'd like the values to be represented with. For example, there's no way to specify a 32-bit integer vs a
64-bit integer with native Python. TensorFlow is tightly integrated with NumPy, and most TensorFlow data
types have a corresponding NumPy dtype :
Complex number made of two 32 bit floating point numbers: real and
tf.complex64 np.complex64
imaginary parts.
The primary exception to when you should not use np.array() is when defining a Tensor of
strings. When using strings, just use standard Python lists. It's best practice to include the b prefix in
front of strings to explicitly define the strings as byte-arrays:
Tensor Shapes
A common term in TensorFlow is a Tensor object's "shape". A shape value is a list or tuple containing
an ordered set of integers. The i-th element in the list describes the length of the i-th dimension in the
tensor, while the number of elements in the list defines the dimensionality of the tensor. Here are some
examples:
8 of 23 3/10/18, 6:49 PM
Week1_Tensorflow_Fundamentals_HW http://localhost:8888/notebooks/Desktop/Ai/Inte...
You can use the tf.shape Operation to get the shape value of Tensor objects:
shape = tf.Session().run(shape_op)
print("Shape of tensor: " + str(shape))
--------------------------------------------------------------------------
-
NameError Traceback (most recent call last
)
<ipython-input-1-9bce9c209600> in <module>()
1 # note, np.ndarray.reshape takes its args "flattened" out
2 # (not in a list or tuple)
----> 3 arr = np.arange(24).reshape(2,3,4)
4 print("In NumPy:", arr.shape,arr,sep="\n")
5
As mentioned, defining an Operation doesn't execute it. To execute it, we have to run it. We do that
with a helper tf.Session . More to come below! Quick quiz: is shape_op a 3D tensor or 1D tensor?
We've already seen a few Operation examples: tf.add and tf.multiply are classic
examples: they both take in two tensors and output one. When given non-scalar values, they do
addition/multiplication element-wise. Also, tf.constant and tf.shape are Operation s.
9 of 23 3/10/18, 6:49 PM
Week1_Tensorflow_Fundamentals_HW http://localhost:8888/notebooks/Desktop/Ai/Inte...
10 of 23 3/10/18, 6:49 PM
Week1_Tensorflow_Fundamentals_HW http://localhost:8888/notebooks/Desktop/Ai/Inte...
In [1]: # or, since we're in a notebook, we can just evaluate the result
# (without explicitly needing to print it out)
# note: that the returned value is a numpy array
tf.Session().run(c)
Jupyter Notebook
Week1_Tensorflow_Fundamentals_HW Current Kernel Logo
Python 3
File
Edit
View
Insert
Cell
Kernel
Widgets
Help
import random
import tensorflow as tf
import numpy as np
Computation Graphs
The primary construct in the TensorFlow API is the "computation graph", or just
The arrows represent data flowing through through the graph (in this case the
Here, the numbers 3 and 7 are sent to an addition operation and a multiplication
output=(3+7)−(3×7)=−11
output=(3+7)−(3×7)=−11
a(x,y)b(x,y)c(x,y)c(3,7)=x+y=x×y=a(x,y)−b(x,y)=a(3,7)−b(3,7)=−11
a(x,y)=x+yb(x,y)=x×yc(x,y)=a(x,y)−b(x,y)c(3,7)=a(3,7)−b(3,7)=−11
return x + y
return x * ya=
return x - y
x = 3
11 of 23 3/10/18, 6:49 PM
Week1_Tensorflow_Fundamentals_HW http://localhost:8888/notebooks/Desktop/Ai/Inte...
The majority of the TensorFlow API is Operations. In addition to Operation-specific inputs, each Operation
can take in a name parameter, which can help identify Operations in TensorBoard and other tools.
Getting into the habit of adding names to your Operations now will save you headaches later on.
When TensorFlow is imported into Python, it automatically creates a Graph object and makes it the
default graph. You can create more graphs as well:
However, operations (such as tf.add and tf.multiply ) are added to the default graph when
created. To add operations to your new graph, use a with statement along with the graph's
as_default() method. This makes that graph the default while inside of the with block:
The default graph, other than being set to the default, is no different than any other Graph . If you need
to get a handle to the default graph, use the tf.get_default_graph function:
default_graph = tf.get_default_graph()
Note: get_default_graph() will return whatever graph is set to the default, so if you are inside of a
with g.as_default() block, get_default_graph() will return g :
Most TensorFlow models will not require more than one graph per script. So, often, you can simply use the
default, implicit graph and be done. However, you may find multiple Graph instances useful when
defining two independent models side-by-side. Additionally, there are mechanisms to export and import
external models and load them in as Graph objects, which can allow you to feed the output of existing
models into your new model (or vice versa). We won't be able to demonstrate these now, but see the
TensorFlow API for more info:
Graph.as_graph_def (https://www.tensorflow.org/versions/r0.12/api_docs/python/framework
/core_graph_data_structures#Graph.as_graph_def)
tf.import_graph_def (https://www.tensorflow.org/api_docs/python/tf/import_graph_def)
TensorFlow Session
12 of 23 3/10/18, 6:49 PM
Week1_Tensorflow_Fundamentals_HW http://localhost:8888/notebooks/Desktop/Ai/Inte...
Creating Sessions
As we saw earlier, Session objects are used to launch and execute graphs. Earlier, we created a
session using its default constructor, but it has three optional parameters:
target specifies the execution engine to use. By default it is the empty string, which causes the
Session to use the standard local execution context. Typically, this parameter is only used when using
TensorFlow in a distributed setting
graph specifies which Graph object the session should run. The default value is None , which
causes the Session to load in the default graph. Sessions only manage one graph at a time, so
executing more than one graph will require more than one session
config allows users to specify advanced options to configure the session. We won't cover this
today, but some things that are available are: limiting the number of CPUs/GPUs used, logging
options, and changing optimization of the graph
Running Sessions
The most important method of a Session is its run() function. Earlier in this notebook, we saw basic
usage of the two primary parameters to run() : fetches and feed_dict .
fetches expects a list of Tensor and/or Operation handles (or just a single
Tensor / Operation ). The list specifies what computations we would like TensorFlow to run, as well
as what we'd like run() to output:
TensorFlow will only perform calculations necessary to compute the values specified in fetches , so it
won't waste time if you only need to run a small part of a large, complicated graph.
feed_dict is an optional parameter to run , but it becomes required when placeholder nodes are
included. We saw it used to feed input data to placeholders, but feed_dict can actually send values to
any node. The keys to the dictionary should be handles to Tensor objects (usually outputs of
Operations), and the values should be replacement data:
13 of 23 3/10/18, 6:49 PM
Week1_Tensorflow_Fundamentals_HW http://localhost:8888/notebooks/Desktop/Ai/Inte...
When using placeholders,TensorFlow insists that any calls to Session.run() include feed_dict
values for all placeholders:
# Now it works!
print(sess_default.run(b, feed_dict=feed_dict))
14 of 23 3/10/18, 6:49 PM
Week1_Tensorflow_Fundamentals_HW http://localhost:8888/notebooks/Desktop/Ai/Inte...
However, even though the object has been created, the value of the Variable has to be initialized
separately with either of the tf.variables_initializer() or, more commonly,
tf.global_variables_initializer() Operations. Remember that Operations must be passed
into Session.run() to be executed:
Having value initialization separated from object creation allows us to reinitialize the variable later if we'd
like.
Now that the Variable is initialized, we can tweak it's value! Let's do some basic incrementing with the
Variable.assign() method:
for i in range(10):
print(sess.run(increment), end=" ")
You may notice that if you run the previous code multiple times in the notebook (i.e., rerun the prior cell a
few times in a row), the value persists and continues to climb. The Variable's state is maintained by the
Session object, and the state will persist unless either the session is close, the Variable is re-initialized, or
a new value is assigned to the Variable.
Trainable Variables
There are several optional parameters in the Variable constructor, but one to pay close attention to is
trainable . It takes in a boolean value, which defaults to True , and specifies to TensorFlow whether
the built-in optimization functions (which we will cover in a separate notebook) should affect this
Variable . If a Variable in you model should not be adjusted during gradient descent, make
sure to set its trainable parameter to False
Exercise 1
15 of 23 3/10/18, 6:49 PM
Week1_Tensorflow_Fundamentals_HW http://localhost:8888/notebooks/Desktop/Ai/Inte...
Part 1
Part 2
Once you've created the graph, use a Session to run the graph and confirm the following input/output
pairs:
In Out
1, 2, 3 14
-1, -2, 3 2
Part 3
Finally, use tf.summary.FileWriter to output the Graph to disk and double check that your
model resembles the above image in TensorBoard (the image reads from left to right, TensorBoard
displays them from bottom to top.
Solution 1
Part 1
In [ ]:
Part 2
In [ ]:
TensorBoard
16 of 23 3/10/18, 6:49 PM
Week1_Tensorflow_Fundamentals_HW http://localhost:8888/notebooks/Desktop/Ai/Inte...
TensorBoard (https://www.tensorflow.org/versions/r0.11/how_tos/summaries_and_tensorboard/index.html)
is TensorFlow's built-in visualization software. With it, users can examine the error rate of models over
time, debug their graphs, examine summary statistics, and compare various models with one another.
Without context, graphs that use TensorBoard summaries can seem cluttered and confusing. However,
they are actually quite straightforward once you understand what each node is doing. Here are the basic
steps you'll most commonly see:
1. Pass the result of a Tensor you'd like to analyze to one of several summary operations
(https://www.tensorflow.org/api_guides/python/summary).
2. Group all of your summaries together using tf.summary.merge_all()
(https://www.tensorflow.org/api_docs/python/tf/summary/merge_all) for convenience.
3. Create a tf.summary.FileWriter (https://www.tensorflow.org/api_docs/python/tf/summary
/FileWriter), which is responsible for writing summaries to disk.
4. While training/evaluating, pass in the output of tf.summary.merge_all() to the FileWriter
5. Once finished, start up TensorBoard in the terminal by using the built-in tensorboard command
Let's start with a simple graph to get us going. The graph below simply takes in two placeholder
inputs and performs addition, subtraction, multiplication, and division with them:
with graph.as_default():
# Input placeholders
a = tf.placeholder(tf.float32, name="a")
b = tf.placeholder(tf.float32, name="b")
Pretty straightforward. We have two placeholder nodes, a and b , and then four Operations that take in
a and b as input. For this exercise, we don't really need to use a tf.Variable for
global_step , but it's good to get in the habit of using this pattern. All of these nodes are placed in a
tf.Graph object, graph .
Now that we've constructed our graph, we can start up a tf.Session , initialize global_step , and
run the graph. To keep things looking clean, we place all of the nodes we'd like to run into a list called
fetches ahead of time:
17 of 23 3/10/18, 6:49 PM
Week1_Tensorflow_Fundamentals_HW http://localhost:8888/notebooks/Desktop/Ai/Inte...
Now, let's get our first taste of TensorBoard. We'll add in some summaries in just a moment, but it's
important to see that TensorBoard can be used to examine your graph with barely any extra effort. As
mentioned above, the key class used to utilize TensorBoard is tf.summary.FileWriter , which
takes in a string output directory as an input parameter. That is, you tell the FileWriter where to save
files locally on disk. When creating a FileWriter , you can optionally pass in a Graph object, which
will store a serialized version of the graph to disk, allowing you to explore your model graphically!
If all you want to do is check out your graph, all you need to do is include these two lines:
This creates a FileWriter and tells it to save information about our graph. Calling close() flushes
any summaries that still need to be written to disk and closes the FileWriter . Since we aren't adding
any summaries yet, we can immediately close the writer. Now, we should have a new directory inside the
folder this notebook is located in called basic_ops . Navigate to the notebook directory inside your
console and type the following:
$ tensorboard --logdir=tbout/basic_ops
At first, you won't see much: the initial screen loaded is the "Summaries" tab, and we don't have any
summaries (yet)! Click the "Graph" button at the top, and you should see a visual representation of our
graph. Neat!
Note: If tensorboard doesn't automatically start up a browser window or tab in your current browser,
simply create a new tab on your own and paste the URL to the right of the at from this line in the output:
Starting TensorBoard b'47' at http://0.0.0.0:6006 . In this case, we would paste
http://0.0.0.0:6006 (http://0.0.0.0:6006) into a new brower tab
Adding Summaries
Now we're going to modify our previous graph by adding in some summary operations. In this example,
we'll use tf.summary.scalar , which creates a summary for a single (scalar) number. We'll make a
new graph called summary_graph to store our new model:
18 of 23 3/10/18, 6:49 PM
Week1_Tensorflow_Fundamentals_HW http://localhost:8888/notebooks/Desktop/Ai/Inte...
with summary_graph.as_default():
# Input placeholders
a = tf.placeholder(tf.float32, name="a")
b = tf.placeholder(tf.float32, name="b")
As you can see, we've added summaries for our inputs as well as our four different operations. At the very
bottom (line 31 - hit Control-m followed by l (the letter L) in the code cell to see the line numbers), we've
created a tf.summary.merge_all() operation, which bundles all of our summaries together into
one operation. If we didn't use this, we'd have to run each of the summaries individually, which would get
cumbersome.
Now, as before, let's open a Session . We'll also open a FileWriter that points to the directory
'basic_summaries', but leave it open, as we're going to be writing summaries to disk with it.
sess = tf.Session(graph=summary_graph)
writer = tf.summary.FileWriter(get_fresh_dir('tbout/basic_summaries'),
graph=summary_graph)
sess.run(init)
We're going to create 20 random samples to generate some toy data. For each sample, we get a random
number between 0-25 for both a and b , and then run our graph with those random numbers as input.
When we run merged , our merge_all op, sess.run() outputs a summary object which we can
pass into our SummaryWriter . We do this by calling writer.add_summary , which takes in a
summary object and (optionally) a global_step parameter.
Notice that instead of creating a fetches list as we did above, we're only calling the merge_all
operation. Because we don't need to use the output from the model and the summaries depend on the
output nodes in order to be calculated, we can simply call the merged op to implicitly run each of our
addition, subtraction, multiplication, and division nodes.
19 of 23 3/10/18, 6:49 PM
Week1_Tensorflow_Fundamentals_HW http://localhost:8888/notebooks/Desktop/Ai/Inte...
Once we're done running our graph, we can close out our Session and FileWriter :
In [ ]: sess.close()
writer.close()
Now let's check out our summaries! Start up TensorBoard, pointing to the "basic_summaries" directory:
$ tensorboard --logdir=tbout/basic_summaries
We'll be using and discussing TensorBoard throughout the class, but you can check out its documentation
here (https://www.tensorflow.org/get_started/summaries_and_tensorboard).
Exercise 2
Part 1
Examine the following code. Using pen/paper or a whiteboard, draw the computation graph you think is the
result of running this code in TensorFlow.
Remember that the Python variable handles (in this case, the variables a and b ) are simply pointers to
underlying Operation or Tensor objects, and assigning them a new Operation or Tensor
doesn't change/modify the original Tensor .
To check your answer, start up TensorBoard on tbout/01_lab21 and look at the displayed Graph .
Part 2
Solution 2
Part 1
20 of 23 3/10/18, 6:49 PM
Week1_Tensorflow_Fundamentals_HW http://localhost:8888/notebooks/Desktop/Ai/Inte...
Run the code in the cell for Part 1 and then view the graph with:
Part 2
In [ ]:
with tf.name_scope('my_section'):
# Place some ops indented here
...
with tf.name_scope('another_section'):
# Place ops related to something else here
...
Let's add some name scopes to our last Graph to see how they help us:
21 of 23 3/10/18, 6:49 PM
Week1_Tensorflow_Fundamentals_HW http://localhost:8888/notebooks/Desktop/Ai/Inte...
with organized_graph.as_default():
with tf.name_scope('inputs'):
a = tf.placeholder(tf.float32, name="a")
b = tf.placeholder(tf.float32, name="b")
with tf.name_scope('input_summaries'):
a_summ = tf.summary.scalar("a_input_summary", a)
b_summ = tf.summary.scalar("b_input_summary", b)
with tf.name_scope('operations'):
plus = tf.add(a, b, name="a_plus_b")
minus = tf.subtract(a, b, name="a_minus_b")
times = tf.multiply(a, b, name="a_times_b")
divided = tf.divide(a, b, name="a_divided_by_b")
with tf.name_scope('op_summaries'):
plus_summ = tf.summary.scalar("plus_op_summary", plus)
minus_summ = tf.summary.scalar("minus_op_summary", minus)
times_summ = tf.summary.scalar("times_op_summary", times)
divided_summ = tf.summary.scalar("divided_op_summary", divided)
with tf.name_scope('global_step'):
global_step = tf.Variable(0, trainable=False, dtype=tf.int32, name="global_step
inc_step = tf.assign(global_step, global_step + 1, name="increment_step"
with tf.name_scope('helpers'):
init = tf.global_variables_initializer()
merged = tf.summary.merge_all()
As you can see, we simply added different sections to our existing code, which provides a nice form of
self-documentation. Now we can run it, placing our summaries into a new directory,
tbout/organized_summaries .
for i in range(20):
rand_a = random.uniform(0, 25)
rand_b = random.uniform(0, 25)
feed_dict = {a: rand_a, b: rand_b}
step, summaries = sess.run([inc_step, merged], feed_dict=feed_dict)
writer.add_summary(summaries, global_step=step)
writer.flush()
writer.close()
sess.close()
tensorboard --logdir=tbout/organized_summaries`]
Exercise 3
22 of 23 3/10/18, 6:49 PM
Week1_Tensorflow_Fundamentals_HW http://localhost:8888/notebooks/Desktop/Ai/Inte...
Solution 3
In [ ]:
In [ ]:
In [ ]:
23 of 23 3/10/18, 6:49 PM