I am trying my hand at implementing a forecasting algorithm that combines both LSTM and CNN models from this paper. Essentially, the paper proposed a model with three branches: a CNN branch, an LSTM branch, and a merged branch that combines both. The first two branches are only present during training to prevent overfitting and ensure the final model is trained for both CNN and LSTM features. Here is the diagram in the paper (alpha, beta, and gamma in the total loss function are just weight for those particular losses.)
As I understand it, these are similar to the auxiliary branches in the likes of ResNet and Inception model to ensure that every layer is contributing to the model output. I implemented this accordingly:
def construct_lstm_cnn(look_forward, look_back=30):
cnn = construct_cnn(look_forward, fc=False)
cnn_flatten = Flatten()(cnn.output)
lstm = construct_lstm(look_forward, look_back, 2, fc=False)
#Merged layer (the main branch that will be making prediction after training)
cnn_lstm = concatenate([cnn_flatten, lstm.output])
fc_merged = Dense(500, activation='relu')(cnn_lstm)
drop_merged = Dropout(0.5)(fc_merged)
fc2_merged = Dense(100, activation='relu')(drop_merged)
drop2_merged = Dropout(0.5)(fc2_merged)
fc3_merged = Dense(25 , activation='relu')(drop2_merged)
drop3_merged = Dropout(0.5)(fc3_merged)
pred_merged = Dense(look_forward, activation='linear')(drop3_merged)
#Auxiliary branch for cnn (want to remove at inference time)
fc_cnn = Dense(500, activation='relu')(cnn_flatten)
drop_cnn = Dropout(0.5)(fc_cnn)
fc2_cnn = Dense(100, activation='relu')(drop_cnn)
drop2_cnn = Dropout(0.5)(fc2_cnn)
fc3_cnn = Dense(25 , activation='relu')(drop2_cnn)
drop3_cnn = Dropout(0.5)(fc3_cnn)
pred_cnn_aux = Dense(look_forward, activation='linear')(drop3_cnn)
#Auxiliary branch for lstm (want to remove at inference time)
fc_lstm = Dense(500, activation='relu')(lstm.output)
drop_lstm = Dropout(0.5)(fc_lstm)
fc2_lstm = Dense(100, activation='relu')(drop_lstm)
drop2_lstm = Dropout(0.5)(fc2_lstm)
fc3_lstm = Dense(25 , activation='relu')(drop2_lstm)
drop3_lstm = Dropout(0.5)(fc3_lstm)
pred_lstm_aux = Dense(look_forward, activation='linear')(drop3_lstm)
#Final model with three branches
model = Model(inputs=[cnn.input, lstm.input], outputs=[pred_merged, pred_cnn_aux, pred_lstm_aux], name="lstm-cnn")
return model
However, I can't seem to find a way in Keras to remove the listed auxiliary branches. Is there a way I could remove the layers that are not useful during inference time?