In [ ]:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
In [ ]:
a = tf.random_normal([2, 20])
with tf.Session() as sess:
out = sess.run(a)
In [ ]:
print out # a 2x20 random matrix
In [ ]:
x, y = out
In [ ]:
plt.scatter(x, y)
plt.show()
Each Tensorflow node is an Operation or Op. To create an operation, you call its associated Python operation or constructor. For example, "constant" takes a tensor input, and output several tensors the same as the input. Note that this simply add Ops to a graph behind the scenes, but no computation is actually taking place. Operations can be zero-input and zero-output. The operation in Tensorflow is more than just mathematical operations like add or sub. They can include tasks such as initializing state.
In [ ]:
# define first Tensorflow graph
a = tf.constant(5, name='input_a') # constant is an Op
b = tf.constant(3, name='input_b')
c = tf.multiply(a, b, name='mul_c')
d = tf.add(a, b, name='add_d')
e = tf.add(c, d, name='add_e')
# run the graph
with tf.Session() as sess:
print "e = %d" % sess.run(e)
writer = tf.summary.FileWriter('./my_graph/computation_graph/example_1', sess.graph)
writer.close()
In [ ]:
# define an equal graph with Tensor
a = tf.constant([5, 3], name='input_a')
b = tf.reduce_prod(a, name='prod_b')
c = tf.reduce_sum(a, name='sum_c')
d = tf.add(b, c, name='add_d')
with tf.Session() as sess:
print "d = %d" % sess.run(d)
writer = tf.summary.FileWriter('./my_graph/computation_graph/example_2', sess.graph)
writer.close()
In [ ]:
import tensorflow as tf
In [ ]:
# TensorFlow shape, can either be list or tuple
s_3_flex = [2, None, None]
a = tf.constant([5, 3], name='input_a')
b = tf.reduce_prod(a, name='prod_b')
c = tf.reduce_sum(a, name='sum_c')
d = tf.add(b, c, name='add_d')
shape = tf.shape(a, name='shape_d')
with tf.Session() as sess:
print sess.run(shape) # tf.shape is also an Operation
Technically, the == operator is overloaded as well, but it will not return a Tensor of boolean values. Instead, it will return True if the two tensors being compared are the same object, and False otherwise. This is mainly used for internal purposes. If you’d like to check for equality or inequality, check out tf.equal() and tf.not_equal, respectively.
As a convenience, TensorFlow automatically creates a Graph when the library is loaded and assigns it to be the default. Thus, any Operations, tensors, etc. defined outside of a Graph.as_default() context manager will automatically be placed in the default graph.
When defining multiple graphs in one file, it's best practice to either not use the default graph or immediately
assign a handle to it.
Additionally, it is possible to load in previously defined models from other TensorFlow scripts and assign them to Graph objects using a combination of the Graph.as_graph_def() and tf.import_graph_def functions. Thus, a user can compute and use the output of several separate models in the same Python file.
In [ ]:
# multiple graph example
import tensorflow as tf
g1 = tf.Graph()
g2 = tf.Graph()
# or we use get a handle to default graph like g2 = tf.get_default_graph()
with g1.as_default():
pass
with g2.as_default():
pass
tf.Session(target=None, graph=default_graph, config=default)
tf.Session.run(fetches, feed_dict=None, options="", run_metadata="")
In [ ]:
# use session as context manager
import tensorflow as tf
g1 = tf.Graph()
with g1.as_default():
a = tf.random_normal((2, 20))
sess = tf.Session()
print a.eval(session=sess)
sess.close()
Placeholders, as the name implies, act as if they are Tensor objects, but they do not have their values specified when created. Instead, they hold the place for a Tensor that will be fed at runtime, in effect becoming an “input” node.
In [ ]:
import tensorflow as tf
import numpy as np
# Creates a placeholder vector of length 2 with data type int32
a = tf.placeholder(tf.int32, shape=[2], name="my_input")
# Use the placeholder as if it were any other Tensor object
b = tf.reduce_prod(a, name="prod_b")
c = tf.reduce_sum(a, name="sum_c")
# Finish off the graph
d = tf.add(b, c, name="add_d")
# Open a TensorFlow Session
sess = tf.Session()
# Create a dictionary to pass into `feed_dict`
# Key: `a`, the handle to the placeholder's output Tensor
# Value: A vector with value [5, 3] and int32 data type
input_dict = {a: np.array([5, 3], dtype=np.int32)}
# Fetch the value of `d`, feeding the values of `input_vector` into `a`
result = sess.run(d, feed_dict=input_dict)
print result
sess.close()
Variables objects, which contain mutable tensor values that persist across multiple calls to Session.run(). Note that Tensor and Operations are immutable objects.
Variable Initialization
Variables have an extra step involved in order to use them- you must initialize the Variable within a Session.
In [ ]:
# 2x2 matrix of zeros
zeros = tf.zeros([2, 2])
# vector of length 6 of ones
ones = tf.ones([6])
# 3x3x3 Tensor of random uniform values between 0 and 10
uniform = tf.random_uniform([3, 3, 3], minval=0, maxval=10)
# 3x3x3 Tensor of normally distributed numbers; mean 0 and standard deviation 2
normal = tf.random_normal([3, 3, 3], mean=0.0, stddev=2.0)
# No values below 3.0 or above 7.0 will be returned in this Tensor
trunc = tf.truncated_normal([2, 2], mean=5.0, stddev=1.0)
# pass Operations to tf Variable
# Default value of mean=0.0
# Default value of stddev=1.0
random_var = tf.Variable(tf.truncated_normal([2, 2]))
In [ ]:
# variable initialization
var1 = tf.Variable(0, name="initialize_me")
var2 = tf.Variable(1, name="no_initialization")
init = tf.variables_initializer([var1], name="init_var1")
sess = tf.Session()
sess.run(init)
In [ ]:
# changing variables
# Create variable with starting value of 1
my_var = tf.Variable(1)
# Create an operation that multiplies the variable by 2 each time it is run
my_var_times_two = my_var.assign(my_var * 2)
# Initialization operation
init = tf.global_variables_initializer()
# Start a session
sess = tf.Session()
# Initialize variable
sess.run(init)
In [ ]:
# Multiply variable by two and return it
sess.run(my_var_times_two)
## OUT: 2
In [ ]:
# Multiply again
sess.run(my_var_times_two)
## OUT: 4
In [ ]:
# Multiply again
sess.run(my_var_times_two)
## OUT: 8
In [ ]:
# reset my_var
sess.run(my_var.initializer) # only reset my_var instead of global reset all the variables
sess.run(my_var)
Trainable: variables are created with trainable features, that can be automatically changed by tf.optimizer object. In some cases, we want to set trainable to False. e.g. step counters or transfer learning and finetuning models.
To manage complexity and hierarchy of large graphs, ensorFlow currently offers a mechanism to help organize your graphs: name scopes. Essentially, name scopes allow you to group Operations into larger, named blocks. Then, when you launch your graph with TensorBoard, each name scope will encapsulate its own Ops, making the visualization much more digestible.
Separating a huge graph into meaningful clusters can make understanding and debugging your model a much more approachable task.
tf.constant objects don’t behave quite the same way as other Tensors or Operations when displayed in TensorBoard. Even though we declared static_value outside of any name scope, it still gets placed inside them. The basic idea for this is that constants can be used at any time and don’t necessarily need to be used in any particular order. To prevent arrows flying all over the graph from a single point, it just makes a little small impression whenever a constant is used.
In [1]:
import tensorflow as tf
with tf.name_scope("Scope_A"):
a = tf.add(1, 2, name="A_add")
b = tf.multiply(a, 3, name="A_mul")
with tf.name_scope("Scope_B"):
c = tf.add(4, 5, name="B_add")
d = tf.multiply(c, 6, name="B_mul")
e = tf.add(b, d, name="output")
writer = tf.summary.FileWriter('./my_graph/computation_graph/name_scope', graph=tf.get_default_graph())
writer.close()
In [7]:
# use fft to compute conv2d
import tensorflow as tf
X = tf.Variable(tf.truncated_normal([128, 32, 32, 3]))
kernel = tf.Variable(tf.truncated_normal([3, 3, 3, 32]))
bias = tf.Variable(tf.truncated_normal([32]))
output = tf.nn.conv2d(X, kernel, strides=[1, 1, 1, 1], padding="SAME") + bias
dX, dKernel, dBias = tf.gradients(output, [X, kernel, bias])
sess = tf.Session()
sess.run(tf.global_variables_initializer())
dX_value, dKernel_value, dBias_value = sess.run([dX, dKernel, dBias])
In [8]:
dX_value.shape
Out[8]:
In [9]:
dKernel_value.shape
Out[9]:
In [ ]: