eloquentarduino / EloquentTinyML

Eloquent interface to Tensorflow Lite for Microcontrollers
301 stars 57 forks source link

How to add other functions correctly #74

Closed GabeFigenio closed 3 months ago

GabeFigenio commented 3 months ago

I'm trying to use more functions than the ones added automatically by the python library. I'm trying to add them like the LSTM example.

template<class TF>
void registerNetworkOps(TF& nn) {
    nn.resolver.AddFullyConnected();
    nn.resolver.AddRelu();
    nn.resolver.AddLogistic();
}

Just this don't work, the AddFullyConnected don't fails to register. And I still need other functions as While, Logistic and Transpose. How do I add them correctly?

eloquentarduino commented 3 months ago

This is the code generated for an LSTM network, for example:

// automatically configure network
#define TF_NUM_INPUTS 450
#define TF_NUM_OUTPUTS 3
#define TF_NUM_OPS 21

/**
 * Call this function to register the ops
 * that have been detected
 */
template<class TF>
void registerNetworkOps(TF& nn) {
    nn.resolver.AddSplit();
    nn.resolver.AddFullyConnected();
    nn.resolver.AddGather();
    nn.resolver.AddTranspose();
    nn.resolver.AddLess();
    nn.resolver.AddTanh();
    nn.resolver.AddMul();
    nn.resolver.AddShape();
    nn.resolver.AddWhile();
    nn.resolver.AddConcatenation();
    nn.resolver.AddSoftmax();
    nn.resolver.AddUnidirectionalSequenceLSTM();
    nn.resolver.AddRelu();
    nn.resolver.AddMaximum();
    nn.resolver.AddFill();
    nn.resolver.AddSlice();
    nn.resolver.AddPack();
    nn.resolver.AddMinimum();
    nn.resolver.AddAdd();
    nn.resolver.AddReshape();
    nn.resolver.AddStridedSlice();  
}

It covers most of the op available (except Conv2D and MaxPool2D). What matters most is #define TF_NUM_OPS 21: be sure you update this number with the correct number of ops you're registering.

By the way, here's the list of supported operators: https://github.com/eloquentarduino/tflm_esp32/blob/5fe67df0264113863fa54997924e20b01df31318/src/tensorflow/lite/micro/micro_mutable_op_resolver.h

GabeFigenio commented 3 months ago

I found the issues. One of them was the num_ops, but I wasn't declaring the registerNetworkOps() on setup().

I have another issue now, I don't know if I need to open another issue.

But I'm trying to use a LSTM layer on the nn.

model = tf.keras.Sequential()
model.add(LSTM(units=32, input_shape=(2,1)))
model.add(Dense(1, activation='sigmoid'))

I'm trying a really simple one to teste first, but I'm not being able to convert the model to C, in Python, because of the LSTM layer.

c_header = convert_model(model, X_values, Y_values, model_name='model')
print(c_header)

I know that's another library of your's, if you want we can discuss better in there. But I really need this help to embedded the LSTM.

There is a specific function to convert a LSTM layer?

eloquentarduino commented 3 months ago

This is the Notebook for LSTM: https://colab.research.google.com/gist/eloquentarduino/9a06210b6943a895cf492f93b985221e/train-tensorflow-lstm-model-for-arduino.ipynb

And this is the blog post on how to use: https://eloquentarduino.com/posts/arduino-esp32-lstm

GabeFigenio commented 3 months ago

Thank you, I'll take a look. If I have any other doubt I'll reach you again.