i'm trying to run a SOM on a M5Stack using minisom (python library for SOM) and i tried in two ways:
1 - Using tflite;
2 - Using UIFlow (official IDE for M5Stack) and Micropython.
For both ways i'm at a dead end.
1 - For the first way i tried to save and export the model as tflite model but the problem is: minisom implementation doesn't use tensforflow and the only way that i found to save the model is using pickle, then i tried to convert to .tflite but the requested input is a .pb/.pbtxt file and i haven't found a way to convert .p file to .pb/.pbtxt. I tried also with different tensorflow implementations of SOM but they doesn't work as good as minisom impl., so my question is: is there a way to export minisom model as tflite model? Or a good tensorflow implementation?
2 - For the second way i discovered that is possible to use python to program the M5Stack using VSCode or UIFlow. My idea was to manually copy the minisom library and import it from code, which I succeeded because the minisom.py file is found but I get an error when importing the MiniSom object and I think it is due to the fact that it is necessary to import the libraries that minisom uses (for example numpy), following the same reasoning I tried to copy numpy inside the M5Stack but here comes the problem. With VSCode and UIFlow i can only create or push one file at a time and i can't create or push directories. The only way i've found to push directories is to use ampy but when i type any ampy command from the terminal the cursor blinks and i get no response from the program. My next step will be to copy the libraries to a microSD and put it in the M5Stack. Could that be a correct way to proceed? Are there other ways to copy python libraries inside the M5Stack?
For the second way i discovered that is possibile to manually copy libraries in microSD card and load them with micropython but i've got an out of memory error while loading libraries. After that i was back on the first way and now i'm trying to build a custom keras model following this guide: Customizing what happens in fit() but i have an error, i will list my code and show the error below: This is the code of the custom model
import tensorflow as tf
from sklearn.metrics import classification_report
from tensorflow import keras
import numpy as np
from minisom import MiniSom
def classify(som, data, X_train, y_train):
"""Classifies each sample in data in one of the classes definited
using the method labels_map.
Returns a list of the same length of data where the i-th element
is the class assigned to data[i].
"""
y = list()
for idx, item in enumerate(y_train):
y.append(np.argmax(y_train[idx]))
print("\rTrain labels transform. progress: " + str(idx + 1) + '/' + str(len(y_train)), end='')
print()
winmap = som.labels_map(X_train, y)
# print(winmap)
# input()
default_class = np.sum(list(winmap.values())).most_common()[0][0]
result = []
for d in data:
win_position = som.winner(d)
if win_position in winmap:
result.append(winmap[win_position].most_common()[0][0])
else:
result.append(default_class)
return result
class SOMModel(keras.Model):
def __init__(self, X_train, y_train):
super().__init__()
self.y_train = y_train
self.X_train = X_train
self.som = None
@tf.function
def train_step(self, data):
# Unpack the data. Its structure depends on your model and
# on what you pass to `fit()`.
n, m, input_shape = data
self.som = MiniSom(n, m, input_shape, sigma=5, learning_rate=0.1,
neighborhood_function='gaussian', activation_distance='manhattan')
self.som.random_weights_init(self.X_train)
self.som.train_random(self.X_train, 100, verbose=True) # random training
with tf.GradientTape() as tape:
y_pred = self(self.X_train, training=True) # Forward pass
# Compute the loss value
# (the loss function is configured in `compile()`)
loss = self.compiled_loss(self.y_train, y_pred, regularization_losses=self.losses)
# Compute gradients
trainable_vars = self.trainable_variables
gradients = tape.gradient(loss, trainable_vars)
# Update weights
self.optimizer.apply_gradients(zip(gradients, trainable_vars))
# Update metrics (includes the metric that tracks the loss)
self.compiled_metrics.update_state(self.y_train, y_pred)
# Return a dict mapping metric names to current value
return {m.name: m.result() for m in self.metrics}
def test_step(self, data):
X_test, y_test = data
new_y_test = list()
for idx, item in enumerate(y_test):
new_y_test.append(np.argmax(y_test[idx]))
print("\rTest labels transform. progress: " + str(idx + 1) + '/' + str(len(y_test)), end='')
print(classification_report(new_y_test, classify(self.som, X_test, self.X_train, self.y_train)))
y_pred = self(X_test, training=False)
# Updates the metrics tracking the loss
self.compiled_loss(y_test, y_pred, regularization_losses=self.losses)
# Update the metrics.
self.compiled_metrics.update_state(y_test, y_pred)
# Return a dict mapping metric names to current value.
# Note that it will include the loss (tracked in self.metrics).
return {m.name: m.result() for m in self.metrics}
This is the code which i use to instantiate the custom model
from SOMModel import SOMModel
model = SOMModel(X_train, y_train)
model.compile(optimizer="adam", loss="categorical_crossentropy")
data = 50, 50, X_train.shape[1]
model.fit(data)
model.evaluate(X_test, y_test)
I have this error when model.fit() is called:
Traceback (most recent call last):
File "C:\Users\Scianso\PycharmProjects\UCI_HAR\main.py", line 328, in <module>
run_experiment(5)
File "C:\Users\Scianso\PycharmProjects\UCI_HAR\main.py", line 324, in run_experiment
execute_minisom(trainX, trainy, testX, testy)
File "C:\Users\Scianso\PycharmProjects\UCI_HAR\main.py", line 241, in execute_minisom
model.fit(data, epochs=1)
File "C:\Users\Scianso\PycharmProjects\UCI_HAR\venv\lib\site-packages\keras\utils\traceback_utils.py", line 70, in error_handler
raise e.with_traceback(filtered_tb) from None
File "C:\Users\Scianso\PycharmProjects\UCI_HAR\venv\lib\site-packages\tensorflow\python\framework\func_graph.py", line 1233, in autograph_handler
raise e.ag_error_metadata.to_exception(e)
tensorflow.python.framework.errors_impl.OperatorNotAllowedInGraphError: in user code:
File "C:\Users\Scianso\PycharmProjects\UCI_HAR\venv\lib\site-packages\keras\engine\training.py", line 1160, in train_function *
return step_function(self, iterator)
File "C:\Users\Scianso\PycharmProjects\UCI_HAR\SOMModel.py", line 45, in train_step *
n, m, input_shape = data
OperatorNotAllowedInGraphError: Iterating over a symbolic `tf.Tensor` is not allowed: AutoGraph did convert this function. This might indicate you are trying to use an unsupported feature.
If i unpack the parameters passed to model.fit() i have:
Traceback (most recent call last):
File "C:\Users\Scianso\PycharmProjects\UCI_HAR\main.py", line 328, in <module>
run_experiment(5)
File "C:\Users\Scianso\PycharmProjects\UCI_HAR\main.py", line 324, in run_experiment
execute_minisom(trainX, trainy, testX, testy)
File "C:\Users\Scianso\PycharmProjects\UCI_HAR\main.py", line 241, in execute_minisom
model.fit(50, 50, X_train.shape[1], epochs=1)
File "C:\Users\Scianso\PycharmProjects\UCI_HAR\venv\lib\site-packages\keras\utils\traceback_utils.py", line 70, in error_handler
raise e.with_traceback(filtered_tb) from None
File "C:\Users\Scianso\PycharmProjects\UCI_HAR\venv\lib\site-packages\tensorflow\python\framework\tensor_shape.py", line 912, in __getitem__
return self._dims[key]
IndexError: tuple index out of range
Is it possible to solve this errors and continue with this approach?
Thanks in advice for the answers.