0

I am writing a custom layer using Keras that returns a tensors of zeros the first three times it is invoked and does nothing the other times. The code is the following

class MyLayer(tf.keras.layers.Layer):

    def __init__(self, **kwargs):
        super(MyLayer, self).__init__(**kwargs)
        self.__iteration = 0
        self.__returning_zeros = None

    def build(self, input_shape):
        self.__returning_zeros = tf.zeros(shape=input_shape, dtype=tf.float32)

    def call(self, inputs):
        self.__iteration += 1

        if self.__iteration <= 3:
            return self.__returning_zeros
        else:
            return inputs

Unfortunately if I try to build a model using this layer like this

def build_model(input_shape, num_classes):
    input_layer = keras.Input(shape=input_shape, name='input')
    conv1 = layers.Conv2D(32, kernel_size=(3, 3), activation="relu", name='conv1')(input_layer)
    maxpool1 = layers.MaxPooling2D(pool_size=(2, 2), name='maxpool1')(conv1)
    conv2 = layers.Conv2D(64, kernel_size=(3, 3), activation="relu", name='conv2')(maxpool1)
    mylayer = MyLayer()(conv2)
    maxpool2 = layers.MaxPooling2D(pool_size=(2, 2), name='maxpool2')(mylayer)
    flatten = layers.Flatten(name='flatten')(maxpool2)
    dropout = layers.Dropout(0.5, name='dropout')(flatten)
    dense = layers.Dense(num_classes, activation="softmax", name='dense')(dropout)

    return keras.Model(inputs=(input_layer,), outputs=dense)

I get the following error message

  File "customlayerkeras.py", line 25, in build
    self.__returning_zeros = tf.zeros(shape=input_shape, dtype=tf.float32)
ValueError: Cannot convert a partially known TensorShape (None, 13, 13, 64) to a Tensor.

Where it seems that, despite using the build function as suggested in the documentation I am not able to retrieve the correct shape of the input. How can I fix this problem?

EDIT: I was complicating the problem without thinking, the best solution is to just multiply the inputs per zero like this

def call(self, inputs):
        self.__iteration += 1

        if self.__iteration <= 3:
            return inputs*0
        else:
            return inputs
0

1 Answer 1

1

Pretty sure you don't need the dimension of the batch, so you can do something like this:

class MyLayer(tf.keras.layers.Layer):

    def __init__(self, **kwargs):
        super(MyLayer, self).__init__(**kwargs)
        self.__iteration = 0
        self.__returning_zeros = None

    def build(self, input_shape):
        self.__returning_zeros = tf.zeros(shape=input_shape[1:], dtype=tf.float32)

    def call(self, inputs):
        self.__iteration += 1

        if self.__iteration <= 3:
            return inputs * self.__returning_zeros
            # or like return tf.repeat(self.__returning_zeros[None,...], tf.shape(inputs)[0], axis=0)
        else:
            return inputs
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.