Problem when converting keras LSTM model to tflite model

Preformatted textI would like to convert this simple keras model to a tflite monde

`def create_model() : 
    model = Sequential()
    model.add(Input(shape=(6,73)))
    model.add(LSTM(units=20, recurrent_dropout=0.5)) 
    model.add(Dense(units=1, activation='sigmoid'))
    optimizer = Adam(learning_rate=0.001)
    model.compile(optimizer=optimizer, loss='binary_crossentropy', metrics=['accuracy'])
    early_stopping = EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True)
    history = model.fit(X_train, y_train, epochs=100, validation_split=0.15, verbose=0, callbacks=[early_stopping])
    return model, history`

But after the conversion, when I print all tensor details I can see that the structure not remains the same :
{‘name’: ‘serving_default_input_1:0’, ‘index’: 0, ‘shape’: array([ 1, 6, 73]), ‘shape_signature’: array([-1, 6, 73]), ‘dtype’: <class ‘numpy.float32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/lstm/strided_slice_3’, ‘index’: 1, ‘shape’: array([3]), ‘shape_signature’: array([3]), ‘dtype’: <class ‘numpy.int32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/lstm/strided_slice_31’, ‘index’: 2, ‘shape’: array([3]), ‘shape_signature’: array([3]), ‘dtype’: <class ‘numpy.int32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/lstm/strided_slice_32’, ‘index’: 3, ‘shape’: array([3]), ‘shape_signature’: array([3]), ‘dtype’: <class ‘numpy.int32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/dense/BiasAdd/ReadVariableOp’, ‘index’: 4, ‘shape’: array([1]), ‘shape_signature’: array([1]), ‘dtype’: <class ‘numpy.float32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/lstm/strided_slice_1’, ‘index’: 5, ‘shape’: array([], dtype=int32), ‘shape_signature’: array([], dtype=int32), ‘dtype’: <class ‘numpy.int32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/lstm/zeros/packed/1’, ‘index’: 6, ‘shape’: array([], dtype=int32), ‘shape_signature’: array([], dtype=int32), ‘dtype’: <class ‘numpy.int32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/lstm/zeros/Const’, ‘index’: 7, ‘shape’: array([], dtype=int32), ‘shape_signature’: array([], dtype=int32), ‘dtype’: <class ‘numpy.float32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/lstm/transpose/perm’, ‘index’: 8, ‘shape’: array([3]), ‘shape_signature’: array([3]), ‘dtype’: <class ‘numpy.int32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/lstm/time’, ‘index’: 9, ‘shape’: array([], dtype=int32), ‘shape_signature’: array([], dtype=int32), ‘dtype’: <class ‘numpy.int32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/lstm/strided_slice/stack_1’, ‘index’: 10, ‘shape’: array([1]), ‘shape_signature’: array([1]), ‘dtype’: <class ‘numpy.int32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/lstm/strided_slice/stack’, ‘index’: 11, ‘shape’: array([1]), ‘shape_signature’: array([1]), ‘dtype’: <class ‘numpy.int32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/lstm/TensorArrayV2_1/num_elements’, ‘index’: 12, ‘shape’: array([], dtype=int32), ‘shape_signature’: array([], dtype=int32), ‘dtype’: <class ‘numpy.int32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/lstm/TensorArrayV2Stack/TensorListStack/element_shape’, ‘index’: 13, ‘shape’: array([2]), ‘shape_signature’: array([2]), ‘dtype’: <class ‘numpy.int32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/dense/MatMul’, ‘index’: 14, ‘shape’: array([ 1, 20]), ‘shape_signature’: array([ 1, 20]), ‘dtype’: <class ‘numpy.float32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/lstm/Shape’, ‘index’: 15, ‘shape’: array([3]), ‘shape_signature’: array([3]), ‘dtype’: <class ‘numpy.int32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/lstm/TensorArrayV2_1’, ‘index’: 16, ‘shape’: array([], dtype=int32), ‘shape_signature’: array([], dtype=int32), ‘dtype’: <class ‘numpy.object_’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/lstm/strided_slice’, ‘index’: 17, ‘shape’: array([], dtype=int32), ‘shape_signature’: array([], dtype=int32), ‘dtype’: <class ‘numpy.int32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/lstm/transpose’, ‘index’: 18, ‘shape’: array([ 6, 1, 73]), ‘shape_signature’: array([ 6, -1, 73]), ‘dtype’: <class ‘numpy.float32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/lstm/zeros/packed’, ‘index’: 19, ‘shape’: array([2]), ‘shape_signature’: array([2]), ‘dtype’: <class ‘numpy.int32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/lstm/zeros’, ‘index’: 20, ‘shape’: array([ 1, 20]), ‘shape_signature’: array([-1, 20]), ‘dtype’: <class ‘numpy.float32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/lstm/while’, ‘index’: 21, ‘shape’: array([], dtype=int32), ‘shape_signature’: array([], dtype=int32), ‘dtype’: <class ‘numpy.int32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/lstm/while1’, ‘index’: 22, ‘shape’: array([], dtype=int32), ‘shape_signature’: array([], dtype=int32), ‘dtype’: <class ‘numpy.int32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/lstm/while2’, ‘index’: 23, ‘shape’: array([], dtype=int32), ‘shape_signature’: array([], dtype=int32), ‘dtype’: <class ‘numpy.object_’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/lstm/while3’, ‘index’: 24, ‘shape’: array([ 1, 20]), ‘shape_signature’: array([-1, 20]), ‘dtype’: <class ‘numpy.float32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/lstm/while4’, ‘index’: 25, ‘shape’: array([ 1, 20]), ‘shape_signature’: array([-1, 20]), ‘dtype’: <class ‘numpy.float32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/lstm/while5’, ‘index’: 26, ‘shape’: array([ 6, 1, 73]), ‘shape_signature’: array([ 6, -1, 73]), ‘dtype’: <class ‘numpy.float32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/lstm/TensorArrayV2Stack/TensorListStack’, ‘index’: 27, ‘shape’: array([ 1, 1, 20]), ‘shape_signature’: array([ 1, -1, 20]), ‘dtype’: <class ‘numpy.float32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/lstm/strided_slice_33’, ‘index’: 28, ‘shape’: array([ 1, 20]), ‘shape_signature’: array([-1, 20]), ‘dtype’: <class ‘numpy.float32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘sequential/dense/MatMul;sequential/dense/BiasAdd’, ‘index’: 29, ‘shape’: array([1, 1]), ‘shape_signature’: array([-1, 1]), ‘dtype’: <class ‘numpy.float32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}
{‘name’: ‘StatefulPartitionedCall:0’, ‘index’: 30, ‘shape’: array([1, 1]), ‘shape_signature’: array([-1, 1]), ‘dtype’: <class ‘numpy.float32’>, ‘quantization’: (0.0, 0), ‘quantization_parameters’: {‘scales’: array([], dtype=float32), ‘zero_points’: array([], dtype=int32), ‘quantized_dimension’: 0}, ‘sparsity_parameters’: {}}

Why do think that? The LSTM-Layer consists of multiple tflite-ops, but the TFLite-Model follows the same structure as your Keras definition.

There is no more weights that I can get. In this example you can see on the neutron image at the end that the structure remains the same and you can get weights and biais.
https://colab.research.google.com/github/tensorflow/tensorflow/blob/master/tensorflow/lite/examples/experimental_new_converter/Keras_LSTM_fusion_Codelab.ipynb#scrollTo=Z7gEg4DRBwbO

Load your tflite model in netron, you should see a similar output.

This post was flagged by the community and is temporarily hidden.

Here is a Github link, I uploaded the png representing the converted LSTM model. https://github.com/lisamignerey83/LSTM-tflite/blob/main/model.png