0
$\begingroup$

I am trying to build a Contractive Auto Encoder using Tensorflow 2.0. The model's loss function uses the encoder output in its calculations. The problem is that every time i retrieve the output, it comes as a Graph Tensor even with eager execution being on by default and it throws the following error.

Is there another way of retrieving the encoder layer output or fixing this error?

My code

from os import path

import tensorflow as tf
from tensorflow.keras import layers
from tensorflow.keras import Model

__root_path = path.dirname(path.abspath(__file__)) + '/../../..'

gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
    # Restrict TensorFlow to only allocate 1GB of memory on the first GPU
    try:
        tf.config.experimental.set_virtual_device_configuration(
                gpus[0],
                [tf.config.experimental.VirtualDeviceConfiguration(memory_limit=1024)])
    except RuntimeError as e:
        # Virtual devices must be set before GPUs have been initialized
        print(e)


class Encoder(layers.Layer):
    def __init__(self, hidden_units=512, output_size=28, *args, **kwargs):
        super().__init__(*args, **kwargs)
        input_shape = kwargs.get('input_shape', (30000,))
        self.first_layer = layers.Dense(units=int(hidden_units), activation=layers.PReLU(), input_shape=input_shape)
        self.second_layer = layers.Dense(units=int(hidden_units / 2), activation=layers.PReLU())
        self.third_layer = layers.Dense(units=int(hidden_units / 4), activation=layers.PReLU())
        self.classifier = layers.Dense(units=output_size)

    def call(self, inputs, **kwargs):
        x = self.first_layer(inputs)
        x = self.second_layer(x)
        x = self.third_layer(x)
        return self.classifier(x)


class Decoder(layers.Layer):
    def __init__(self, hidden_units=512, output_units=30000, **kwargs):
        super().__init__(**kwargs)
        input_shape = kwargs.get('input_shape', (28,))
        self.first_layer = layers.Dense(hidden_units / 4, activation=layers.PReLU(), input_shape=input_shape)
        self.second_layer = layers.Dense(hidden_units / 2, activation=layers.PReLU())
        self.third_layer = layers.Dense(hidden_units, activation=layers.PReLU())
        self.output_layer = layers.Dense(output_units)

    def call(self, inputs, **kwargs):
        x = self.first_layer(inputs)
        x = self.second_layer(x)
        x = self.third_layer(x)
        return self.output_layer(x)


class ContractiveAutoEncoder(Model):
    def __init__(self, data_shape=(30000,), hidden_units=512, transition_units=28, *args,
                 **kwargs):
        super().__init__(*args, **kwargs)
        self.lam = 1e-3
        self.encoder = Encoder(input_shape=data_shape, hidden_units=hidden_units, output_size=transition_units)
        self.decoder = Decoder(input_shape=(transition_units,), hidden_units=hidden_units, output_units=data_shape[0])

    def call(self, inputs, training=None, mask=None):
        if len(inputs.shape) < 2:
            inputs = tf.expand_dims(inputs, 0)
        coded = self.encoder(inputs)
        reconstructed = self.decoder(coded)
        return reconstructed


def contractive_loss(predicted, reference):
    global nn
    mse_error = tf.reduce_mean(tf.square(reference - predicted), axis=1)
    w = nn.get_layer('encoder').weights[-2]
    w = tf.keras.backend.transpose(w)
    h = nn.get_layer('encoder').output
    dh = h * (1 - h)

    contractive = nn.lam * tf.reduce_sum(dh ** 2 * tf.reduce_sum(w ** 2, axis=1), axis=1)
    return mse_error + contractive


def gen_dataset():
    list_ds = tf.data.Dataset.list_files(__root_path + '/navigation/maps/maps/*.png')
    ds = list_ds.map(map_func=process_path, num_parallel_calls=tf.data.experimental.AUTOTUNE)
    ds = tf.data.Dataset.zip((ds, ds))
    return ds


def process_path(path):
    img = tf.io.read_file(path)
    img = tf.image.decode_png(img, channels=3)
    img = tf.image.convert_image_dtype(img, tf.float32)
    img = tf.image.resize(img, [100, 100])
    img = tf.reshape(img, (30000,))
    return img


