Fix TypeError in Keras class - how to cast Keras.Sequential to Layer class so it can be part of a Keras.Model instance

Viewed 41

I have the following code, and I am getting a TypeError. My guess is that I am making a Keras.Model part of a, well, Keras.Model when I should have been using Layer instead. Long story short, how can I cast the Keras.Sequential object that mlp returns so that when I construct an instance of SumNet, I don't get:

raise TypeError('The added layer must be '
TypeError: The added layer must be an instance of class Layer. Found: input_1 Placeholder FLOAT32(<tile.Value SymbolicDim UINT64()>, 5)
 :

EDIT: It needs to be a Keras API-only way due to the answer of this question. Perhaps, the function mlp needs to be rewritten so it returns a type Layer not Model somehow.

The code is here:

def mlp(size_in, size_out, act=layers.ReLU):
    return keras.Sequential([layers.Input(shape=(size_in,)),
                             layers.Dense(hidden, name='layer1'),
                             act(),
                             layers.Dense(hidden, name='layer2'),
                             act(),
                             layers.Dense(hidden, name='layer3'),
                             act(),
                             layers.Dense(size_out, name='layer4')])


class SumNet(keras.Model):

    def __init__(self):
        super(SumNet, self).__init__()

        ########################################################
        # The same inductive bias as above!
        self.g = mlp(5, 1)
        self.f = mlp(1, 1)

    def call(self, x):
        y_i = self.g(x)[:, :, 0]
        y = keras.backend.sum(y_i, axis=1, keepdims=True) / y_i.shape[1]
        z = self.f(y)
        return z[:, 0]
1 Answers

After much discussion with AloneTogether I figured out a way to rewrite the mlp function so that it plays nice with the subclassed model. Apparently, the Sequential module does not cast well.

Here is the rewritten function:

def mlp2(size_in, size_out):
    hidden = 128
    inputs = keras.Input(shape=(size_in,))
    x = keras.layers.Dense(hidden, name='layer1', activation='relu')(inputs)
    x = keras.layers.Dense(hidden, name='layer2', activation='relu')(x)
    x = keras.layers.Dense(hidden, name='layer3', activation='relu')(x)
    outputs = keras.layers.Dense(size_out, name='layer4', activation='relu')(x)
    m = keras.Model(inputs, outputs)
    return m
Related