yuqli
yuqli

Reputation: 5161

tf.constant_initializer() vs tf.global_variables_initializer()

In the following code from this website, what's the role of tf.constant_initializer(0.) and tf.global_variables_initializer()? Why do we need two initializers?

import tensorflow as tf

### build the graph
## first set up the parameters
m = tf.get_variable("m", [], initializer=tf.constant_initializer(0.))
b = tf.get_variable("b", [], initializer=tf.constant_initializer(0.))
init = tf.global_variables_initializer()

## then set up the computations
input_placeholder = tf.placeholder(tf.float32)
output_placeholder = tf.placeholder(tf.float32)

x = input_placeholder
y = output_placeholder
y_guess = m * x + b

loss = tf.square(y - y_guess)

## finally, set up the optimizer and minimization node
optimizer = tf.train.GradientDescentOptimizer(1e-3)
train_op = optimizer.minimize(loss)

### start the session
sess = tf.Session()
sess.run(init)

The original post I link has an explanation that goes:

The answer lies in the split between sessions and graphs. We’ve set the initializer property of get_variable to point at our const_init_node, but that just added a new connection between nodes in the graph. We haven’t done anything about the root of the exception: the memory associated with the variable node (which is stored in the session, not the graph!) is still set to “null”. We need the session to tell the const_init_node to actually update the variable.

... which still seems confusing as, in that case, why do we need the tf.constant_initializer(0.) at all? We might as well just leave our m and b uninitialized until we run tf.global_variables_initializer()...

Upvotes: 4

Views: 701

Answers (3)

Sihyeon Kim
Sihyeon Kim

Reputation: 161

This TensorFlow Guide about initializing variables might be helpful.

And below three things are from TensorFlow site and also useful.
tf.get_variable: Gets an existing variable with these parameters or create a new one.
tf.constant_initializer: Initializer that generates tensors with constant values.
tf.global_variables_initializer: Returns an Op that initializes global variables.


To put it simply, the role of tf.constant_initializer is to generate constant values.
The role of tf.global_variables_initializer is to initialize variables. In TensorFlow, you should initialize variables before creating graphs and sessions. Therefore you have to use tf.global_variables_initializer when using variables.


Actually, in your code, you don't have to use tf.constant_initializer because tf.get_variable uses default initializer as glorot_uniform_initializer.

But you should use tf.global_variables_initializer because tf.get_variable gets an variables or creates an variables.


Example code 1: If you do not use tf.global_variables_initializer then yon encounter an error message.

import tensorflow as tf

m = tf.get_variable("m", [])
b = tf.get_variable("b", [])

y = m + b

sess = tf.Session()
sess.run(y)
# Example code 1 result

FailedPreconditionError: Attempting to use uninitialized value m
     [[{{node m/read}}]]

Example code 2: You don't have to use tf.constant_initializer.

import tensorflow as tf

m = tf.get_variable("m", [])
b = tf.get_variable("b", [])
init = tf.global_variables_initializer()

y = m + b

sess = tf.Session()
sess.run(init)
sess.run(y)
# Example code 2 result

Call initializer instance with the dtype argument instead of passing it to the constructor
0.43568623

Finally, even if you use tf.constant_initializer in tf.get_variable you should use tf.global_variables_initializer. The reason is that tf.get_variable is a variable. So you initialize variables before tf.Session by using tf.global_variables_initializer.

Maybe you can think of initializer in tf.get_variable(e.g tf.constant_initializer, glorot_uniform_initializer) as initializing value by some kind of distributions when initializing variables by using tf.global_variables_initializer.

Upvotes: 2

gorjan
gorjan

Reputation: 5555

Let's assume that you want to create a Tensorflow graph and train it from scratch. Therefore, all of the tf.Variable in your TF Graph will be initialized randomly. For example, in the code bellow, the tf.Variable will be initialized with values from a normal distribution.

tf.reset_default_graph()
x = tf.get_variable(name="random", shape=[1, 5] initializer=tf.random_normal_initializer())
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(x))
    # [[-1.1984633  -0.42527035 -1.020795   -0.7023787   0.22350429]]

Now, let us assume that you again want to create a TF Graph and train it from scratch. However, right now, for some weird reason, you know the exact values that you want to use for some of the tf.Variable in your graph. Therefore:

tf.reset_default_graph()
x = tf.get_variable(name="constant", shape=[1,5], initializer=tf.constant_initializer(value=[[1,2,3,4,5]]))
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(x))
    # [[1. 2. 3. 4. 5.]]

you initialized those tf.Variable with a the values you wish.

As for the distinction between tf.global_variables_initializer and tf.constant_initializer, they are something completely different:

  • tf.global_variables_initializer is an operation that you execute to initialize all variables in your graph. It doesn't matter whether the variables will get initialized with tf.constant_initializer, tf.random_normal_initializer or tf.glorot_uniform_initializer. You just pass that operation to a tf.Session so that the graph variables will get initialized.

  • tf.constant_initializer on the other hand, is just an initializer that you pass to the tf.Variable of your graph. Then, when a tf.Session runs the operation tf.global_variables_initializer, the TF Graph will use the tf.constant_initializer to initialize the corresponding tf.Variable with the constant values provided.

Upvotes: 2

xdurch0
xdurch0

Reputation: 10474

The two are entirely different. The constant_initializer is basically an "instruction" how the variable should be initialized once this is actually done. I.e., whether it should use constant values, random uniform values, random normal values...
Passing this does not mean that the variable will be initialized with constant values at that time. If you don't pass an initializer, get_variable uses a default (glorot_uniform, I believe).

global_variables_initializer, on the other hand, is an op that will actually perform the initialization once it is run inside a session -- this will then call the execute the initializers you passed to the variables when you created them. You always need to run an op to initialize variables, since as mentioned, just passing the initializers in the constructors doesn't actually do anything.

Upvotes: 2

Related Questions