I want to use a classification model inside another model as layer, since I thought that keras models can be used as layers also. This is the code of the first model:
cencoder_inputs = keras.layers.Input(shape=[pad_len], dtype=np.int32)
ccondi_input = keras.layers.Input(shape=[1], dtype=np.int32)
ccondi_layer = tf.keras.layers.concatenate([cencoder_inputs, ccondi_input], axis=1)
cembeddings = keras.layers.Embedding(vocab_size, 4)
cencoder_embeddings = cembeddings(ccondi_layer)
clstm = keras.layers.LSTM(128)(cencoder_embeddings)
cout_layer = keras.layers.Dense(16, activation="softmax")(clstm)
classification_model = keras.Model(inputs=[cencoder_inputs, ccondi_input], outputs=[cout_layer])
classification_model.compile(optimizer="Nadam", loss="sparse_categorical_crossentropy", metrics=["accuracy"], experimental_run_tf_function=False)
I train this model, save and reload it as class_model and set trainable=False
This is the code of my model, which should use the model above as layer:
encoder_inputs = keras.layers.Input(shape=[pad_len], dtype=np.int32)
decoder_inputs = keras.layers.Input(shape=[pad_len], dtype=np.int32)
condi_input = keras.layers.Input(shape=[1], dtype=np.int32)
class_layer = class_model((encoder_inputs, condi_input))
#Thats how I use the class model. Compilation goes fine so far
class_pred_layer = keras.layers.Lambda(lambda x: tf.reshape(tf.cast(tf.keras.backend.argmax(x, axis=1), dtype=tf.int32),shape=(tf.shape(encoder_inputs)[0],1)))(class_layer)
# Lambda and reshape layer, so I get 1 prediction per batch as integer
condi_layer = tf.keras.layers.concatenate([encoder_inputs, condi_input, class_pred_layer], axis=1)
embeddings = keras.layers.Embedding(vocab_size, 2)
encoder_embeddings = embeddings(condi_layer)
decoder_embeddings = embeddings(decoder_inputs)
encoder_1 = keras.layers.LSTM(64, return_sequences=True, return_state=True)
encoder_lstm_bidirectional_1 = keras.layers.Bidirectional(encoder_1)
encoder_output, state_h1, state_c1, state_h2, state_c2 = encoder_lstm_bidirectional_1(encoder_embeddings)
encoder_state = [Concatenate()([state_h1, state_h2]), Concatenate()([state_c1, state_c2])]
decoder_lstm = keras.layers.LSTM(64*2, return_sequences=True, return_state=True, name="decoder_lstm")
print(encoder_output.shape)
decoder_outputs,decoder_fwd_state, decoder_back_state = decoder_lstm(decoder_embeddings,initial_state=encoder_state)
print(decoder_outputs.shape)
attn_layer = AttentionLayer(name="attention_layer")
attn_out, attn_states = attn_layer([encoder_output, decoder_outputs])
decoder_concat_input = Concatenate(axis=-1, name="decoder_concat_layer")([decoder_outputs, attn_out])
decoder_dense_out = keras.layers.TimeDistributed(keras.layers.Dense(vocab_size, activation="softmax"))
decoder_outputs = decoder_dense_out(decoder_concat_input)
model = keras.Model(inputs=[encoder_inputs, decoder_inputs, condi_input], outputs=[decoder_outputs])
When I execute model.fit(), I receive the following error:
Inputs to eager execution function cannot be Keras symbolic tensors, but found [<tf.Tensor 'input_21:0' shape=(None, 35) dtype=int32>]
I thought trained models could be used easily as layers, what am I doing wrong? I also already looked into this Post but it didnt help me either. Thanks for your help!
Ok, i will do 2 things: (1) I will give you an example that works where i had to do call a model inside an other model, and (2) try to give you a hint on what could be your problem here ( i cant really undertand the code but i had in the past the same error )
1. This is an example of a model that use an other model as an hidden layer:
def model_test(input_shape, sub_model):
inputs = Input(input_shape)
eblock_1_1 = dense_convolve(inputs, n_filters=growth_rate)
eblock_1_2 = dense_convolve(eblock_1_1, n_filters=growth_rate);
dblock_1_1 = dense_convolve(eblock_1_2, n_filters=growth_rate);
dblock_1_2 = dense_convolve(dblock_1_1, n_filters=growth_rate);
final_convolution = Conv3D(2, (1, 1, 1), padding='same', activation='relu')(dblock_1_2)
intermedio = sub_model(final_convolution)
layer = LeakyReLU(alpha=0.3)(intermedio)
model = Model(inputs=inputs, outputs=layer)
return model
I call it like this:
with strategy.scope():
sub_model = tf.keras.models.load_model('link_to_the_model')
sub_model.trainable = False
model = model_test(INPUT_SIZE, sub_model)
model.compile(optimizer=Adam(lr=0.1),
loss=tf.keras.losses.MeanSquaredError(),
metrics=None)
I just tested this on google colab with keras.
If the problem is the call of the model maybe try to do what i did, pass the model as a parameter and call it inside with a layer as argument and use it as a simple layer
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.