Burak
Burak

Reputation: 23

Keras Lambda layer to perform a maximum and output in (?, 1) shape

I have two prediction models; a deterministic and a deep learning network. I'd like to ensamble the two models where the deterministic one provides the basis for the prediction and deep learning makes the adjustment needed. It's a regression problem with a float output.

The last layer of deep learning network is:

Dense(1, activation='linear',kernel_initializer=init) (previous_layer_output)

So its output shape is just (?, 1). Deterministic model's output shape must be identical for my merge layer to work.

Deterministic model takes the input layer which has the shape (?, 10, 1) and should take the maximum value of the 10 values and output in (?, 1) shape.

The code below which takes 10 slices and performs a Maximum() over them works perfectly well. However it looks cumbersome and I don't think this is the right way of doing it.

#print(x_test_scaled.shape[1:]) = (10, 1)

Det_Guess1 = Lambda(lambda x: x[:,0], input_shape=x_test_scaled.shape[1:], output_shape=(1,)) (Input_Layer)
Det_Guess2 = Lambda(lambda x: x[:,1], input_shape=x_test_scaled.shape[1:], output_shape=(1,)) (Input_Layer)
Det_Guess3 = Lambda(lambda x: x[:,2], input_shape=x_test_scaled.shape[1:], output_shape=(1,)) (Input_Layer)
Det_Guess4 = Lambda(lambda x: x[:,3], input_shape=x_test_scaled.shape[1:], output_shape=(1,)) (Input_Layer)
Det_Guess5 = Lambda(lambda x: x[:,4], input_shape=x_test_scaled.shape[1:], output_shape=(1,)) (Input_Layer)
Det_Guess6 = Lambda(lambda x: x[:,5], input_shape=x_test_scaled.shape[1:], output_shape=(1,)) (Input_Layer)
Det_Guess7 = Lambda(lambda x: x[:,6], input_shape=x_test_scaled.shape[1:], output_shape=(1,)) (Input_Layer)
Det_Guess8 = Lambda(lambda x: x[:,7], input_shape=x_test_scaled.shape[1:], output_shape=(1,)) (Input_Layer)
Det_Guess9 = Lambda(lambda x: x[:,8], input_shape=x_test_scaled.shape[1:], output_shape=(1,)) (Input_Layer)
Det_Guess10 = Lambda(lambda x: x[:,9], input_shape=x_test_scaled.shape[1:], output_shape=(1,)) (Input_Layer)

Det_Guess = Maximum()([Det_Guess1, Det_Guess2, Det_Guess3, Det_Guess4,
                       Det_Guess5, Det_Guess6, Det_Guess7, Det_Guess8,
                       Det_Guess9, Det_Guess10])

#print(Det_Guess.shape) = (?, 1)

Simpler Lambda function below looks neat but doesn't work as its output is in scalar shape;

def find_max(x):
    K.max(x)
    return K.max(x)

Det_Guess= Lambda(find_max, input_shape=x_test_scaled.shape[1:], output_shape=(1,)) (Input_Layer)

# print(Det_Guess.shape) = ()

I tried reshaping, adding dimensions to this simpler lambda function but couldn't manage to keep the (?) sample dimension, I always end up losing it and output is never in (?, 1) shape.

How can I build a neat looking layer with the desired operation performed which outputs in (?, 1) shape?

Upvotes: 1

Views: 1204

Answers (1)

Marco Cerliani
Marco Cerliani

Reputation: 22031

To solve this, you can try in this way:

inp = Input((10,1))
Det_Guess= Lambda(lambda x: tf.reduce_max(x, axis=1))(inp)
model = Model(inp, Det_Guess)
model.summary()

Layer (type)                 Output Shape              Param #   
=================================================================
input_4 (InputLayer)         [(None, 10, 1)]           0         
_________________________________________________________________
lambda_7 (Lambda)            (None, 1)                 0         
=================================================================

X = np.random.randint(0,1000, (100,10,1))
model.predict(X)

Upvotes: 2

Related Questions