Search code examples
pythontensorflowkeras

How to call TensorFlow model with linspace?


I'm trying to call a TensorFlow model on a linspace but I can't seem to get even a very simple example (based on https://www.tensorflow.org/api_docs/python/tf/keras/Model) to work:

import tensorflow as tf

class FeedForward(tf.keras.Model):
    def __init__(self):
        super().__init__()
        self.dense1 = tf.keras.layers.Dense(4, activation=tf.nn.relu, name='lyr1')
        self.dense2 = tf.keras.layers.Dense(5, activation=tf.nn.softmax, name='lyr2')
    
    def call(self, inputs, training=False):
        x = self.dense1(inputs) # <--- error here
        return self.dense2(x)

model = FeedForward()
batchSize = 2048

preX = tf.linspace(0.0, 10.0, batchSize)
model(preX, training=True)

I get the following error (on the line indicated above):

ValueError: Exception encountered when calling layer "feed_forward_87" (type FeedForward).

Input 0 of layer "lyr1" is incompatible with the layer: expected min_ndim=2, found ndim=1. Full shape received: (2048,)

Call arguments received:
  • inputs=tf.Tensor(shape=(2048,), dtype=float32)
  • training=True

I have tried adding an input layer

import tensorflow as tf

class FeedForward(tf.keras.Model):
    def __init__(self):
        super().__init__()
        self.inLyr = tf.keras.layers.Input(shape=(2048,), name='inp')
        self.dense1 = tf.keras.layers.Dense(4, activation=tf.nn.relu, name='lyr1')
        self.dense2 = tf.keras.layers.Dense(5, activation=tf.nn.softmax, name='lyr2')
    
    def call(self, inputs, training=False):
        x = self.inLyr(inputs) # <---- error here
        x = self.dense1(x)
        return self.dense2(x)

model = FeedForward()
batchSize = 2048

preX = tf.linspace(0.0, 10.0, batchSize)
model(preX, training=True)

But then the error becomes

TypeError: Exception encountered when calling layer "feed_forward_88" (type FeedForward).

'KerasTensor' object is not callable

Call arguments received:
  • inputs=tf.Tensor(shape=(2048,), dtype=float32)
  • training=True

Any help is appreciated.


Solution

  • You do not need an explicit Input layer. You are just missing a dimension. Try using tf.expand_dims to get the required input shape (batch_size, features):

    import tensorflow as tf
    
    class FeedForward(tf.keras.Model):
        def __init__(self):
            super().__init__()
            self.dense1 = tf.keras.layers.Dense(4, activation=tf.nn.relu, name='lyr1')
            self.dense2 = tf.keras.layers.Dense(5, activation=tf.nn.softmax, name='lyr2')
        
        def call(self, inputs, training=False):
            x = self.dense1(inputs)
            return self.dense2(x)
    
    model = FeedForward()
    batchSize = 2048
    
    preX = tf.expand_dims(tf.linspace(0.0, 10.0, batchSize), axis=-1)
    model(preX, training=True)
    
    <tf.Tensor: shape=(2048, 5), dtype=float32, numpy=
    array([[2.0000000e-01, 2.0000000e-01, 2.0000000e-01, 2.0000000e-01,
            2.0000000e-01],
           [2.0061693e-01, 1.9939975e-01, 1.9954492e-01, 2.0115443e-01,
            1.9928394e-01],
           [2.0123295e-01, 1.9879854e-01, 1.9908811e-01, 2.0231272e-01,
            1.9856769e-01],
           ...,
           [4.1859145e-03, 1.6480753e-08, 7.3006660e-08, 9.9581391e-01,
            5.0233933e-09],
           [4.1747764e-03, 1.6337188e-08, 7.2423312e-08, 9.9582505e-01,
            4.9767293e-09],
           [4.1636685e-03, 1.6194873e-08, 7.1844603e-08, 9.9583614e-01,
            4.9305160e-09]], dtype=float32)>
    

    Or with an Input layer:

    class FeedForward(tf.keras.Model):
        def __init__(self):
            super().__init__()
            inputs = tf.keras.layers.Input((1,))
            dense1 = tf.keras.layers.Dense(4, activation=tf.nn.relu, name='lyr1')(inputs)
            dense2 = tf.keras.layers.Dense(5, activation=tf.nn.softmax, name='lyr2')(dense1)
            self.model = tf.keras.Model(inputs, dense2)
        def call(self, inputs, training=False):
            return self.model(inputs)