Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keras, tensorflow: Initializer for variable... is from inside a control-flow construct, a loop or conditional

I am training a mask r-cnn model refer to this rep on github: https://github.com/matterport/Mask_RCNN

I meet a problem which seems to be an issue of using Keras, so I come here.

The code calculates masks from region of interest(rois) and feature map:

mrcnn_mask = build_fpn_mask_graph(rois, mrcnn_feature_maps,
    config.IMAGE_SHAPE,
    config.MASK_POOL_SIZE,
    config.NUM_CLASSES)

However, sometimes rois maybe all zeros, in which case I want to return all zeros directly. So, I use tf.cond like this:

def ff_true():
    mrcnn_mask = build_fpn_mask_graph(rois, mrcnn_feature_maps,
       config.IMAGE_SHAPE,
       config.MASK_POOL_SIZE,
       config.NUM_CLASSES)

def ff_false():
    return tf.zeros_like(target_mask)

mrcnn_mask = KL.Lambda(lambda x: tf.cond(tf.equal(tf.reduce_mean(x), 0), 
    ff_true, ff_true)) (rois)

This raises an error:

ValueError: Initializer for variable lambda_5/cond/mrcnn_mask_conv1/kernel/ is from inside a control-flow construct, such as a loop or conditional. When creating a variable inside a loop or conditional, use a lambda as the initializer.

I google it but no useful info got. This seems to be an issue of falsely using keras/tensorflow. Any clue will be welcomed!

BTW, if I use this code, it will be no error(but I don't want to calculate a in advance):

a = build_fpn_mask_graph(rois, mrcnn_feature_maps,
    config.IMAGE_SHAPE,
    config.MASK_POOL_SIZE,
    config.NUM_CLASSES)   
def ff_true():
    return a
def ff_false():
    return tf.zeros_like(target_mask)

mrcnn_mask = KL.Lambda(lambda x: tf.cond(tf.equal(tf.reduce_mean(x), 0), 
    ff_true, ff_true)) (rois)
like image 520
Pavle Avatar asked Jan 30 '18 06:01

Pavle


People also ask

How do you initialize a TensorFlow variable?

To initialize a new variable from the value of another variable use the other variable's initialized_value() property. You can use the initialized value directly as the initial value for the new variable, or you can use it as any other tensor to compute a value for the new variable.

What is the use of TensorFlow variable?

A TensorFlow variable is the recommended way to represent shared, persistent state your program manipulates. This guide covers how to create, update, and manage instances of tf. Variable in TensorFlow. Variables are created and tracked via the tf.

How do you assign a value to a tensor?

We can access the value of a tensor by using indexing and slicing. Indexing is used to access a single value in the tensor. slicing is used to access the sequence of values in a tensor. we can modify a tensor by using the assignment operator.


2 Answers

The error is basically what the message says. You cannot have a variable initializer inside a conditional. A crude analogy to normal programming languages is:

if my_condition:
    a = 1
print a    # can't do this. a might be uninitialized.

Here is a simple example to illustrate this issue and the fix suggested in the error message:

import tensorflow as tf

def cond(i, _):
  return i < 10

def body(i, _):
  zero = tf.zeros([], dtype=tf.int32)
  v = tf.Variable(initial_value=zero)
  return (i + 1, v.read_value())

def body_ok(i, _):
  zero = lambda: tf.zeros([], dtype=tf.int32)
  v = tf.Variable(initial_value=zero, dtype=tf.int32)
  return (i + 1, v.read_value())

tf.while_loop(cond, body, [0, 0])

This is using tf.while_loop but it is the same as tf.cond for this purposes. If you run this code as is, you will get the same error. If you replace body with body_ok everything will be fine. The reason is that when the initializer is a function, tensorflow can place it "outside of the control flow context" to make sure it always runs.

To clarify a possible confusion for future readers, the approach to "compute a first" is not ideal but for a subtle reason. First, remember that what you are doing here is building a computation graph (assuming you are not using eager execution). So, you are not actually computing a. You are just defining how it can be computed. Tensorflow runtime decides what needs to be computed at runtime, depending on the arguments to session.run(). So, one might expect that the if the condition is false, the branch returning a will not be executed (since it is not needed). Unfortunately, this is not how TensorFlow runtime works. You can find more details in the first answer here, but briefly, TensorFlow runtime will execute all dependencies for either branch, only the operations inside the true_fn/false_fn will be executed conditionally.

like image 66
iga Avatar answered Oct 16 '22 01:10

iga


The same problem occurs with me while using keras with CNN-LSTM. The code was working fine on GPU server, but when I tried to run it on my local machine, got this weird error.

The following trick works for me.

Solution: clear variables and restart your kernel. This work for me. Maybe someone else getting to exactly the same problem what I am going through will be helpful.

like image 6
Muhammad Sohail Avatar answered Oct 16 '22 01:10

Muhammad Sohail