Skocz do zawartości

Elvis

Użytkownicy
  • Zawartość

    2540
  • Rejestracja

  • Ostatnio

  • Wygrane dni

    187

Elvis wygrał w ostatnim dniu 29 marca

Elvis ma najbardziej lubianą zawartość!

Reputacja

1118 Mistrz

2 obserwujących

O Elvis

  • Ranga
    8/10

Informacje

Ostatnio na profilu byli

Blok z ostatnio odwiedzającymi jest wyłączony i nie jest wyświetlany innym użytkownikom.

  1. Nie sprawdzałem jak jest w najnowszych wersjach, ale dawniej takiej opcji nie było - i nie był to błąd, ale raczej założenie projektowe (it's not bug, it's a feature). Problemem w przypadku tak skomplikowanych układów jak STM32MP1 jest konieczność współdzielenia peryferiów między równolegle działające rdzenie i systemy. GPIO są dobrym przykładem - projektant musi zadecydować, które piny przydzielić dla Linux-a, a którymi ma sterować rdzeń M4. Ponieważ w wersji "produkcyjnej" najpierw startuje Linux i to on jest głównym systemem, za konfigurację GPIO odpowiada ten system. Dlatego CubeMX nie generuje kodu inicjalizującego GPIO dla M4 - po prostu ma to zrobić A7. CubeMX generuje za to plik konfiguracyjny, czyli device-tree, który należy dodać do jądra linuxa - dzięki czemu piny zostaną skonfigurowane poprawnie jeszcze zanim kod na M4 zacznie działać. Niestety takie podejście nie sprawdza się w przypadku trybu inżynierskiego i w nim trzeba konfigurację GPIO napisać samemu. Ale to chyba nie jest zbyt skomplikowane zadanie
  2. Skoro nie masz jeszcze kopii zapasowej systemu, najwyższy czas ją przygotować: https://forbot.pl/blog/kopia-zapasowa-raspberry-pi-jak-skopiowac-karte-microsd-id29561 Na szczęście w przypadku RaspberryPi bardzo łatwo jest zachować dane - wystarczy wyjąć kartę microSD, a wszystko od nowa zainstalować na innej. Na koniec można po prostu przekopiować pliki konfiguracyjne, dane, bazy, itd. Oczywiście najlepiej byłoby naprawić obecny system, ale i tak lepiej tego nie robić na aktualnej i jedynej kopii. Więc jeśli chcesz poeksperymentować, to najpierw zrób backup, następnie odwiń go na inną kartę i zacznij naprawiać system. Jak coś pójdzie źle to zawsze można próbować jeszcze raz.
  3. STM32MP157 nie posiada pamięci flash, to nie jest mikrokontroler jak typowe STM32. Program dla rdzenia Cortex-M musi być załadowany do pamięci RAM i z niej wykonywany. Podczas debugowania można załadować program używając JTAG-a, natomiast w "produkcyjnej" wersji kod jest wczytywany z karty SD lub innej pamięci przez skrypt systemu Linux, albo bootloader.
  4. Proponuję nie zakładać nic ponad to, że ktoś szuka darmowej informacji kto i za ile taki projekt chciałby wykonać. Jak dla mnie tekst: "Budżet 10000zł. Jeśli nierealny proszę składać także wyższe oferty." oznacza, że to nie jest poważna oferta. Przecież nikt podając budżet nie zakłada, że szuka kogoś za więcej... cytując jak sądzę autora tej oferty "Gdzie sens? Gdzie logika?".
  5. Nigdzie i nikogo nie hejtowalem, chyba pod hejt znacznie bardziej pasuje zarzucanie komuś braku umiejętności. Jedyne co napisałem to ostrzeżenie, bo moim zdaniem w przypadku takich "anonimowych" ogłoszeń trzeba być ostrożnym. Szkoda czasu np. na pisanie oferty skoro ktoś przykładowo chce udowodnić że projekt powinien kosztować daną kwotę, zrobić badanie rynku, albo po prostu zyskać trochę rozgłosu w sieci.
  6. @atMegaTona nie słyszałeś nigdy o ogłoszeniach dawanych zupełnie nie po to żeby wykonać projekt? O tym właśnie pisałem odnośnie ostrożności - bo wcale nie jestem pewien, czy to ogłoszenie faktycznie ma na celu znalezienie wykonawcy, czy np. sprawdzenie za ile takie projekty są wykonywane, albo po prostu zrobienie komuś reklamy. Oczywiście mogę się mylić, ale jakoś zakres wymagań idealnie pokrywa się z tym co w EP i EdW opisuje jeden z zablokowanych użytkowników tego i innych forów... Więc jak dla mnie to nie ma żadnego budżetu, żadnego projektu, jest ogłoszenie, na które wielu naiwnych może się nabrać.
  7. A ja bym proponował mocno zastanowić się nad wiarygodnością "zlecenia" w tym temacie. Po pierwsze, ktoś sobie zadał sporo trudu, żeby napisać prawie dwie strony "wymagań". Wygląda to profesjonalnie, wreszcie jakieś poważnie wyglądające ogłoszenie - ale autor się nie podpisał. Bo chyba Fast Rabbit to nie imię i nazwisko, ani nazwa firmy. Więc jeśli ktoś spędza sporo czasu pisząc "ofertę", ale się nie podpisuje to istotne ostrzeżenie. Bo jeśli nie chce podawać swoich danych, to czego się obawia? Druga sprawa to same "założenia" projektu. Nawet po szybkim przeglądzie widać, że nic się tutaj nie zgadza. O samym działaniu rządzenia praktycznie brak informacji - 230VAC, termostat i 3 przekaźniki 8A to właściwie cały opis części wykonawczej... Natomiast o niepotrzebnych wodotryskach jest całe mnóstwo. Po co komu aż 3 wyświetlacze: oled, tft oraz matryca LED? Dlaczego aż tyle i dlaczego akurat 128x160 pikseli? to już 480x272, albo 128x128 będzie złe? Standard MISRA, który ma mieć jakieś związki z zawieszaniem... itd. itp. Prawdę mówiąc po przeczytaniu założeń mam nieodparte wrażenie, że pisał je ktoś związany z EdW i EP, kto ma opisane moduły pod ręką i z jakiegoś powodu chce z nich ulepić projekt... Mogę się oczywiście mylić, ale radziłbym ewentualnym zleceniobiorcom daleko idącą ostrożność - a moderatorom uwagę.
  8. @Harnas dziękuję za uwagi. Odczyt z plików, jak i samo przygotowanie danych jest oczywiście zrobione absolutnie nieprofesjonalnie. To co opisałem powstawało jako "dłubanina" metodą prób i błędów, a moim celem było uruchomienie przykładu z X-CUBE-AI, planowałem później wszystko zrobić od początku, ładniej, lepiej, i poprawniej oraz z ciekawszym czujnikiem (chciałem użyć czujnik gestów https://botland.com.pl/pl/czujniki-gestow/3065-apds-9960-czujnik-rgb-i-wykrywacz-gestow-33v-i2c-sparkfun-sen-12787.html). Plan był dobry, ale zabrakło czasu, więc opisałem po prostu to co udało mi się zrobić, za niedoskonałości bardzo przepraszam.
  9. W poprzednich częściach udało się zebrać dane treningowe oraz przygotować sieć neuronową. Zostało ostatnie i najprzyjemniejsze, czyli napisanie końcowego programu. Jako punkt wyjścia używam program w wersji użytej do zbierania danych. Jest w nim już praktycznie wszystko co potrzebne, czyli konfiguracja modułów peryferyjnych oraz odczyt danych z akcelerometru. Spis treści serii artykułów: Sztuczna inteligencja na STM32, czyli przykład użycia X-CUBE-AI cz.1 Sztuczna inteligencja na STM32, czyli przykład użycia X-CUBE-AI cz.2 Sztuczna inteligencja na STM32, czyli przykład użycia X-CUBE-AI cz.3 Przechodzimy do widoku CubeMX i odnajdujemy wyjątkowo kiepsko widoczny przycisk "Additional Software": Po jego naciśnięciu zobaczymy okno pozwalające na dodawanie modułów do naszego projektu. Nas interesuje moduł "STMicroelectronics.X-CUBE-AI". Jeśli wcześniej tego nie zrobiliśmy, musimy najpierw ten moduł pobrać i zainstalować. Niezbędne opcje zobaczymy w prawej części okna: Po instalacji modułu X-CUBE-AI wystarczy zaznaczyć checkbox i użyć podstawową funkcjonalność, czyli Core. Gdybyśmy planowali wykorzystanie sieci neuronowej w poważniejszym programie, takie ustawienie byłoby chyba najlepszą opcją. Jednak na potrzeby nauki możemy wykorzystać gotowiec i dodać jeszcze opcję "Application Template". Jakość kodu, który zostanie dodany jako "template" jest delikatnie mówiąc niezbyt imponująca. Dlatego napisałem, że lepiej chyba nie używać go w poważniejszych zastosowaniach - ale do nauki to bardzo wygodne rozwiązanie. Teraz możemy wrócić do głównego widoku CubeMX i odszukać moduł "STMicroelectronics.X-CUBE-AI" w kategorii "Additional Software": W środkowej części okna widzimy konfigurację modułu naciskamy przycisk-zakładkę z symbolem "+" i dodajemy naszą sieć. Domyślna nazwa to "network", ale warto ją zmienić na coś bardziej opisowego, ja wybrałem "forbot_ai". Następnie wybieramy typ modelu "Keras" oraz sam model, czyli nasz plik data2.h5 utworzony w poprzedniej części. Gdy wszystko jest już gotowe możemy nacisnąć przycisk "Analyze" i poczekać aż X-CUBE-AI sprawdzi, czy nasza sieć pasuje do wybranego mikrokontrolera. Wynik powinien wyglądać następująco: Jak widzimy cała skomplikowana sieć wykorzystuje 8.39KB pamięci flash oraz 72 bajty RAM. To bardzo mało jak dla STM32L475, ale nawet znacznie słabiej wyposażone mikrokontrolery mogą skorzystać z możliwości jakie dają sieci neuronowe. Natomiast w przypadku większych sieci możemy wykorzystać opcję kompresji. Po zapisaniu projektu i wygenerowaniu kodu zobaczymy dwie ważne zmiany w pliku main.c. Przed pętlą główną pojawi się wywołanie MX_X_CUBE_AI_Init(), a w samej pętli znajdziemy MX_X_CUBE_AI_Process(). Inicjalizacja nie będzie nas interesować i możemy zostawić wygenerowany kod bez zmian. Warto natomiast zapoznać się z treścią funkcji MX_X_CUBE_AI_Process(). Kod, który w niej znajdziemy może przyprawić o palpitacje serca, ale na szczęście to tylko przykład, chociaż chyba niezbyt udany. Możemy więc spróbować zrozumieć o co w tym kodzie chodzi - i szybko odkryjemy, że jedyne co istotne to wywołanie funkcji aiRun(), która przyjmuje dwa parametry: pierwszy to tablica z danymi wejściowymi dla sieci, a w drugiej pojawią się wyniki. Warto jeszcze odszukać jakie są wymiary tych tablic: AI_FORBOT_AI_IN_1_SIZE ma wartość 128, i jest to wielkość zdefiniowana podczas trenowania sieci, właśnie tyle danych musimy podać na wejście. Wielkość danych wynikowych znajdziemy w stałej AI_FORBOT_AI_OUT_1_SIZE, która ma wartość 2. Przykładowy kod wykonuje mnóstwo dziwnych operacji na typach danych, ale w rzeczywistości dane wejściowe i wyjściowe to zwykłe float-y. Możemy więc skasować wszystko co automat nam wygenerował i napisać pierwszy kod: void MX_X_CUBE_AI_Process(void) { /* USER CODE BEGIN 1 */ float nn_input[AI_FORBOT_AI_IN_1_SIZE]; float nn_output[AI_FORBOT_AI_OUT_1_SIZE]; aiRun(nn_input, nn_output); /* USER CODE END 1 */ } Taki program oczywiście nic nie robi, ani nie działa poprawnie, ale umieściłem go aby pokazać jak łatwe jest używanie sieci neuronowej. Musimy wypełnić tablicę nn_input danymi do przetworzenia, następnie wywołujemy aiRun() i w nn_output mamy wyniki. Poniżej wstawiam już pełny kod: static uint32_t next_ms = 1000; static float nn_input[AI_FORBOT_AI_IN_1_SIZE]; float nn_output[AI_FORBOT_AI_OUT_1_SIZE]; while (HAL_GetTick() < next_ms) {} next_ms += READ_DELAY_MS; lsm6_value_t acc; acc = lsm6_read_acc(); for (int i = 0; i < AI_FORBOT_AI_IN_1_SIZE - 1; i++) nn_input[i] = nn_input[i + 1]; nn_input[AI_FORBOT_AI_IN_1_SIZE - 1] = sqrt(acc.x * acc.x + acc.y * acc.y + acc.z * acc.z); aiRun(nn_input, nn_output); if (nn_output[0] >= 0.5f) HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET); else HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_SET); Tablica nn_input jest definiowana jako statyczna, aby zachować historię pomiarów. Pomiary są wykonywane co 20ms, stąd czekanie w pętli while. Następnie odczytywana jest wartość przyspieszeń z akcelerometru. Wyniki przechowywane w tablicy nn_input są przesuwane o jedną pozycję, a najnowszy pomiar dodawany jest na końcu. Następnie wywoływana jest funkcja aiRun() i przetwarzane są wyniki. nn_ouput zawiera dwie wartości - pierwsza pozycja to prawdopodobieństwo, że nie wykryto gestu, druga to że wykryto - ich suma wynosi 1, więc wystarczyłaby jedna wartość, ale tak była trenowana sieć. Na podstawie obliczonego prawdopodobieństwa gaszona lub zapalana jest dioda LED. Poniżej efekt działania program (z drobną poprawką o której za moment): Uczenie sieci wymaga dużej ilości danych treningowych, w sumie im więcej tym lepiej. Niestety przykładowa sieć była trenowana na bardzo małej próbce. Efekty były i tak bardzo dobre, ale po wykryciu gestu pojawiały się pewne "zakłócenia". Po pierwsze czas zapalenia diody był bardzo różny, po drugie czasem dioda zapalała się kilka razy. Oczywiście najlepiej byłoby spędzić więcej czasu ucząc sieć, ale ja zastosowałem pewne obejście. W programie, po wykryciu machania płytką dioda jest zapalana na 1s - sieć mogłaby to robić sama, ale o wiele łatwiej było zmienić program. Podsumowanie Projekt opisany w tych artykułach miał być jedynie pierwszym krokiem, taką próbą użycia X-CUBE-AI. Planowałem poprawić opisywane przykłady, dodać bardziej rozbudowany projekt z innym czujnikiem oraz wykorzystać bardziej zaawansowaną topologię sieci. Ale jak to z planami często bywa, zostały niezrealizowane. Mam jedna nadzieję, że opisane możliwości zachęcą czytelników do eksperymentowania ze sztuczną inteligencją w systemach wbudowanych oraz dzielenia się swoimi doświadczeniami. Spis treści serii artykułów: Sztuczna inteligencja na STM32, czyli przykład użycia X-CUBE-AI cz.1 Sztuczna inteligencja na STM32, czyli przykład użycia X-CUBE-AI cz.2 Sztuczna inteligencja na STM32, czyli przykład użycia X-CUBE-AI cz.3
  10. W poprzedniej części udało mi się zebrać dane treningowe, czas te dane wykorzystać oraz przygotować własną sieć neuronową. X-CUBE-AI pozwala na wykorzystanie sieci zapisanych za pomocą różnych bibliotek, zdecydowałem się wykorzystać Keras, która jest nie tylko bardzo łatwa w użyciu, ale jeszcze całkiem dobrze opisana. Wydawnictwo Helion ma o ofercie świetną książkę pt. "Deep Learning. Praca z językiem Python i biblioteką Keras", którą bardzo polecam i z której korzystałem intensywnie przygotowując ten artykuł. Spis treści serii artykułów: Sztuczna inteligencja na STM32, czyli przykład użycia X-CUBE-AI cz.1 Sztuczna inteligencja na STM32, czyli przykład użycia X-CUBE-AI cz.2 Sztuczna inteligencja na STM32, czyli przykład użycia X-CUBE-AI cz.3 Podstawą biblioteki Keras, jak i chyba większości innych związanych z AI jest język Python, więc poznanie chociaż jego podstaw jest niestety niezbędne. Kolejny brakujący element to zainstalowanie interpretera języka Python3 oraz potrzebnych bibliotek. Znacznym ułatwieniem jest wykorzystani gotowej "dystrybucji" o nazwie Anaconda. Ze strony projektu wystarczy pobrać program instalacyjny i zainstalować. Za jednym zamachem uzyskamy dostęp do języka Python3 oraz mnóstwa narzędzi pomocnych przy przetwarzaniu danych. Domyślna instalacja nie zawiera potrzebnych nam bibliotek, warto więc uruchomić program Anaconda Navigator oraz doinstalować pakiety: keras, tensorflow oraz matplotlib. Skrypty używane do trenowania sieci możemy pisać w dowolnym edytorze tekstu, a następnie uruchamiać jak każdy inny program w języku Python3, ale jest to dość niewygodne. Znacznie wygodniejszym i polecanym w wielu książkach rozwiązaniem jest wykorzystanie edytora Jupyter, albo jego nowszego kuzyna JupyterLab. W pakiecie Anaconda znajdziemy obie aplikacje. Wystarczy uruchomić wspomniany Anaconda Navigator, a w nim JupyterLab: Sam JupyterLab działa wewnątrz przeglądarki internetowej, co jest o tyle wygodne, że pozwala łatwo pracować na zdalnym komputerze - nie zawsze mamy bezpośredni dostęp do odpowiednio wydajnej maszyny, a pracując w narzędziach Jupyter możemy wykorzystać moc zdalnej jednostki. Co więcej możemy tak samo pracować na płytce typu Jetson Nano, jak i na potężnej stacji roboczej w chmurze. Zanim przejdziemy dalej warto nieco bliżej zapoznać się z zebranymi danymi. Napiszmy w pythonie prosty skrypt, który wczyta oraz przedstawi graficznie pobrane dane: Już na pierwszy rzut oka widać, że dane nie są tak łatwe do analizy jak nieco wyidealizowany przykład z wykrywaniem uderzeń serca. Na szczęście użycie sieci neuronowej zwalnia nas z obowiązku pisania programu, który będzie musiał te dane ręcznie przetwarzać. Jak pamiętamy, dane z akcelerometru to 3 liczby, które reprezentują wartości przyspieszenia względem osi XYZ. W przypadku rozpoznawania gestów możemy nieco uprościć sobie zadanie i obliczyć wypadkowe przyspieszenie. Jedna liczba to nie tylko mniej danych, ale i o wiele łatwiejsza prezentacja diagramów. Oczywiście tworząc bardziej zaawansowane projekty możemy wykorzystywać wszystkie dane. W każdym razie na wykresie widzimy jak wyglądają nasze dane źródłowe oraz momenty gdy podczas uczenia naciskany był przycisk. Poniżej jeszcze kilka przykładów kiedy następowało wykrycie samego gestu: Jak pamiętamy pomiary wykonujemy co 20 ms, ale jeden wynik nie wystarczy do stwierdzenia, czy nastąpiło wykrycie poszukiwanego gestu. Musimy więc pamiętać "historię" pomiarów. Jak pisałem w poprzedniej części, wybrałem pomiary co 20ms oraz wielkość okna pomiarowego 128 wyników. Więc nasza sieć na wejściu będzie dostawała ostatnie 128 pomiarów i ma stwierdzić - czy nastąpiło wówczas poszukiwane machanie płytką, czy nie. Teraz możemy utworzyć nowy projekt projekt w JupyterLab i zacząć trenować naszą bazę. W JupyterLab nasz skrypt można podzielić na fragmenty, edytować i uruchamiać niezależnie. Dzięki temu jeśli np. dostroimy parametry sieci, nie musimy uruchamiać całego skryptu - wystarczy ponownie wykonać zmienioną część. To ogromne ułatwienie oraz oszczędność czasu. Na początku mamy więc import używanych bibliotek: import math import numpy as np from keras import models from keras import layers from keras.utils import to_categorical Następnie podobnie jak poprzednio wczytanie naszych danych treningowych oraz wykonania niezbędnych obliczeń: f = open('data1.csv','r') values = [] results = [] for line in f: fields = line.strip().split(',') if len(fields) == 4: x = float(fields[0]) y = float(fields[1]) z = float(fields[2]) values.append([math.sqrt(x**2 + y**2 + z**2)]) results.append(float(fields[3])) f.close() print('number of values: {}'.format(len(values))) Teraz musimy zmienić trochę postać danych. Plik wejściowy to 6467 wierszy z wynikami. Do uczenia sieci chcemy jednak wykorzystać okna po 128 wyników, które dają na wyjściu odpowiedź czy wykryto uczony wzorzec, czy nie. Co więcej dane powinniśmy podzielić na część treningową oraz testową - właściwie powinna być jeszcze trzecia część przeznaczona do walidacji, jednak jako prosty pierwszy przykład mam tylko dwie części: trening i test. train_values = [] train_labels = [] test_values = [] test_labels = [] split = len(values) * 0.8 for i in range(len(values) - 128): if i < split: train_values.append(values[i:i+128]) train_labels.append(results[i+128]) else: test_values.append(values[i:i+128]) test_labels.append(results[i+128]) train_values = np.array(train_values).reshape(-1, 128).astype('float32') train_labels = np.array(train_labels).astype('float32') test_values = np.array(test_values).reshape(-1, 128).astype('float32') test_labels = np.array(test_labels).astype('float32') Przyznać się muszę do jeszcze jednego niedociągnięcia - dane powinny być również znormalizowane. Najpierw planowałem wykorzystać wszystkie składowe XYZ, a wówczas normalizacja nie była konieczna. Jednak przeliczenie przyspieszenia na wartość wypadkową wprowadziło stałą odpowiadającą przyspieszeniu ziemskiemu - a w skryptach już tego niestety nie uwzględniłem. Teraz najważniejsza część czy uczenie samej sieci. Struktura jest banalnie prosta i pochodzi bezpośrednio z przykładów opisywanych w książce "Deep Learning. Praca z językiem Python i biblioteką Keras" train_labels = to_categorical(train_labels) test_labels = to_categorical(test_labels) network = models.Sequential() network.add(layers.Dense(16, activation='relu', input_shape=(128,))) network.add(layers.Dense(2, activation='softmax')) network.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy']) network.fit(train_values, train_labels, epochs=5, batch_size=8) network.summary() Po uruchomieniu kodu zobaczymy podsumowanie naszej sieci: Jak widzimy dokładność uczenia to 0.9086, moglibyśmy uzyskać dużo lepsze rezultaty tworząc bardziej wyszukaną sieć, ale przykład jest ogromnym uproszczeniem. Warto zwrócić uwagę na liczbę parametrów: 2064 dla pierwszej i 34 dla drugiej warstwy. Musimy pamiętać, że te parametry trzeba będzie zapisać w pamięci mikrokontrolera - jednak niewiele ponad 2000 parametrów to bardzo mało i pewnie dałoby się uruchomić nawet na STM32F0. Zanim zakończymy tworzenie sieci, jeszcze dwie ważne sprawy. Pierwsza to testowanie. Wynik, który widzieliśmy wcześniej dotyczy danych, na których sieć była uczona - jednak ważniejsze jest jak zachowa się z danymi, których "nie widziała". Podczas przygotowywania danych 20% zostało zapisane w zmiennych test_values, test_results i teraz mogą posłużyć do sprawdzenia jak sieć radzi sobie z nowymi informacjami: Uzyskujemy dokładność na poziomie 89.35%, czyli podobnie jak dla danych użytych do trenowania sieci. Ostatnia rzecz to zapisanie samej sieci do pliku, czyli wywołanie: network.save('data2.h5') Teraz mamy plik data2.h5, który jest gotowy do użycia z X-CUBE-AI, co opiszę w kolejnej części. data2.zip Spis treści serii artykułów: Sztuczna inteligencja na STM32, czyli przykład użycia X-CUBE-AI cz.1 Sztuczna inteligencja na STM32, czyli przykład użycia X-CUBE-AI cz.2 Sztuczna inteligencja na STM32, czyli przykład użycia X-CUBE-AI cz.3
  11. Algorytmy związane z szeroko pojętą sztuczną inteligencją (AI, Artificial Intelligence) są ostatnio bardzo popularnym tematem. Na ogół AI kojarzy się z ogromnym zapotrzebowaniem na moc obliczeniową, wykorzystaniem GPU (Graphics Processing Unit) oraz obliczeniami w chmurze. Okazuje się jednak, że sztuczna inteligencja znajduje również zastosowanie w świecie mikrokontrolerów. Powstał nawet termin na określenie takich zastosowań - Edge AI. O tym jak popularny jest temat AI świadczy chociażby pojawienie się sprzętowych akceleratorów przeznaczone dla urządzeń wbudowanych, tzw. TPU (Tensor Processing Unit), przykładowo Google Coral, albo Intel Neural Compute Stick. Dostępne są również mikrokontrolery z wbudowanym TPU, np. Kendryte K210 . Spis treści serii artykułów: Sztuczna inteligencja na STM32, czyli przykład użycia X-CUBE-AI cz.1 Sztuczna inteligencja na STM32, czyli przykład użycia X-CUBE-AI cz.2 Sztuczna inteligencja na STM32, czyli przykład użycia X-CUBE-AI cz.3 Firma STMicroelectronics, czyli producent popularnych również na naszym forum układów STM32 postanowiła dostarczyć produkt związany z AI. Na razie nie oferuje sprzętowej akceleracji, ale możemy za darmo pobrać pakiet oprogramowania o nazwie X-CUBE-AI, który pozwala na łatwe wykorzystanie możliwości jakie daje sztuczna inteligencja. W niniejszym artykule postaram się opisać bardzo prosty przykład wykorzystania biblioteki X-CUBE-AI na płytce ewaluacyjnej z układem STM32L475. Planowałem napisać dłuższy artykuł na zakończony niedawno konkurs, ale w trakcie przygotowywania projektu odkryłem jak dużo muszę się jeszcze sam nauczyć, zanim będę w stanie dzielić się wiedzą. Jednak to co udało mi się poznać i zrobić postaram się opisać w tym temacie. Proszę jednak o wyrozumiałość, tematem sztucznej inteligencji zajmuję się wyłącznie hobbistycznie i cały czas się uczę, więc z góry przepraszam za niedoskonałości opisywanego rozwiązania. Wybór platformy sprzętowej Sztuczna inteligencja nie bez powodu kojarzy się z ogromnym zapotrzebowaniem na pamięć i moc obliczeniową, rozpoznawanie mowy lub obrazu jest chyba dobrym przykładem, gdzie moc chmury wydaje się niezbędna. Okazuje się jednak, że AI można również zastosować w znacznie mniej wymagających obszarach. Jakiś czas temu na forum pojawił się opis projektu czujnika HRV: Wykrywanie bicia serca na podstawie sygnału jest jednym z przykładów, gdzie algorytmy sztucznej inteligencji mogą znaleźć zastosowanie. Ja co prawda nie jestem entuzjastą projektowania urządzeń medycznych metodami mocno hobbistycznymi, ale wspomniany artykuł zachęcił mnie do wypróbowania X-CUBE-AI do wykrywania wzroca w pewnym sygnale. Jako platformę testową wybrałem płytkę B-L475E-IOT01A, wyposażoną w mikrokontroler STM32L475 oraz całkiem sporo interesujących modułów peryferyjnych, a co najważniejsze w akcelerometr LSM6DSL. Płytka posiada ogromny potencjał, ja wykorzystam tylko mały jej fragment: port UART do komunikacji z PC, przede wszystkim do wysyłania danych akcelerometr posłuży jako źródło sygnału przycisk wykorzystam do uczenia sieci dioda LED będzie sygnalizowała wykrycie gestu Zbieranie danych treningowych Danymi źródłowymi będą pomiary z akcelerometru. Podczas uczenia, po wykonaniu gestu, który chcę nauczyć sieć będę naciskał przycisk na płytce. Dane treningowe mają więc postać 4 liczb: odczytu z akcelerometru dla osi XYZ oraz stanu przycisku. Ponieważ obraz jest wart tysiąca słów poniżej filmik z uczenia sieci: Moim celem było nauczenie sieci wykrywania dwukrotnego machnięcia płytką. W sumie nie wyszło mi to trenowanie do końca, bo wcale nie łatwo jest taki gest wielokrotnie wykonywać i się nie pomylić. Więc ostatecznie sieć ma wykrywać dwu- lub więcej- krotne pobujanie płytką. Jednokrotne, albo dwukrotne wykonane z odstępem gesty mają być ignorowane. Oczywiście można sieć nauczyć właściwie dowolnego gestu, pod warunkiem oczywiście, że sami jesteśmy w stanie ten gest wielokrotnie wykonać (i nie stracimy cierpliwości). Dane z akcelerometru odczytuję co 20ms. Z moich obliczeń wyszło, że 128 wyników, czyli 2.56s w zupełności wystarcza na wykonanie interesującego mnie gestu. Wyniki pomiarów wysyłane są przez port szeregowy Uczenie polegało na włączeniu zapisu danych do pliku oraz cierpliwym machaniu płytką oraz naciskaniu przycisku po wykonaniu uczonego gestu. W wyniku powstał plik data1.csv data1.zip Program do zbierania danych został napisany w środowisku STM32CubeIDE, dzięki temu jego kod będzie można później wykorzystać od testowania wytrenowanej sieci. Sam program jest właściwie banalny, do jego napisania wystarczy w zupełności materiał kursu STM32F4. Skoro mamy już dane treningowe, czas przystąpić do najważniejszego, czyli uczenia sieci. W następnej części postaram się opisać jak możemy wykorzystać zebrane dane. Spis treści serii artykułów: Sztuczna inteligencja na STM32, czyli przykład użycia X-CUBE-AI cz.1 Sztuczna inteligencja na STM32, czyli przykład użycia X-CUBE-AI cz.2 Sztuczna inteligencja na STM32, czyli przykład użycia X-CUBE-AI cz.3
  12. Bez podstaw pythona raczej nie da się używać keras, ani nic sensownego w AI zrobić. Nie musisz być od razu pythonowym guru, ale postawy są niezbędne. Inaczej zostanie tylko uruchamianie gotowców i zabawa przygotowanymi przez kogoś sieciami.
  13. Wydaje mi się, że jeśli ktoś chce poznać lepiej uczenie maszynowe, to do tego przyda się dobra książka i bardzo mocny komputer, najlepiej z solidną kartą graficzną. Natomiast użycie AI w systemach embedded to trochę inny temat. I tak trzeba sieć wytrenować na PC, później zostaje już tylko konwersja na mikrokontroler i w tym faktycznie może pomóc AI-CUBE. Miałem o tym napisać artykuł, ale trochę zabrakło czasu.
  14. Pytanie tylko czy @SOYER jest bardziej zainteresowany nauką budowy frezarek, czy raczej ich wykorzystania. Bo zbudowanie frezarki, czy drukarki to dopiero początek. Ale oczywiście jak ktoś ma mnóstwo wolnego czasu i dużo pieniędzy, to niech buduje od podstaw, w końcu kto bogatemu zabroni
×
×
  • Utwórz nowe...