automl icon indicating copy to clipboard operation
automl copied to clipboard

EfficientDetV1 ignores reused scope

Open lorenzovaquero opened this issue 3 years ago • 0 comments

First of all, thanks a lot for all your work!

The problem I encounter is that EfficientDetV1 ignores the scope in which it is defined when attempting to reuse it. It goes out of the scope and creates new variables:

import tensorflow as tf
from efficientdet_arch import efficientdet

input_tensor = tf.random_normal(shape=[10, 896, 896, 3])  # Our image batch

# We define the first instance, which should create the variables (and it does)
with tf.compat.v1.variable_scope('siamese', reuse=tf.compat.v1.AUTO_REUSE) as scope:
  endpoints = efficientdet(features=input_tensor, model_name='efficientdet-d0', image_size=896)

defined_vars = sorted([v for v in tf.trainable_variables()], key=lambda x: x.name)
len(defined_vars)  # 493

# We define the second instance, which should NOT create more variables (but it creates most of them again)
with tf.compat.v1.variable_scope('siamese', reuse=tf.compat.v1.AUTO_REUSE) as scope:
  endpoints = efficientdet(features=input_tensor, model_name='efficientdet-d0', image_size=896)

defined_vars = sorted([v for v in tf.trainable_variables()], key=lambda x: x.name)
len(defined_vars)  # 878

print(defined_vars[84])   # <tf.Variable 'siamese/efficientnet-b0/blocks_0/conv2d/kernel:0' shape=(1, 1, 32, 16) dtype=float32>
print(defined_vars[553])  # <tf.Variable 'siamese_1/efficientnet-b0/blocks_0/conv2d/kernel:0' shape=(1, 1, 32, 16) dtype=float32>

Notice how the first call to len() outputs 493 while the second one outputs 878.

The expected behavior should be something like this:

import tensorflow as tf
from efficientdet_arch import efficientdet

input_tensor = tf.random_normal(shape=[10, 896, 896, 3])  # Our image batch

# We define the first instance, which creates the variables
with tf.compat.v1.variable_scope('siamese', reuse=tf.compat.v1.AUTO_REUSE) as scope:
  endpoints = tf.layers.conv2d(input_tensor, 3, [2, 2], padding='SAME')

defined_vars = sorted([v for v in tf.trainable_variables()], key=lambda x: x.name)
len(defined_vars)  # 2

# We define the second instance, which reuses previous variables
with tf.compat.v1.variable_scope('siamese', reuse=tf.compat.v1.AUTO_REUSE) as scope:
  endpoints = endpoints = tf.layers.conv2d(input_tensor, 3, [2, 2], padding='SAME')

defined_vars = sorted([v for v in tf.trainable_variables()], key=lambda x: x.name)
len(defined_vars)  # 2

print(defined_vars[0])   # <tf.Variable 'siamese/conv2d/bias:0' shape=(3,) dtype=float32_ref>dtype=float32>

Where both len() output the same number (2 in this case).

Oddly enough, despite following a very similar structure, this issue, while it also happens with backbone.efficientnet_builder.build_model_base() (the one in this repository), it does not happen with the efficientnet_builder.build_model_base() found in tensorflow/tpu

I am using TensorFlow 1.14.0, and the most recent version of the master branch of this repository.

lorenzovaquero avatar Aug 31 '21 18:08 lorenzovaquero