Home > Mobile >  [tensorflow]How do I wrap a sequence of code in to by subclassing the model class ( tf.keras.Model)
[tensorflow]How do I wrap a sequence of code in to by subclassing the model class ( tf.keras.Model)

Time:10-19

I have code sequence as below. There i tried to wrap that code by subclassing using tensorflow model class. However i get following errors. Any help is apprated to solve these errors. Thank you in advance

code sequence

input_tensor = Input(shape=(720, 540, 2))
base_model = ResNet50V2(input_tensor=input_tensor, include_top=False, weights=None, classes=4)
x = base_model.output
x = GlobalAveragePooling2D()(x)
predictions = Dense(4, activation= 'sigmoid')(x)
model = Model(inputs = base_model.input, outputs = predictions)

Attemted model class

class StreoModel(tf.keras.Model):

def __init__(self):
    super(StreoModel, self).__init__()
    self.dense1 = Dense(4, activation='sigmoid')

def call(self, inputs):
    input_tensor = Input(shape=(720, 540, 2))
    x = ResNet50V2(input_tensor=input_tensor, include_top=False, weights=None, classes=4)
    x= x.output
    x = GlobalAveragePooling2D()(x)
    predictions = self.dense1(x)
    return predictions

Error log:

TypeError: Cannot convert a symbolic Keras input/output to a numpy array. This error may indicate that you're trying to pass a symbolic value to a NumPy call, which is not supported. Or, you may be trying to pass Keras symbolic inputs/outputs to a TF API that does not register dispatching, preventing Keras from automatically converting the API call to a lambda layer in the Functional Model.

CodePudding user response:

I think the problem lies in the way you pass data to your ResNet50V2. Try defining a simple Subclassing model like this:

class StreoModel(tf.keras.Model):

  def __init__(self):
    super(StreoModel, self).__init__()
    self.resnet_v2 = tf.keras.applications.resnet_v2.ResNet50V2(include_top=False, weights=None, classes=4, input_shape=(720, 540, 2))
    self.resnet_v2.trainable = True 
    x= self.resnet_v2.output
    x = tf.keras.layers.GlobalAveragePooling2D()(x)
    output = tf.keras.layers.Dense(4, activation='softmax')(x)
    self.model = tf.keras.Model(self.resnet_v2.input, output)

Note that I removed your input layer and add an input shape to ResNet50V2. According to the docs, you should specify the input_shape if include_top=False. I also changed your output activation function to softmax, since you are dealing with 4 classes.

And then using it:

sm = StreoModel()
sm.model(np.random.random((1, 720, 540, 2)))
# <tf.Tensor: shape=(1, 4), dtype=float32, numpy=array([[0.25427648, 0.25267935, 0.23970276, 0.2533414 ]], dtype=float32)>

If you want to define your Model with a call method, then you can do it like this:

class StreoModel(tf.keras.Model):

  def __init__(self):
      super(StreoModel, self).__init__()
      self.dense = tf.keras.layers.Dense(4, activation='softmax')
      self.resnet = tf.keras.applications.resnet_v2.ResNet50V2(include_top=False, weights=None, classes=4, input_shape=(720, 540, 2))
      self.pooling = tf.keras.layers.GlobalAveragePooling2D()

  def call(self, inputs):
      x = self.resnet(inputs)
      x = self.pooling(x)
      predictions = self.dense(x)
      return predictions

And use it like this:

sm = StreoModel()
sm(np.random.random((1, 720, 540, 2)))
# <tf.Tensor: shape=(1, 4), dtype=float32, numpy=array([[0.25062975, 0.2428435 , 0.25178066, 0.25474608]], dtype=float32)>
  • Related