Search code examples
tensorflowsequential

Model.predict tensorflow shape is read incorrectly


I started making a sequential network using tensorflow for food classification. When I created the simplest model I faced a following issue: model.predict(images[99]) was giving me an issue : Input 0 of layer "dense_2" is incompatible with the layer: expected axis -1 of input shape to have value 4096, but received input with shape (32, 64). It happened even though images[99].shape 99

images is a data, where every element of the list is an image with one channel. images.shape (10099, 64, 64)

Model: `

model = keras.Sequential([
    keras.layers.Flatten(input_shape=(64,64)),
    keras.layers.Dense(4096, activation=tf.nn.relu),

    
    keras.layers.Dense(101, activation=tf.nn.softmax)

])
model.compile(optimizer='adam',
loss = tf.keras.losses.MeanSquaredError(),
metrics = \['accuracy'\])


model.fit(images_tr, categories_tr, epochs=2)

it also looks absurd to me because when I try: model.predict(np.zeros((64, 64))` I get the same issue

Also when I do evaluation model.evaluate(images) it works perfectly fine.

I have tried to change version of tensorflow from 2.9.0 to 2.2.2, that didn't help.


Solution

  • that is because it selected one from the received value shape and the smallest that can be filled is 32, you can do something as this for creating a flexible layer the shape is by your conditions.

    Sample: You may calculate the input shape for the target layer as in the sample.

    import tensorflow as tf
    
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""
    : Variables
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""
    start = 3
    limit = 12291
    delta = 3
    
    # Create DATA
    sample = tf.range( start, limit, delta )
    sample = tf.cast( sample, dtype=tf.int64 ).numpy()
    sample = tf.constant( [sample, sample], shape=( 2, 4096, 1 ) )
    
    label = tf.constant([[0.2, 0.8, 0.8], [0.0, 0.0, 0.8]], dtype=tf.float32)
    
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""
    : Class / Functions
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""
    class MyDenseLayer(tf.keras.layers.Layer):
        def __init__(self, num_outputs):
            super(MyDenseLayer, self).__init__()
            self.num_outputs = num_outputs
    
        def build(self, input_shape):
            self.kernel = self.add_weight("kernel",
            shape=[int(input_shape[-1]),
            self.num_outputs])                      # (4096, 1)
    
        def call(self, inputs):
            temp = tf.matmul(inputs, self.kernel)
            return temp
    
    input_layer = tf.keras.layers.InputLayer(input_shape=( int(sample.shape[-2] / 64), 64, 1 ))
    layer_01 = MyDenseLayer(3)
            
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""
    : Model Initialize
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""
    model = tf.keras.models.Sequential([
        input_layer,
        tf.keras.layers.Flatten(),
        tf.keras.layers.Dense(36, activation='relu'),
        layer_01,
    ])
    
    model.summary()
    
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""
    : DataSet
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""
    dataset = tf.data.Dataset.from_tensor_slices((tf.constant(tf.cast(sample, dtype=tf.int64), shape=(2, 1, 64, 64), dtype=tf.int64),tf.constant(label, shape=(2, 3, 1), dtype=tf.float32)))
    
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""
    : Optimizer
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""
    optimizer = tf.keras.optimizers.Nadam(
        learning_rate=0.00001, beta_1=0.9, beta_2=0.999, epsilon=1e-07,
        name='Nadam'
    )
    
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""
    : Loss Fn
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""                               
    lossfn = tf.keras.losses.BinaryCrossentropy(
        from_logits=False,
        label_smoothing=0.0,
        axis=-1,
        reduction=tf.keras.losses.Reduction.AUTO,
        name='binary_crossentropy'
    )
    
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""
    : Model Summary
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""
    model.compile(optimizer=optimizer, loss=lossfn, metrics=['accuracy'])
    
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""
    : Training
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""
    history = model.fit( dataset, batch_size=10, epochs=5 )
    
    
    predictions = model.predict(tf.constant(sample[1,:,:], shape=(1, int(sample.shape[-2] / 64), 64, 1)))
    print( predictions )
    

    Output: 3 dots controls rotor communication wireless.

    Epoch 1/10000
    2/2 [==============================] - 1s 4ms/step - loss: 10.8326 - accuracy: 0.0000e+00
    Epoch 2/10000
    2/2 [==============================] - 0s 5ms/step - loss: 10.8326 - accuracy: 0.0000e+00
    [[ 0.0, 1.0, 0.8 ]]