calmiLovesAI / Basic_CNNs_TensorFlow2

A tensorflow2 implementation of some basic CNNs(MobileNetV1/V2/V3, EfficientNet, ResNeXt, InceptionV4, InceptionResNetV1/V2, SENet, SqueezeNet, DenseNet, ShuffleNetV2, ResNet).
MIT License
526 stars 178 forks source link

[DenseBlock] ValueError: tf.function-decorated function tried to create variables on non-first call. #13

Closed taffy128s closed 4 years ago

taffy128s commented 4 years ago

Hello!

Sorry to bother you.

It seems that creating layers inside 'call' function in a custom layer inheriting from tf.keras.layers.Layer is not proper.

The problem happens when I use your codes as libraries and then I do model.fit with model checkpoint call-back function.

Also, custom layers inheriting from tf.keras.layers.Layer should include get_config as well, or some errors will happen while saving, too.

I've fixed them like below:

class DenseBlock(tf.keras.layers.Layer):
    def __init__(self, num_layers, growth_rate, drop_rate, name=None):
        super(DenseBlock, self).__init__(name=name)
        self.num_layers = num_layers
        self.growth_rate = growth_rate
        self.drop_rate = drop_rate
        self.features_list = []
        self.model_list = []
        for i in range(0, self.num_layers):
            tmp = BottleNeck(growth_rate=self.growth_rate, drop_rate=self.drop_rate)
            self.model_list.append(tmp)

    # def _make_layer(self, x, training):
    #     y = BottleNeck(growth_rate=self.growth_rate, drop_rate=self.drop_rate)(x, training=training)
    #     self.features_list.append(y)
    #     y = tf.concat(self.features_list, axis=-1)
    #     return y

    def call(self, inputs, training=None, **kwargs):
        self.features_list.append(inputs)
        x = inputs
        # x = self._make_layer(inputs, training=training)
        for i in range(0, self.num_layers):
            # x = self._make_layer(x, training=training)
            x = self.model_list[i](x, training=training)
            self.features_list.append(x)
            x = tf.concat(self.features_list, axis=-1)
        self.features_list.clear()
        return x

    def get_config(self):
        config = super(DenseBlock, self).get_config()
        config.update({'growth_rate': self.growth_rate,
                       'drop_rate': self.drop_rate,
                       'num_layers': self.num_layers})
        return config

Please fix them if you are free! Thank you!

calmiLovesAI commented 4 years ago

I have fixed the bug.