0

Megre doesn't work anymore. I tried the new functional API (concatenate, add, multiply) but it doesn't work for models. How to implement it?

lower_model = [self.build_network(self.model_config['critic_lower'], input_shape=(self.history_length, self.n_stock, 1)) 
                               for _ in range(1  + self.n_smooth + self.n_down)]
                merged = Merge(lower_model, mode='concat')
                # upper layer
                upper_model = self.build_network(self.model_config['critic_upper'],  model=merged)
                # action layer
                action = self.build_network(self.model_config['critic_action'], input_shape=(self.n_stock,), is_conv=False)
                # output layer
                merged = Merge([upper_model, action], mode='mul')
                model = Sequential()
                model.add(merged)
                model.add(Dense(1))
                return model
HNN
  • 39
  • 7
  • Please describe the problem completely, and show us what you tried with the functional API, and why it doesn't work. – Dr. Snoopy Jan 22 '19 at 14:07

2 Answers2

2

I cannot really give you the exact answer, because your question is not detailed enough, but I can provide you an example, where layers are concatenated. Common problem is to import Concatenate and use it as in previous versions.

nlp_input = Input(shape=(seq_length,), name='nlp_input')
meta_input = Input(shape=(10,), name='meta_input')
emb = Embedding(output_dim=embedding_size, input_dim=100, input_length=seq_length)(nlp_input)
nlp_out = Bidirectional(LSTM(128, dropout=0.3, recurrent_dropout=0.3, kernel_regularizer=regularizers.l2(0.01)))(emb)
x = concatenate([nlp_out, meta_input])
x = Dense(classifier_neurons, activation='relu')(x)
x = Dense(1, activation='sigmoid')(x)
model = Model(inputs=[nlp_input , meta_input], outputs=[x])
ixeption
  • 1,972
  • 1
  • 13
  • 19
  • Well I posted the code in the old keras version and I want to compile it in the newest keras version: – HNN Jan 22 '19 at 14:45
  • And `concatenate([upper_model, action])` does not work? – ixeption Jan 22 '19 at 14:49
  • I tried the new functional api like concatenate but it doen't work. I read that the problem is that the new api works with tensors only not models. The problem is how to write merged = Merge(lower_model, mode='concat') with the latest keras version and also merged = Merge([upper_model, action], mode='mul') – HNN Jan 22 '19 at 14:51
  • I also tried merged = merge(lower_model, mod="cos", dot_axes=1) and got TypeError: 'module' object is not callable – HNN Jan 22 '19 at 14:54
  • build_network Model= build_network build_network Model= – HNN Jan 22 '19 at 15:08
  • lower_model= [, , , , .... And more... – HNN Jan 22 '19 at 15:09
  • You are trying to concatenate Sequential and Functional models? Try to call `concatenate([upper_model.model, action.model])` or look here https://github.com/keras-team/keras/issues/10386 – ixeption Jan 22 '19 at 15:40
  • I tried merged = Concatenate()([lower_model.model]) and got this error: merged = Concatenate()([lower_model.model]) AttributeError: 'list' object has no attribute 'model' – HNN Jan 22 '19 at 16:46
0

This is a dirty workaround to show how to get input and output tensors from models and use concatenate layers with them. Also to learn how to use Dense and other layers with tensors and create functional API models.

Ideally, you should rewrite everything that's inside build_network for clean and optimized code. (Perhaps this doesn't even work depending on the content of this function, but this is the idea)

lower_model = [self.build_network(
                  self.model_config['critic_lower'], 
                  input_shape=(self.history_length, self.n_stock, 1)) 
               for _ in range(1  + self.n_smooth + self.n_down)]

#for building models you need input and output tensors
lower_inputs = [model.input for model in lower_model]
lower_outputs = [model.output for model in lower_model]
    #these lines assume each model in the list has only one input and output

#using a concatenate layer on a list of tensors
merged_tensor = Concatenate()(lower_outputs) #or Concatenate(axis=...)(lower_outputs)


#this is a workaround for compatibility. 
#ideally you should work just with tensors, not create unnecessary intermediate models
merged_model = Model(lower_inputs, merged_tensor) #make model from input tensors to outputs

# upper layer
upper_model = self.build_network(self.model_config['critic_upper'],  model=merged_model)

# action layer
action = self.build_network(self.model_config['critic_action'], input_shape=(self.n_stock,), is_conv=False)

# output layer - get the output tensors from the models
upper_out = upper_model.output
action_out = action.output

#apply the Multiply layer on the list of tensors
merged_tensor = Multiply()([upper_out, action_out])

#apply the Dense layer on the merged tensor
out = Dense(1)(merged_tensor)

#get input tensors to create a model
upper_iputs = upper_model.inputs #should be a list   
action_inputs = action.inputs #if not a list, append to the previous list

inputs = upper_inputs + action_inputs
model = Model(inputs, out)

return model
Daniel Möller
  • 84,878
  • 18
  • 192
  • 214
  • I get undefined Model and merged in merged_model = Model(lower_inputs, merged). Am I missing an import? – HNN Jan 22 '19 at 18:33
  • Exactly what I fixed in the answer. – Daniel Möller Jan 22 '19 at 19:11
  • Ok now I get error in upper_model = self.build_network(self.model_config['critic_upper'], model=merged_model) ValueError: Layer model_1 expects 11 inputs, but it received 1 input tensors. Input received: [] – HNN Jan 22 '19 at 19:37
  • Now it's up to you to work `build_network` properly. I can't help if the code is hidden. If it's expecting tensors instead of models, there is no point in merging the tensors. – Daniel Möller Jan 22 '19 at 19:51
  • def build_network(self, conf, model=None, input_shape=None, is_conv=True): """Build network""" _model = model model = Sequential() if _model is None: model.add(Lambda(lambda x: x, input_shape=input_shape)) else: model.add(_model) It fails model.add(_model) – HNN Jan 22 '19 at 20:25
  • Rewrite everything. Use only functional API, forget about sequentials and merges. This seems a lot of trouble now, but it's the best for all your future projects. – Daniel Möller Jan 22 '19 at 20:48
  • I am new to this and rewriting everything is beyond me. There must be a relatively simple solution to implement Merge concat and mul in the new version of Keras. – HNN Jan 23 '19 at 16:40
  • It is simple. Just get the input/output tensors and pass them through layers, but you haven't shown any code, it's impossible to know what is happening in `build_network`. But it's mixing things, models and tensors and this is more confusing than just building a new model from scratch. – Daniel Möller Jan 27 '19 at 13:18
  • I posted a new thread with the full code actor+critic+build network. https://stackoverflow.com/questions/54406981/convert-old-keras2-code-to-new-keras2 – HNN Jan 28 '19 at 17:32