def preprocess_dataset(ds: tf.data.Dataset, batch_size=30000, cache=True, shuffle_buffer_size=500000):
    if cache:
        if isinstance(cache, str):
            ds = ds.cache(cache)
        else:
            ds = ds.cache()
    ds = ds.shuffle(shuffle_buffer_size)
    ds = ds.batch(batch_size)
    ds = ds.prefetch(buffer_size=tf.data.experimental.AUTOTUNE)
    return ds


if __name__ == '__main__':
    batch_size_ = 30000
    dataset = gen_dataset()
    dataset = preprocess_dataset(dataset, batch_size_)
    nn = ContractiveAutoEncoder(data_shape=(batch_size_,), transition_units=64)

    initialization_inputs = layers.Input(shape=(batch_size_,))
    nn.call(inputs=initialization_inputs)

    nn.compile(optimizer='adagrad', loss=contractive_loss, metrics=['accuracy'])
    nn.fit(dataset, epochs=1000, callbacks=[tf.keras.callbacks.TensorBoard(log_dir=__root_path +
                                                                                   '/intelligence/weights/summary',
                                                                           histogram_freq=2)])
    nn.save_weights(__root_path + '/intelligence/weights/')

Error

Traceback (most recent call last):
  File "/home/jhonas/.pyenv/versions/mp_env/lib/python3.7/site-packages/tensorflow_core/python/eager/execute.py", line 61, in quick_execute
    num_outputs)
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: encoder/Identity:0

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/jhonas/.pyenv/versions/3.7.5/lib/python3.7/contextlib.py", line 130, in __exit__
    self.gen.throw(type, value, traceback)
  File "/home/jhonas/.pyenv/versions/mp_env/lib/python3.7/site-packages/tensorflow_core/python/ops/variable_scope.py", line 2803, in variable_creator_scope
    yield
  File "/home/jhonas/.pyenv/versions/mp_env/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training_v2.py", line 342, in fit
    total_epochs=epochs)
  File "/home/jhonas/.pyenv/versions/mp_env/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training_v2.py", line 128, in run_one_epoch
    batch_outs = execution_function(iterator)
  File "/home/jhonas/.pyenv/versions/mp_env/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training_v2_utils.py", line 98, in execution_function
    distributed_function(input_fn))
  File "/home/jhonas/.pyenv/versions/mp_env/lib/python3.7/site-packages/tensorflow_core/python/eager/def_function.py", line 568, in __call__
    result = self._call(*args, **kwds)
  File "/home/jhonas/.pyenv/versions/mp_env/lib/python3.7/site-packages/tensorflow_core/python/eager/def_function.py", line 632, in _call
    return self._stateless_fn(*args, **kwds)
  File "/home/jhonas/.pyenv/versions/mp_env/lib/python3.7/site-packages/tensorflow_core/python/eager/function.py", line 2363, in __call__
    return graph_function._filtered_call(args, kwargs)  # pylint: disable=protected-access
  File "/home/jhonas/.pyenv/versions/mp_env/lib/python3.7/site-packages/tensorflow_core/python/eager/function.py", line 1611, in _filtered_call
    self.captured_inputs)
  File "/home/jhonas/.pyenv/versions/mp_env/lib/python3.7/site-packages/tensorflow_core/python/eager/function.py", line 1692, in _call_flat
    ctx, args, cancellation_manager=cancellation_manager))
  File "/home/jhonas/.pyenv/versions/mp_env/lib/python3.7/site-packages/tensorflow_core/python/eager/function.py", line 545, in call
    ctx=ctx)
  File "/home/jhonas/.pyenv/versions/mp_env/lib/python3.7/site-packages/tensorflow_core/python/eager/execute.py", line 75, in quick_execute
    "tensors, but found {}".format(keras_symbolic_tensors))
tensorflow.python.eager.core._SymbolicException: Inputs to eager execution function cannot be Keras symbolic tensors, but found [<tf.Tensor 'encoder/Identity:0' shape=(None, 64) dtype=float32>]

Process finished with exit code 1

Thanks for the help!

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.