Home > other >  How to rewrite this sequential API tensorflow model using functional API?
How to rewrite this sequential API tensorflow model using functional API?

Time:11-14

I am trying to rewrite my working sequential model using the functional API. This is my sequential model:

num_classes = 3
# Define a simple sequential model
def create_model():
  model = Sequential([
    layers.experimental.preprocessing.Rescaling(1./255, input_shape=(img_height, img_width, 3)),
    layers.Conv2D(16, 3, padding='same', activation='relu'),
    layers.MaxPooling2D(),
    layers.Conv2D(32, 3, padding='same', activation='relu'),
    layers.MaxPooling2D(),
    layers.Conv2D(64, 3, padding='same', activation='relu'),
    layers.MaxPooling2D(),
    layers.Flatten(),
    layers.Dense(128, activation='relu'),
    layers.Dense(num_classes)
  ])
  
  model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])
  
  return model
  
# Create a basic model instance
model = create_model()

# Display the model's architecture
model.summary()

Model summary of sequential model:

Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
rescaling_2 (Rescaling)      (None, 180, 180, 3)       0
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 180, 180, 16)      448
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 90, 90, 16)        0
_________________________________________________________________
conv2d_4 (Conv2D)            (None, 90, 90, 32)        4640
_________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, 45, 45, 32)        0
_________________________________________________________________
conv2d_5 (Conv2D)            (None, 45, 45, 64)        18496
_________________________________________________________________
max_pooling2d_5 (MaxPooling2 (None, 22, 22, 64)        0
_________________________________________________________________
flatten_1 (Flatten)          (None, 30976)             0
_________________________________________________________________
dense_2 (Dense)              (None, 128)               3965056
_________________________________________________________________
dense_3 (Dense)              (None, 3)                 387
=================================================================
Total params: 3,989,027
Trainable params: 3,989,027
Non-trainable params: 0
_________________________________________________________________

This is my attempt at rewriting it as a functional model.

num_classes = 3
input_shape=(img_height, img_width, 3)
from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, Flatten, Dense
from tensorflow.keras.models import Model

def create_model():
  model_input = Input(shape=input_shape) 
  # how to include preprocessing layer that I have in my sequential model: layers.experimental.preprocessing.Rescaling(1./255, input_shape=(img_height, img_width, 3)),
  x = Conv2D(16, 3, activation='relu',padding='same')(model_input) 
  x = MaxPooling2D()(x) 
  x = Conv2D(32, 3, activation='relu',padding='same')(model_input) 
  x = MaxPooling2D()(x) 
  x = Conv2D(64, 3, activation='relu',padding='same')(model_input) 
  x = MaxPooling2D()(x) 
  x = Flatten()(x)
  outputs = Dense(num_classes, activation='relu')(x)

  model = Model(model_input, x,)

  model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

  return model

# Create a basic model instance
model = create_model()
 
# Display the model's architecture
model.summary()

keras.utils.plot_model(model, "model_with_shape_info.png", show_shapes=True)

Model summary of functional model:

_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 input_10 (InputLayer)       [(None, 180, 180, 3)]     0         
                                                                 
 conv2d_23 (Conv2D)          (None, 180, 180, 64)      1792      
                                                                 
 max_pooling2d_23 (MaxPoolin  (None, 90, 90, 64)       0         
 g2D)                                                            
                                                                 
 flatten_4 (Flatten)         (None, 518400)            0         
                                                                 
=================================================================
Total params: 1,792
Trainable params: 1,792
Non-trainable params: 0
_________________________________________________________________

I tried to go line by line in my sequential model to determine what layers to include in my functional model. Can you please help me understand how to rewrite my sequential model correctly as a functional model? Thank you for your help.

EDIT: Trying to compile and train functional model.

model2.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

epochs=10
history = model2.fit(
  train_ds,
  validation_data=val_ds,
  epochs=epochs
)

CodePudding user response:

You seem to be missing some layers and not connecting them correctly. Try this and both models should have the same number of layers and training parameters:

import tensorflow as tf

model1 = tf.keras.Sequential([
  tf.keras.layers.Rescaling(1./255, input_shape=(180, 180, 3)),
  tf.keras.layers.Conv2D(16, 3, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(),
  tf.keras.layers.Conv2D(32, 3, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(),
  tf.keras.layers.Conv2D(64, 3, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(),
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dense(3)
])

model_input = tf.keras.layers.Input(shape=(180, 180, 3)) 
x = tf.keras.layers.Rescaling(1./255)(model_input) 
x = tf.keras.layers.Conv2D(16, 3, activation='relu',padding='same')(x)
x = tf.keras.layers.MaxPooling2D()(x) 
x = tf.keras.layers.Conv2D(32, 3, activation='relu',padding='same')(x) 
x = tf.keras.layers.MaxPooling2D()(x) 
x = tf.keras.layers.Conv2D(64, 3, activation='relu',padding='same')(x) 
x = tf.keras.layers.MaxPooling2D()(x) 
x = tf.keras.layers.Flatten()(x)
x = tf.keras.layers.Dense(128, activation='relu')(x)
outputs = tf.keras.layers.Dense(3)(x)

model2 = tf.keras.Model(model_input, outputs)

print(model1.summary())

print(model2.summary())
  • Related