Search code examples
pythontensorflowkeraslayer

How to implement a numpy equation in the call of a tensorflow layer for a tensorflow model (Cannot convert a symbolic tf.Tensor to a numpy array)


I have this layer class in tensorflow where i want to implement a specific equation in numpy for the return in the call function. I have this following custom layer:

class PhysicalLayer(keras.layers.Layer):
    def __init__(self, units=32):
        super(PhysicalLayer, self).__init__()
        self.units = units

    def build(self, input_shape):
        self.w = self.add_weight(
            shape=(input_shape[-1], self.units),
            initializer="random_normal",
            trainable=True,
        )
        self.b = self.add_weight(
            shape=(self.units,), initializer="random_normal", trainable=True
        )

    def call(self, inputs):
        rotationSpeedSquare = tf.math.square(rotationSpeed)
        maximumVibration = tf.convert_to_tensor(np.max(inputs))
        stiff = rotationSpeedSquare/maximumVibration
        stiff.astype('float32')
        return tf.matmul(stiff, self.w) + self.b

This layer is then implement in a model in the following way:

class model(tf.keras.Model):

    def __init__(self, num_classes=50):
        super(model, self).__init__()
        self.dense1  = tf.keras.layers.Dense(num_classes, activation=tf.nn.relu)
        self.physical = PhysicalLayer()
        self.dense2  = tf.keras.layers.Dense(64, activation=tf.nn.relu)
        self.dense3  = tf.keras.layers.Dense(32, activation=tf.nn.relu)
        self.dense4  = tf.keras.layers.Dense(1, activation=tf.nn.relu)


    def call(self, inputs):
        x = self.dense1(inputs)
        x = self.physical(x)
        x = self.dense2(x)
        x = self.dense3(x)
        
        return self.dense4(x)

One of my first concern is if I'm doing this model class correctly as i just learnt how to do it. By trying to fit this model with the training set (which are numpy array, dtype = float32 and size is (72367, 50))

model = model()
model.compile(optimizer='adam', loss='mae', metrics=[tf.keras.metrics.RootMeanSquaredError()])
model.fit(a, b, batch_size=32, epochs=2, verbose=2)

I obtain the following error:

NotImplementedError: Cannot convert a symbolic tf.Tensor (model_18/dense_72/Relu:0) to a numpy array. This error may indicate that you're trying to pass a Tensor to a NumPy call, which is not supported.

Thanks


Solution

  • Use tf.math.reduce_max to get the maximum of a tensor:

        def call(self, inputs):
            rotationSpeedSquare = tf.math.square(rotationSpeed)
            maximumVibration = tf.math.reduce_max(inputs, axis=1, keepdims=True)
    
            stiff = rotationSpeedSquare / maximumVibration
            return tf.matmul(stiff, self.w) + self.b