pythontensorflowkeras

Having trouble when initializing Input layer with constant value


I have three Input layers in my model, and 'input3' is set as constant value. Then I input 'input3' to Embedding layer , get the result 'lookup_table' and then do some other operations.

But when I use model.summary() to observe my model and the training parameters, I find that the Input3 layer and the Embedding layer are not added to the model, and I think the parameters of Embedding layer will not be trained.

The code:

import numpy as np
from keras.models import Model
from keras.layers import*
import keras.backend as K


np_constant = np.array([[1,2,3],
                        [4,5,6],
                        [7,8,9]])

def NN():
    input1 = Input(batch_shape=(None,1),name='input1',dtype='int32')
    input2 = Input(batch_shape=(None,1),name='input2',dtype='int32')
    # constant_tensor = K.constant(np_constant)
    input3 = Input(tensor=K.constant(np_constant),batch_shape=(3,3),dtype='int32',name='constant_input_3')
    embedding = Embedding(input_dim=10,output_dim=5,input_length=3)
    lookup_table = embedding(input3)
    lookup_table = Lambda(lambda x: K.reshape(x, (-1,15)))(lookup_table)

    output1 = Lambda(lambda x: K.gather(lookup_table, K.cast(x, dtype='int32')))(input1)
    output2 = Lambda(lambda x: K.gather(lookup_table, K.cast(x, dtype='int32')))(input2)

    # Merge branches
    output = Concatenate(axis=1)([output1, output2])
    # Process merged branch
    output = Dense(units=2
                   , activation='softmax'
                   )(output)

    model = Model([input1, input2, input3], outputs=output)
    return model

model = NN()
model.summary()
in_1 = np.array([1,2,1])
in_2 = np.array([1,0,1])
model.compile()  # just for example
model.fit([in_1,in_2])
The model summary

Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input1 (InputLayer)             (None, 1)            0                                            
__________________________________________________________________________________________________
input2 (InputLayer)             (None, 1)            0                                            
__________________________________________________________________________________________________
lambda_2 (Lambda)               (None, 1, 15)        0           input1[0][0]                     
__________________________________________________________________________________________________
lambda_3 (Lambda)               (None, 1, 15)        0           input2[0][0]                     
__________________________________________________________________________________________________
concatenate_1 (Concatenate)     (None, 2, 15)        0           lambda_2[0][0]                   
                                                                 lambda_3[0][0]                   
__________________________________________________________________________________________________
dense_1 (Dense)                 (None, 2, 2)         32          concatenate_1[0][0]              
==================================================================================================
Total params: 32
Trainable params: 32
Non-trainable params: 0
__________________________________________________________________________________________________

I have to feed data in the model.fit() function, and the input3 is always constant and the shape of input3 is different from input1 and input2, so I use it in this way. But I have no idea why the Input3 layer and Embedding layer are not added to the model.


Solution

  • I modify my original code, I define a custom function outside the model and pass a list of tensors into a Lambda layer as Anakin suggested. Here is the modified codes.

    import numpy as np
    from keras.models import Model
    from keras.layers import*
    import keras.backend as K
    
    
    np_constant = np.array([[1,2,3],
                            [4,5,6],
                            [7,8,9]])
    
    def look_up(arg):
        in1 = arg[0]
        in2 = arg[1]
        lookup_table = arg[2]
    
        in1 = Lambda(lambda x: K.reshape(x, (-1, )))(in1)
        in2 = Lambda(lambda x: K.reshape(x, (-1, )))(in2)
    
        output1 = Lambda(lambda x: K.gather(lookup_table, K.cast(x, dtype='int32')))(in1)
        output2 = Lambda(lambda x: K.gather(lookup_table, K.cast(x, dtype='int32')))(in2)
        return [output1,output2]
    
    def NN():
        input1 = Input(batch_shape=(None,1),name='input1',dtype='int32')
        input2 = Input(batch_shape=(None,1),name='input2',dtype='int32')
        # constant_tensor = K.constant(np_constant)
        input3 = Input(tensor=K.constant(np_constant),batch_shape=(3,3),dtype='int32',name='constant_input_3')
        lookup_table = Embedding(input_dim=10,output_dim=5,input_length=3)(input3)
        lookup_table = Lambda(lambda x: K.reshape(x, (-1, 15)))(lookup_table)
    
    
        output1 = Lambda(look_up)([input1,input2,lookup_table])[0]
        output2 = Lambda(look_up)([input1,input2,lookup_table])[1]
        # Merge branches
        output = Concatenate(axis=1)([output1, output2])
        # Process merged branch
        output = Dense(units=2
                       , activation='softmax'
                       )(output)
    
        model = Model([input1, input2, input3], outputs=output)
        return model
    
    model = NN()
    model.summary()
    input_1 = np.array([1,2,1])
    input_2 = np.array([1,0,1])
    model.compile()  # just for example
    model.fit([input_1,input_2])
    

    In this way, the Embedding could be added to the model. And input3 is a constant tensor, we don't need to feed it in model.fit() function.

    The model summary
    
    __________________________________________________________________________________________________
    Layer (type)                    Output Shape         Param #     Connected to                     
    ==================================================================================================
    constant_input_3 (InputLayer)   (3, 3)               0                                            
    __________________________________________________________________________________________________
    embedding_1 (Embedding)         (3, 3, 5)            50          constant_input_3[0][0]           
    __________________________________________________________________________________________________
    input1 (InputLayer)             (None, 1)            0                                            
    __________________________________________________________________________________________________
    input2 (InputLayer)             (None, 1)            0                                            
    __________________________________________________________________________________________________
    lambda_1 (Lambda)               (3, 15)              0           embedding_1[0][0]                
    __________________________________________________________________________________________________
    lambda_2 (Lambda)               [(None, 15), (None,  0           input1[0][0]                     
                                                                     input2[0][0]                     
                                                                     lambda_1[0][0]                   
    __________________________________________________________________________________________________
    lambda_11 (Lambda)              [(None, 15), (None,  0           input1[0][0]                     
                                                                     input2[0][0]                     
                                                                     lambda_1[0][0]                   
    __________________________________________________________________________________________________
    concatenate_1 (Concatenate)     (None, 30)           0           lambda_2[0][0]                   
                                                                     lambda_11[0][1]                  
    __________________________________________________________________________________________________
    dense_1 (Dense)                 (None, 2)            62          concatenate_1[0][0]              
    ==================================================================================================
    Total params: 112
    Trainable params: 112
    Non-trainable params: 0
    __________________________________________________________________________________________________