nengo-dl
nengo-dl copied to clipboard
Converter KeyError when using Keras Sequential API to create the input
Minimal Reproducer:
import nengo_dl
import tensorflow as tf
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Dense(16, input_shape=(1,), activation="relu"))
model.summary()
nengo_converter = nengo_dl.Converter(
model,
swap_activations={
tf.keras.activations.relu: nengo.RectifiedLinear(),
},
synapse=None,
)
assert model.input is model.layers[0].input
print(model.input, list(nengo_converter.inputs)[0])
nengo_input = nengo_converter.inputs[model.input]
Output:
Model: "sequential_10"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_18 (Dense) (None, 16) 32
=================================================================
Total params: 32
Trainable params: 32
Non-trainable params: 0
_________________________________________________________________
Tensor("dense_18_input:0", shape=(None, 1), dtype=float32) Tensor("input_10:0", shape=(None, 1), dtype=float32)
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-61-95be1111e3ee> in <module>
14 print(model.input, list(nengo_converter.inputs)[0])
15
---> 16 nengo_input = nengo_converter.inputs[model.input]
~/anaconda3/envs/*/lib/python3.7/site-packages/nengo_dl/converter.py in __getitem__(self, key)
399
400 def __getitem__(self, key):
--> 401 return self.dict[self._get_key(key)]
402
403 def __iter__(self):
KeyError: <Reference wrapping <tf.Tensor 'dense_18_input:0' shape=(None, 1) dtype=float32>>
Expected Behaviour:
Expected to be able to grab the converted input by looking up model.input
, analogous to how it's done here: https://www.nengo.ai/nengo-loihi/examples/keras-to-loihi.html, but instead using the Sequential()
API. It looks like the issue is that the name in the sequential model ("dense_18_input:0") doesn't match the one in the converter ("input_10:0")?
Current Workaround:
assert len(nengo_converter.inputs) == 1
nengo_input = list(nengo_converter.inputs)[0]
When you pass in a Sequential model the Converter automatically converts it to a Functional model for you, and then that functional model is what is used for the actual conversion process. So all the converter data structures will be with respect to that functional model, not the sequential one. If you change your code to
nengo_input = nengo_converter.inputs[nengo_converter.model.input]
(note, using nengo_converter.model
instead of model
), then everything should work as expected.
I'll add a sentence to the warning that gets raised when you pass in a Sequential model to make this more obvious.
Thanks! That worked. As a quick note I was also seeing this when similarly trying to lookup a particular layer, e.g., via nengo_converter.layers[model.get_layer("layer_name").output]
. I also tried nengo_converter.model
instead of model
. As well as model.layers[index]
. Just mentioning this as a nice-to-have or in case I'm doing the wrong thing.