Abbiamo reso nuovamente semplice il Machine Learning su Arduino
Spazio Chirale Trends • 28 giugno, 2024
Chiunque abbia avuto modo di sperimentare la scheda Arduino Nano 33 BLE, seguendo il classico percorso proposto dalla documentazione ufficiale di Arduino, molto probabilmente sarà stato incuriosito dalla possibilità di utilizzare il Machine Learning.
Infatti, il Machine Learning era proprio uno degli elementi distintivi che aveva caratterizzato il lancio di questa board, coinciso con il rilascio da parte di Google della libreria TensorFlow Lite Micro.
Arduino Nano 33 BLE fu il dispositivo scelto dal team di Google nel 2018 per sperimentare il funzionamento della prima versione della nuova libreria, e la versione per Arduino fu il primo esempio di porting verso una specifica piattaforma a microcontrollore.
Il progetto fu seguito da un team di lavoro comprendente ingegneri software di Google e ingegneri di Arduino.
Da questa esperienza nacque un interessante workshop che successivamente fu utilizzato come base per la stesura del tutorial denominato “Get Started With Machine Learning on Arduino“, tuttora presente nella documentazione ufficiale della scheda e visibile a questo link.
Nel 2019, fummo tra i primi centri di formazione italiani ad inserire questo tutorial nell’ambito dei nostri corsi sul Tiny Machine Learning in quanto ben rappresentava il potenziale di questa tecnologia emergente.
Sebbene la data di aggiornamento del tutorial ufficiale sia molto recente, aprile 2024 nel momento in cui stiamo scrivendo questo post, chiunque abbia provato a seguire i passaggi descritti e ad utilizzare gli sketch pubblicati, da due anni a questa parte, avrà certamente notato che la compilazione dello sketch decisivo, quello che si riferisce all’esecuzione del TensorFlow Lite su Arduino, fallisce con una serie di errori.
Cosa è successo?
La ricerca su Internet del problema non aiuta.
Tutti i tutorial video sono datati tra il 2019 e il 2020, periodo in cui tutto funzionava perfettamente.
Da alcuni thread presenti sul forum Arduino e sulle “issue” di GitHub, si capisce che il problema è noto e che la causa è da ricercarsi nel disallineamento tra le versioni della libreria, non più presente nel registry ufficiale Arduino, ma presente sul repository GitHub di TensorFlow, e il codice dello sketch riportato all’interno del tutorial.
Alcune risposte nei thread sul forum Arduino sono tranchant e più o meno affermano che oramai, con l’avvento della IA in stile ChatGPT, giocare con il tiny machine leraning su una piattaforma limitata come un microcontrollore è un esercizio inutile e superato.
Noi non siamo assolutamente d’accordo, e per questo motivo, in occasione della preparazione del nostro nuovo corso su Arduino, abbiamo deciso di inserire il Tiny Machine Learning tra gli argomenti e abbiamo messo mano al TensorFlow Lite Micro per generare una nuova libreria, aggiornata a giugno 2024, in grado di rendere la sperimentazione diretta di questa tecnologia nuovamente alla portata di tutti, soprattutto coloro che non sono programmatori C++ esperti di TensorFlow.
In questo lungo articolo, vi spiegheremo perché riteniamo il Tiny Machine Learning un tema di estrema attualità soprattutto nell’era di ChatGPT e cos’era accaduto alla libreria originale Arduino TensorFlow Lite.
Se stai cercando una soluzione al problema del mancato funzionamento del tutorial ufficiale Arduino relativo al Machine Learning sulla scheda Nano 33 BLE, sei nel posto giusto.
Dopo le nostre considerazioni sull’importanza dell’argomento Tiny Machine Learning, ti spiegheremo come fare per realizzare sketch corretti e funzionanti che usano il TensorFlow Lite Micro su Arduino.
Cos’è il Tiny Machine Learning e perché è importante?
Il Machine Learning è una delle aree di ricerca nell’ambito del più ampio settore dell’Intelligenza Artificiale.
Da un punto di vista pratico ed ingegneristico, si tratta di un processo di sviluppo di software alternativo a quello tradizionale basato sulla definizione di algoritmi espliciti composti da sequenze di istruzioni, cicli e diramazioni if … then … else.
Esistono, infatti, situazioni in cui il processo tradizionale non è applicabile.
Per comprendere il concetto, facciamo riferimento ad alcuni semplici esempi.
Immaginiamo di voler realizzare un programma che date, in input, le tre misure delle lunghezze dei lati di un triangolo, fornisca in output la categoria a cui appartiene il triangolo: triangolo rettangolo, oppure triangolo non rettangolo.
Si tratta di un banale problema di classificazione, facilmente risolubile. La strada più veloce è quella di fare riferimento al teorema di Pitagora e realizzare un semplice algoritmo che verifichi se la somma dei quadrati dei lati più corti sia pari al quadrato del lato più lungo. Se questa proprietà è verificata, il triangolo è rettangolo, se la proprietà non è verificata il triangolo non è rettangolo.
In questo caso siamo stati in grado di trovare un algoritmo esplicito che ha permesso di risolvere il problema di classificazione.
Prendiamo ora un problema diverso. L’immagine riportata sopra mostra un braccio robotico a cui è applicato un sensore IMU (Inertial Measurment Unit) in grado di rilevare i valori di accelerazione lineare e angolare durante il movimento del braccio.
A seconda del carico applicato al braccio robotico, delle condizioni operative e di altri fattori ambientali, le sequenze di valori letti dal sensore possono essere molto diverse tra loro. Immaginiamo di rilevare sequenze di letture in varie condizioni operative sia quando il braccio funziona correttamente sia quando il braccio mostra delle anomalie di funzionamento, ad esempio per surriscaldamento dei motori o in caso di veri e propri guasti.
Probabilmente le letture effettuate nell’intervallo di tempo che ha preceduto l’anomalia mostrano andamenti che possono essere utilizzati per prevedere l’imminente futuro guasto.
Osservando le sequenze di dati, siamo in grado di identificare le regole matematiche che permettono di identificare la situazione anomala?
Molto probabilmente no.
Quando si analizzano situazioni di questo tipo, molto spesso la rappresentazione grafica delle sequenze di valori appare diversa già da una semplice analisi visiva, ma passare dal riconoscimento visivo del “pattern” delle curve di valori alla formulazione di una regola algoritmica non è una cosa facile e spesso neanche possibile.
Così come analizzando la sequenza di numeri binari di cui è composto un file jpg è impossibile definire un algoritmo specifico per fornire l’identificazione degli oggetti presenti nell’immagine, anche nel caso dell’analisi di sequenze di valori rilevate da sensori complessi come un IMU è solitamente impossibile definire un algoritmo specifico per identificare situazioni di potenziale anomalia.
In questi casi il Machine Learning fornisce una soluzione elegante ed efficace.
Per procedere attraverso questa tecnica, si suddivide il processo di realizzazione del software in due fasi.
Nella prima fase si sviluppa un software per raccogliere e memorizzare le sequenze di dati, e si lascia girare il software per un periodo sufficientemente lungo in modo da rilevare situazioni normali ma anche situazioni anomale.
I dati così raccolti si “etichettano“, manualmente o automaticamente, in modo da identificare i campioni che rappresentano situazioni di normalità e quelli che rappresentano situazioni di allarme.
Nella seconda fase si realizza un software che implementa un modello di machine learning, ad esempio una rete neurale convoluzionale.
Questi “modelli” sono algoritmi generalizzati caratterizzati da un elevato numero di parametri.
Per ogni valore fornito in input, il risultato calcolato in output dipende dal valore assegnato ai parametri.
Al “modello” è associato un opportuno algoritmo di training, chiamato anche algoritmo di model fitting, che attraverso un procedimento iterativo e l’applicazione di funzioni e metodi di derivazione statistica, elabora i dati di esempio, etichettati con le classificazioni note, per determinare il valore da assegnare ai parametri in modo che il “modello” sia in grado di determinare la corretta classificazione dell’input.
Il risultato finale di questo processo di sviluppo è un algoritmo software in grado di risolvere il nostro problema di classificazione.
Il progettista software non è in grado di stabilire a priori un algoritmo preciso per risolvere il problema, ma attraverso il meccanismo di apprendimento, o model fitting, il sistema è in grado di determinare automaticamente i parametri corretti, sulla base di un insieme di dati noti, chiamato dataset di training.
L’essenza del Machine Learning è questa e, come si intuisce, si tratta di un metodo molto potente che ci permette di risolvere problemi di analisi dati e classificazione che non sono affrontabili in maniera tradizionale.
L’esempio relativo alla manutenzione predittiva del braccio robotico che abbiamo descritto sopra, è indicativo di come il Machine Learning possa essere uno strumento molto valido nell’ambito dei sistemi digitali di controllo. Come si implementa tutto questo in un contesto dove i dati vengono raccolti e analizzati da dispositivi a microcontrollore?
Come abbiamo visto, nei sistemi basati sul Machine Learning esistono due diverse categorie di algoritmi, gli algoritmi di apprendimento o model fitting e gli algoritmi di “previsione” o “classificazione“, in cui viene elaborato l’input attraverso un modello matematico i cui parametri sono stati predeterminati attraverso l’apprendimento.
Gli algoritmi di apprendimento richiedono tempi lunghi e molte risorse di elaborazione. Per questo motivo, solitamente vengono eseguiti su computer dedicati, equipaggiati con CPU multi-core e coprocessori specializzati GPU (gli stessi usati per la grafica) o TPU (coprocessori specializzati nel calcolo tensoriale tipico del machine learning).
Gli algoritmi di classificazione, nei casi simili a quelli che abbiamo citato come esempi, richiedono solitamente risorse e potenze di elaborazione molto più limitate e nella maggioranza dei casi possono essere eseguiti anche a bordo di un moderno microcontrollore a 32 bit.
La tecnologia che consente di elaborare gli algoritmi di previsione dei modelli di Machine Learning e delle Reti Neurali su dispositivi limitati come smartphone, single board computer e schede a microcontrollore, prende il nome di Tiny Machine Learning.
Una soluzione basata sul Tiny Machine Learning prevede solitamente una fase di raccolta dati, una fase di model fitting da condurre su computer dedicati o su piattaforme di elaborazione in cloud e l’installazione ed esecuzione del modello addestrato sui dispositivi a microcontrollore o su smart device.
Nel 2018, Google ha rilasciato una libreria open source in C++, chiamata TensorFlow Lite Micro, che ha reso facile ed immediato il porting di un modello di rete neurale realizzato attraverso la potente e utilizzatissima piattaforma TensorFlow sui microcontrollori.
L’entusiasmo iniziale da parte degli sviluppatori di firmware e il fiorire di tutorial e progetti pilota nell’ambito delle community open source, come quella di Arduino, sono stati adombrati dal recente avvento delle nuove Intelligenze Artificiali Generative, che hanno in parte modificato l’approccio alle tecnologie generali di Machine Learning.
La potenza di sistemi come quelli presentati da OpenAI e dai suoi competitor è tale che molti problemi di analisi dati possono essere direttamente proposti a strumenti come ChatGPT ottenendo risposte immediate e corrette senza dover più procedere alla realizzazione di un proprio modello di rete neurale da addestrare in modo appropriato.
Ha ancora senso implementare a bordo di un microcontrollore un algoritmo basato su reti neurali, quando sarebbe più facile e immediato inviare i dati rilevati dai sensori ad un potente sistema di AI raggiungibile in cloud e invocato tramite API?
Una semplice ricerca web sulla parola chiave Intelligenza Artificiale associata ad Arduino porta oggi ad una serie di pagine dove si descrivono progetti, più o meno amatoriali, in cui il dispositivo utilizza la connessione Internet per avvalersi di un servizio esterno basato su IA.
Sebbene questa architettura sia facile da realizzare e molto più immediata, in un contesto amatoriale o artigianale, la soluzione dell’invio verso il cloud dei dati elementari raccolti dai sensori remoti, non è efficiente, né economicamente conveniente, in un contesto industriale.
La raccolta real time di flussi di dati continuativi da centinaia o migliaia di sensori remoti e il relativo inoltro verso Internet richiede larghezze di banda adeguate e la conseguente necessità di impiegare dispositivi di trasmissione potenti per superare i problemi di interferenze e disturbi solitamente presenti negli impianti industriali.
Non è un caso che nell’ambito Industrial Internet of Things, sono sempre più diffuse le architetture definite di Edge Computing, in cui l’elaborazione dei dati avviene a bordo dei dispositivi sensori, o su sistemi intermedi prossimi ad essi, limitando l’inoltro verso i sistemi centrali dei soli dati di sintesi o degli allarmi.
Il Tiny Machine Learning è una soluzione conforme all’architettura Edge Computing e per questo motivo la sua importanza crescerà nell’immediato futuro.
A livello industriale la ricerca e sviluppo in questo settore non si è mai fermata e la stessa libreria TensorFlow Lite Micro è attualmente localizzata per tutte le principali architetture dei microcontrollori presenti sul mercato, da ARM Cortex M4 fino a ESP32 S3.
Il mondo Arduino, tuttavia, risente molto dei trend e degli hype mediatici, che ovviamente influenzano la nutrita community di appassionati, che comprende anche molti studenti e ricercatori.
Il Tiny Machine Learning su Arduino sembrava un tema passato di moda, e questo è un peccato, poiché storicamente da questa community sono emerse idee creative e innovative che hanno avuto la capacità di influenzare la ricerca industriale.
In realtà, negli ultimi mesi, l’interesse sembra essere risalito, ma l’evidente obsolescenza delle risorse messe a disposizione dalla documentazione ufficiale e dalla community disillude rapidamente i profili meno tecnici che provano a sperimentare questa tecnologia.
Per questo motivo abbiamo deciso di riprendere in mano il progetto di porting del TensorFlow Lite Micro su Arduino e rendere nuovamente disponibili risorse e materiale didattico in grado di consentire a creativi e appassionati l’inserimento del Tiny Machine Learning nei propri progetti, in modo intuitivo e nel tipico stile che caratterizza Arduino.
La libreria TensorFlow Lite per Arduino
La libreria ufficiale C++ TensorFlow Lite Micro è sviluppata e mantenuta da Google come collezione generale di file sorgenti in linguaggio C++. I file sono disponibili con licenza di tipo open source su un repository GitHub dedicato e separato dal repository generale del codice sorgente della piattaforma TensorFlow. Inizialmente i file erano contenuti all’interno del ramo Lite del repository TensorFlow, ma dal 2022 il codice è stato spostato in un repository dedicato. Chi è abituato a contribuire a progetti open source in rapida evoluzione conosce bene la struttura apparentemente caotica e spesso ridondata di questi archivi su GitHub. I file essenziali e più significativi sono mescolati in un intricato albero di directory e sotto-directory assieme a file di esempio, a codici sperimentali e a file di dubbia utilità. La documentazione esterna è praticamente inesistente e per orientarsi e cominciare ad entrare nel merito del progetto è necessario leggere il codice sorgente e studiarne struttura e commenti. L’idea di Google è che l’effettivo porting della libreria su una specifica piattaforma, come ad esempio mbed_nano Arduino o Raspberry Pi, sia svolto dal team di progettisti che ha interesse a farlo. Come abbiamo detto all’inizio di questo articolo, per dare delle linee guida su come effettuare questo processo di generazione di un progetto specifico, a partire dalla libreria generica, fu scelto dal team di Google di usare la scheda Arduino Nano 33 BLE come esempio. Fu quindi creata una versione della libreria adattata e funzionante su questa scheda Arduino e memorizzata su questo repository con il nome di TensorFlow Lite Micro Arduino Example, come si può vedere seguendo il link precedente. La parola “example” nel nome del repository si riferisce proprio al fatto che questo progetto doveva servire da esempio per chiunque avesse voluto adattare la libreria alla propria piattaforma. Al progetto parteciparono degli ingegneri di Arduino e la libreria fu registrata nel library register ufficiale di Arduino, con il nome Arduino_TensorFlowLite rendendola installabile automaticamente tramite l’IDE Arduino. Il repository GitHub di questa libreria fu mantenuto sincronizzato, attraverso le funzionalità automatiche offerte da GitHub, con la versione generica e non specializzata della libreria C++ sorgente, in modo che eventuali modifiche apportate ai file sorgenti originali fossero replicate sui file presenti nel repository derivato. Tuttavia, come sempre accade in questo tipo di progetti, poiché le operazioni di porting su piattaforme complesse come i microcontrollori richiedono una certa dose di lavoro manuale, questo allineamento automatico iniziò a non andare più a buon fine e nel 2022 fu interrotto. Dopo alcuni mesi fu chiesto ai mantainer del registry Arduino di rimuovere la libreria. Questo vuol dire che, da allora, la libreria non è più allineata con le ultime modifiche apportate al sistema TensorFlow Lite Micro e non è disponibile dall’IDE Arduino per l’installazione automatica. A peggiorare la situazione per i cultori di Arduino c’è da notare che gli allineamenti automatici effettuati tra il 2019 e il 2022 non hanno mai modificato il numero di versione che risulta essere ancora 2.0.4-ALPHA. I tutorial “Get Started With Machine Learning on Arduino” presenti sul sito Arduino nella documentazione ufficiale della scheda Arduino Nano 33 BLE Sense erano stati mantenuti aggiornati fino alla versione 2.0.4-ALPHA. Dopo la rimozione della libreria dal registry, il testo dei tutorial è stato aggiornato, specificando che la libreria deve essere scaricata dal repository GitHub “ufficiale”, e installata come file .zip. Peccato che la versione della libreria sul repository indicato non sia più la originale 2.4.0-ALPHA, ma una qualche versione più avanzata, ma comunque già obsoleta, ferma al 2022. Per questo motivo, chiunque provi a seguire le istruzione del tutorial termina il suo esperimento inondato da errori di compilazione. Se volete provare a tornare indietro nel tempo, e sperimentare il tutorial come se foste nell’anno 2019, potete procurarvi la vera versione 2.0.4-ALPHA scaricandola da questo link. Installando la versione originale del 2019 e non quella puntata dal link all’interno del tutorial, gli sketch di esempio saranno correttamente compilati e l’esperimento funzionerà. Se volete iniziare a sperimentare con una versione recente del TensorFlow Lite Micro su Arduino, invece, potete scaricare comodamente dall’IDE la nostra nuova libreria Chirale_TensorFlowLite. La libreria porta con se lo sketch di esempio “hello_world” che mostra come utilizzare il Tensor Flow Lite all’interno dello sketch. Abbiamo generato un nuovo progetto a partire dai file master aggiornati e generato una nuova libreria nello stile dell’originaria Arduino_TensorFlowLite. Sul Tiny Machine Learning, abbiamo reso disponibile l’ultima lezione del nostro nuovo corso Arduino Unchained in un corso acquistabile separatamente. Potete leggere tutti i dettagli accedendo alla piattaforma Accademia delle Arti Numeriche tramite il pulsante che segue.
Lo stile della libreria Arduino_TensorFlowLite, e quindi della nostra libreria, non è quello a cui sono abituati gli appassionati di Arduino.
Nel codice è presente una sintassi C++ molto tecnica e vengono utilizzati puntatori e altri tipi di dato solitamente evitati negli sketch Arduino.
Il nostro progetto è appena iniziato e i prossimi passi saranno proprio quello di rendere intuitiva e conforme allo standard Arduino questa libreria, in modo da facilitare l’accesso a questa importante tecnologia a tutta la community di creativi che opera con Arduino.