TypeError: An op outside of the function building code is being passed a Graph tensor
Asked Answered
D

1

18

I am getting the following exception

TypeError: An op outside of the function building code is being passed
a "Graph" tensor. It is possible to have Graph tensors
leak out of the function building context by including a
tf.init_scope in your function building code.
For example, the following function will fail:
  @tf.function
  def has_init_scope():
    my_constant = tf.constant(1.)
    with tf.init_scope():
      added = my_constant * 2
The graph tensor has name: conv2d_flipout/divergence_kernel:0

which also raises the following exception

tensorflow.python.eager.core._SymbolicException: Inputs to eager execution function cannot be Keras symbolic tensors, but found [<tf.Tensor 'conv2d_flipout/divergence_kernel:0' shape=() dtype=float32>]

when running the following code

from __future__ import print_function

import tensorflow as tf
import tensorflow_probability as tfp


def get_bayesian_model(input_shape=None, num_classes=10):
    model = tf.keras.Sequential()
    model.add(tf.keras.layers.Input(shape=input_shape))
    model.add(tfp.layers.Convolution2DFlipout(6, kernel_size=5, padding="SAME", activation=tf.nn.relu))
    model.add(tf.keras.layers.Flatten())
    model.add(tfp.layers.DenseFlipout(84, activation=tf.nn.relu))
    model.add(tfp.layers.DenseFlipout(num_classes))
    return model

def get_mnist_data(normalize=True):
    img_rows, img_cols = 28, 28
    (x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()

    if tf.keras.backend.image_data_format() == 'channels_first':
        x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
        x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
        input_shape = (1, img_rows, img_cols)
    else:
        x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
        x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
        input_shape = (img_rows, img_cols, 1)

    x_train = x_train.astype('float32')
    x_test = x_test.astype('float32')

    if normalize:
        x_train /= 255
        x_test /= 255

    return x_train, y_train, x_test, y_test, input_shape


def train():
    # Hyper-parameters.
    batch_size = 128
    num_classes = 10
    epochs = 1

    # Get the training data.
    x_train, y_train, x_test, y_test, input_shape = get_mnist_data()

    # Get the model.
    model = get_bayesian_model(input_shape=input_shape, num_classes=num_classes)

    # Prepare the model for training.
    model.compile(optimizer=tf.keras.optimizers.Adam(), loss="sparse_categorical_crossentropy",
                  metrics=['accuracy'])

    # Train the model.
    model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1)
    model.evaluate(x_test, y_test, verbose=0)


if __name__ == "__main__":
    train()

The problem is apparently related to the layer tfp.layers.Convolution2DFlipout. Why exactly am I getting these exceptions? Is this due to a logical error in my code or is it possibly a bug in TensorFlow or TensorFlow Probability? What do these errors mean? How can I solve them?

I am using TensorFlow 2.0.0 (which eagerly execute, by default). and TensorFlow Probability 0.8.0 and Python 3.7.4. I have also opened the related issue here and here.

Please, do not suggest me to use TensorFlow 1, to lazily execute my code (that is, to use tf.compat.v1.disable_eager_execution() after having imported TensorFlow, given that I know that this will make the code above run without getting the mentioned exception) or to explicitly create sessions or placeholders.

Danelle answered 25/10, 2019 at 21:25 Comment(2)
Have you found a solution to your problem without using , experimental_run_tf_function=False in the compiler? For me, it is the only thing that made it work. Not sure if the performance decrease or not.Rhyner
@MathieuChâteauvert See https://github.com/tensorflow/probability/issues/620#issuecomment-620821990.Danelle
D
4

This issue can be partially solved by setting the argument experimental_run_tf_function of the compile method to False, as I had written in a comment to the Github issue I had opened.

However, if you set experimental_run_tf_function to False and you try to use the predict method, you will get another error. See this Github issue.


Edit (28/09/2020)

experimental_run_tf_function was removed in the latest version of TF. However, in the latest version of TFP (specific versions I used are listed below), the problem with the Bayesian convolutional layers (at least, the one that uses the Flipout estimator) was fixed. See https://github.com/tensorflow/probability/issues/620#issuecomment-620821990 and https://github.com/tensorflow/probability/commit/1574c1d24c5dfa52bdf2387a260cd63a327b1839.

Specifically, I used the following versions

tensorflow==2.3.0
tensorflow-probability==0.11.0

And I used both dense and convolutional Bayesian layers, I did not use experimental_run_tf_function=False when calling compile.

Danelle answered 13/1, 2020 at 0:43 Comment(3)
Since TFv2.2 this option is no longer available isn't it? Here a sourcePhotoplay
@AgustinBarrachina I think you are right, but this error does not occur anymore in TF 2.2 (or TF 2.3) if you use the latest version of TFP, because the bug was fixed in TFP (if I remember correctly). Check the Github issues.Danelle
You can perhaps use run_eagerly=False while compiling your model.Phonometer

© 2022 - 2024 — McMap. All rights reserved.