Keras converter. Lambda layer with multiple inputs.
shamangary opened this issue · 4 comments
shamangary commented
Hi. I encounter an issue when lambda layer receives multiple inputs.
# This is a custom activation function.
def swish(x,s1):
return K.sigmoid(x)*x
def merge(x):
return x[0]+x[1]
# Create a silly model that has our custom activation function as a new layer.
def create_model():
a = 3
inp = Input(shape=(256, 256, 3))
x = Conv2D(6, (3, 3), padding="same")(inp)
#x = Activation(swish)(x) # doesn't work! :-(
x = Lambda(swish, arguments={'s1':a})(x)
x = GlobalAveragePooling2D()(x)
x0 = Dense(10, activation="softmax")(x)
x1 = Dense(10, activation="softmax")(x0)
x = Lambda(merge)([x0,x1])
return Model(inp, x)
The conversion works fine when lambda layer only has one input. However, x = Lambda(merge)([x0,x1]) causes the following problem.
Traceback (most recent call last):
File "test.py", line 98, in <module>
custom_conversion_functions={ "Lambda": convert_lambda })
File "/home/shamangary/anaconda3/envs/new/lib/python3.5/site-packages/coremltools/converters/keras/_keras_converter.py", line 745, in convert
custom_conversion_functions=custom_conversion_functions)
File "/home/shamangary/anaconda3/envs/new/lib/python3.5/site-packages/coremltools/converters/keras/_keras_converter.py", line 543, in convertToSpec
custom_objects=custom_objects)
File "/home/shamangary/anaconda3/envs/new/lib/python3.5/site-packages/coremltools/converters/keras/_keras2_converter.py", line 191, in _convert
graph.build()
File "/home/shamangary/anaconda3/envs/new/lib/python3.5/site-packages/coremltools/converters/keras/_topology2.py", line 643, in build
successors = self.edge_map[layer]
KeyError: 'lambda_2'
I was trying much more complex merging function (with multiple different dim features) other than just addition.
Do you know how to resolve this? Thank you!
aseemw commented
Can you try changing this function locally to the following and see if the error persists?
def _get_first_shared_layer(self):
for idx, layer in enumerate(self.layer_list):
keras_layer = self.keras_layer_map[layer]
if not _is_merge_layer(self.keras_layer_map[layer]) and \
len(self.get_predecessors(layer)) > 1 and \
len(keras_layer._inbound_nodes) > 1:
return idx
return -1
shamangary commented
Hello. The conversion works :). Despite I still have to write a custom swift file for my layer for the ios app, I guess the conversion is working now. Many thanks.
visionscaper commented
@aseemw Has the above fix been merged in the code?
aseemw commented
Yes.