Učenje klasifikacije slik na ugnezdenih napravah (ESP32-CAM).
Avtor: Marcelo Rovai
Vedno bolj se soočamo z revolucijo vgradnje strojnega učenja. In ko govorimo o strojnem učenju (Machine Learning: ML), prva stvar, ki pride na misel, je klasifikacija slik, nekakšen ML Hello World!
Ena najbolj priljubljenih in cenovno dostopnih razvojnih plošč, ki že ima integrirano kamero, je ESP32-CAM, ki združuje Espressif ESP32-S MCU čip s kamero ArduCam OV2640.
Čip ESP32 je tako zmogljiv, da lahko obdeluje celo slike. Vključuje komunikacije I2C, SPI, UART ter PWM in DAC izhode.
Parametri:
- Delovna napetost: 4,75-5,25V
- Flash: privzeto 32Mbit
- RAM: notranji 520KB + zunanji 8MB PSRAM
- Wi-Fi: 802.11b/g/n/e/i
- Bluetooth: Bluetooth 4.2BR/EDR in standard BLE
- Podporni vmesnik (2Mbps): UART, SPI, I2C, PWM
- Podpora za TF kartico: največja podpora 4G
- IO vrata: 9
- Hitrost serijskih vrat: privzeto 115200 bps
- Razpon spektra: 2400 ~ 2483,5 MHz
- Oblika antene: vgrajena PCB antena, dobitek 2dBi
- Izhodni format slike: JPEG (podpira samo OV2640), BMP, SIVILA
- Upoštevajte, da ta naprava nima vgrajenega serijskega modula USB-TTL, zato bo za nalaganje kode v ESP32-CAM potreben poseben adapter, kot je prikazano na sliki 5
Ta vsebina je samo za naročnike
Če želite izvedeti več o ESP32-CAM, močno priporočam knjige in vadnice Ruija Santosa [1].
Namestitev ESP32-CAM na Arduino IDE
Odprite okno z nastavitvami iz Arduino IDE in pojdite na:
Arduino > Nastavitve
Vnesite spodnjo vrstico:
https://dl.espressif.com/dl/package_esp32_index.json
v polje ==> URL-ji upravitelja dodatnih plošč (Additional Boards Manager URLs) (slika 7)
Nato odprite upravitelja plošč. Pojdite na Orodja > Plošča > Upravitelj plošč… in vnesite z ESP32. Izberite in namestite najnovejši paket (slika 8).
Izberite ESP32 ploščo:
Na primer, AI-Thinker ESP32-CAM (slika 9)
Nenazadnje izberite vrata, kamor je priključen ESP32-CAM.
To je to! Naprava mora biti pripravljena. Naredimo nekaj testov.
Testiranje plošče z utripanjem LED-ice
ESP32-CAM ima vgrajeno LED-ico, ki je povezana z GPIO33. Torej ustrezno spremenite Blink skico, glej program 1.
Program 1:
#define LED_BUILT_IN 33 voidsetup() { pinMode(LED_BUILT_IN, OUTPUT); // Set the pin as output} // Remember that the pin work with inverted logic // LOW to Turn on and HIGH to turn off voidloop() { digitalWrite(LED_BUILT_IN, LOW); //Turn on delay (1000); //Wait 1 sec digitalWrite(LED_BUILT_IN, HIGH); //Turn off delay (1000); //Wait 1 sec }
Upoštevajte, da se LED-ica nahaja pod ploščo.
Testiranje WiFi
Ena od zvočnih značilnosti ESP32S je njegova WiFi povezljivost. Torej, preizkusimo njegov radio in skenirajmo WiFi omrežja okoli njega. To lahko storite tako, da zaženete enega od primerov kode, ki je priložen plošči.
Pojdite na Arduino IDE Primeri in poiščite WiFI ==> WiFIScan
Na serijskem monitorju bi morali videti WiFi omrežja (SSID in RSSI) v dosegu vaše naprave. Takole izgleda to, kar imam doma (slika 10).
Testiranje kamere
Za preizkus kamere lahko uporabite kodo, ki je na voljo na:
Examples ==> ESP32 ==> Camera ==> CameraWebServer
Izberite samo pravo kamero:
#define CAMERA_MODEL _AI_THINKER
in vstopite z omrežnimi poverilnicami:
constchar* ssid = "*********"; constchar* password = "*********";
Na serijskem monitorju boste dobili ustrezen naslov za zagon strežnika, kjer lahko nadzorujete kamero (slika 11)
V mojem primeru: http://172.16.42.26 (slika 12)
Uporaba vašega spletnega strežnika
Do sedaj smo lahko preizkusili vso ESP32-CAM strojno opremo (MCU in kamero) in tudi Wi-Fi povezljivost.
Zdaj pa zaženimo enostavnejšo kodo, da zajamemo eno sliko in jo predstavimo na preprosti spletni strani.
Ta koda je bila razvita na podlagi odlične vadnice avtorja Rui Santos z naslovom: ESP32-CAM fotografiraj in prikaži v spletnem strežniku.
Prenesite datoteko: ESP332_CAM_HTTP_Server_STA iz GitHuba, spremenite poverilnice za Wi-Fi in zaženite kodo.
Tukaj je rezultat (slika 13).
Poskusite pregledati kodo; lažje bo razumeti, kako deluje kamera.
Sadje in zelenjava – razvrstitev slik
Zdaj, ko imamo vgrajeno delujočo kamero je čas, da poskusimo s klasifikacijo slik.
Začeti bi morali trenirati model in nadaljevati s sklepanjem na ESP32-CAM. Za usposabljanje bi morali najti nekaj podatkov (pravzaprav na tone podatkov!).
Toda najprej potrebujemo cilj! Kaj želimo razvrstiti?
Pri TinyML naboru tehnik, povezanih s sklepanjem strojnega učenja na ugnezdenih napravah, bi morali zaradi omejitev (v tej situaciji predvsem pomnilnika) omejiti klasifikacijo na tri ali štiri kategorije.
Jabolka bomo ločili od banan in krompirja (poskusite lahko tudi druge kategorije).
Torej, poiščimo določen nabor podatkov, ki vključuje slike iz teh kategorij.
Kaggle [2] je dober začetek razvrščevanja sadja [3].
Ta nabor podatkov vsebuje slike naslednjih živil:
- Sadje – banana, jabolko, hruška, grozdje, pomaranča, kivi, lubenica, granatno jabolko, ananas, mango.
- Zelenjava – kumare, korenček, paprika, čebula, krompir, limona, paradižnik, redkev, rdeča pesa, zelje, solata, špinača, soja, cvetača, paprika, čili paprika, repa, koruza, koruza, sladki krompir, paprika, česen, grah, jajčevci.
Vsaka kategorija je razdeljena na niz (100 slik), test (10 slik) in validacijo (10 slik). Prenesite nabor podatkov s spletnega mesta Kaggle v svoj računalnik.
Usposabljanje modela z Edge Impulse Studio
Za usposabljanje bomo uporabljali Edge Impulse Studio, vodilno razvojno platformo za strojno učenje na robnih napravah.
Vnesite poverilnice svojega računa (ali ustvarite brezplačen račun) na Edge Impulse. Nato ustvarite nov projekt (slika 15)
Zajem podatkov
Nato v razdelku UPLOAD DATA iz računalnika naložite datoteke iz izbranih kategorij (slika 16)
Pomagalo bi, če bi končali s svojimi tremi kategorijami podatkov, branjem za usposabljanje (slika 17). Prav tako lahko naložite dodatne podatke za nadaljnje testiranje modela ali razdelite podatke o usposabljanju.
Impulse Design
Impulse zajame neobdelane podatke (v tem primeru slike), zajame značilnosti (spremeni velikost slik) in nato uporabi učni blok za razvrstitev novih podatkov.
Kot smo že omenili, je razvrščanje slik najpogostejša uporaba globokega učenja, vendar je treba za izpolnitev te naloge uporabiti veliko podatkov. Za vsako kategorijo imamo okoli 90 slik. Ali je ta številka dovolj? Sploh ne!
Potrebovali bomo na tisoče slik, da se bomo »učili ali modelirali«, da bi razlikovali jabolko od banane. Toda to težavo lahko rešimo s ponovnim usposabljanjem predhodno usposobljenega modela s tisočimi slikami. To tehniko smo poimenovali “Transfer Learning” (TL) (slika 18).
S TL lahko natančno prilagodimo vnaprej usposobljen model klasifikacije slik na naših podatkih, tako da dosežemo dobro zmogljivost tudi z relativno majhnimi nabori podatkov slik (naš primer).
Torej, začenši s surovimi slikami, jim bomo spremenili velikost (96 × 96) slikovnih pik in jih tako dali v naš Transfer Learning blok (slika 19).
Predprocesiranje
Poleg spreminjanja velikosti slik bi jih morali spremeniti v sivine, da ohranimo dejansko globino barve RGB. Pri tem bo vsak od naših vzorcev podatkov imel dimenzijo 9, 216 značilnosti (96x96x1). Če bi ohranili RGB, bi bila ta dimenzija trikrat večja. Delo s sivinami pomaga zmanjšati količino končnega pomnilnika, potrebnega za sklepanje (slika 20).
Ne pozabite pritisniti tipke “Shrani parametre”. To bo ustvarilo funkcije, ki se bodo uporabljale pri usposabljanju.
Usposabljanje (zajemanje in povečanje podatkov)
Leta 2007 je Google predstavil MobileNetV1 [4], družino nevronskih omrežij računalniškega vida splošnega namena, zasnovane za mobilne naprave, ki podpirajo klasifikacijo, odkrivanje in drugo. MobileNets so majhni modeli z nizko zakasnitvijo in nizko porabo, ki so parametrizirani tako, da izpolnjujejo omejitve virov različnih primerov uporabe.
Čeprav je osnovna arhitektura MobileNet že majhna in ima nizko zakasnitev, lahko velikokrat določen primer uporabe ali aplikacija zahteva, da je model manjši in hitrejši. Za izdelavo teh manjših in računsko manj dragih modelov MobileNet uvaja zelo preprost parameter α (alfa), imenovan množitelj širine. Vloga množitelja širine α je enakomerno tanjšati omrežje na vsaki plasti.
Edge Impulse Studio ima na voljo MobileNet V1 (96×96 slike) in V2 (96×96 in 160×160 slike), z več različnimi vrednostmi α (od 0,05 do 1,0). Najvišjo natančnost boste na primer dosegli s slikami V2, 160×160 in α=1,0. Seveda obstaja kompromis. Višja kot je natančnost, več pomnilnika (okoli 1,3M RAM-a in 2,6M ROM-a) bo potrebno za zagon modela, kar pomeni večjo zakasnitev.
V drugem skrajnem primeru bo manjši odtis dosežen z MobileNet V1 in α=0,10 (okoli 53,2 K RAM-a in 101 K ROM-a).
Za izvajanje tega projekta na ESP32-CAM bi morali ostati na spodnji strani možnosti, zagotoviti primer sklepanja, vendar ne z visoko natančnostjo.
Druga potrebna tehnika, ki jo je treba uporabiti pri globokem učenju, je povečanje podatkov. Povečanje podatkov je metoda, ki lahko pomaga izboljšati natančnost modelov strojnega učenja. Sistem za povečanje podatkov med vadbenim procesom naredi majhne, naključne spremembe vaših vadbenih podatkov (kot so obračanje, obrezovanje ali vrtenje slik).
Tu lahko vidite, kako Edge Impulse izvaja politiko povečanja podatkov za vaše podatke, glej program 2.
Program 2:
# Implements the data augmentation policy def augment_image(image, label): # Flips the image randomly image = tf.image.random_flip_left_right(image) # Increase the image size, then randomly crop it down to # the original dimensions resize_factor = random.uniform(1, 1.2) new_height = math.floor(resize_factor * INPUT_SHAPE[0]) new_width = math.floor(resize_factor * INPUT_SHAPE[1]) image = tf.image.resize_with_crop_or_pad(image, new_height, new_width) image = tf.image.random_crop(image, size=INPUT_SHAPE) # Vary the brightness of the image image = tf.image.random_brightness(image, max_delta=0.2) returnimage, label
Če ste med vadbo izpostavljeni tem spremembam, lahko preprečite, da bi vaš model uporabljal bližnjice, tako da si “zapomni” površne namige v vaših podatkih o vadbi, kar pomeni, da lahko bolje odraža globoke osnovne vzorce v vašem naboru podatkov.
Končna plast našega modela bo imela 16 nevronov z 10 % osipa za preprečevanje prevelikega števila vzorcev. Tukaj je rezultat usposabljanja (slika 21).
Rezultat ni odličen. Model je dosegel približno 77 % natančnosti, vendar je pričakovana količina pomnilnika RAM, ki bo uporabljen med sklepanjem, precej majhna (okoli 60 KB), kar je zelo dobro.
Uvajanje in zagon
Izurjeni model bo nameščen kot Arduino.zip knjižnica, ki se bo uporabljala na določeni ESP32-CAM kodi (slika 22).
Odprite svoj Arduino IDE in pod Sketch pojdite na Include Library in add.ZIP Library. Izberite datoteko, ki ste jo pravkar prenesli iz Edge Impulse Studio in to je to!
Pod zavihkom Primeri v Arduino IDE bi morali najti kodo skice pod imenom svojega projekta (slika 23).
Odprite Static Buffer primer (slika 24).
Vidite lahko, da je prva vrstica kode točno klic knjižnice, ki bo imela vse potrebno za izvajanje sklepanja na vaši napravi.
#include <ESP32-CAM-Fruit-vs-Veggies_ inferencing.h>
Seveda je to generična koda (»predloga«), ki dobi samo en vzorec neobdelanih podatkov shranjenih v spremenljivki: features = {} in zažene klasifikator, pri čemer izvede sklepanje. Rezultat je prikazan na serijskem monitorju.
Kar moramo storiti je, da dobimo vzorec (sliko) iz kamere, jo predhodno obdelamo (spremenite velikost na 96×96, pretvorimo v sivine in ji znižamo resolucijo. To bo vhodni tenzor našega modela. Izhodni tenzor bo vektor s tremi vrednostmi, ki prikazujejo verjetnosti vsakega od razredov (slika 25).
Na spletnem mestu [5] je Edge impulse prilagodil kodo, ki je na voljo za testiranje kamere (Primeri ==> ESP32 ==> Camera ==> CameraWebServer), vključno s tisto, kar je potrebno da zaženete sklepanje na ESP32-CAM.
Na GitHub prenesite kodo Basic-Image-Classification, vključno s knjižnico vašega projekta, pri čemer izberite svojo kamero in poverilnice za WIFi omrežje (slika 26).
Naložite kodo v vaš ESP32-CAM in že boste lahko začeli razvrščati svoje sadje in zelenjavo! To lahko preverite na serijskem monitorju (slika 27).
Testiranje modela (sklepanje)
Slika 28. Če dobite fotografijo s kamero, se bo rezultat razvrstitve prikazal na serijskem monitorju (slika 29).
Sliko kot, ki jo je posnela kamera, je mogoče preveriti na spletni strani (slika 30). Drugi testi (slika 31,32).
Zaključek
ESP32-CAM je zelo prilagodljiva, ni draga in enostavna naprava za programiranje. Projekt bi lahko dokazal potencial TinyML, vendar nisem prepričan, ali je mogoče splošne rezultate uporabiti v resničnih aplikacijah (na način, kot je bil razvit). Samo najmanjši model Transfer Learning je deloval pravilno (MobileNet V1 z α=0,10) in vsak poskus povečanja natančnosti z uporabo večjega α je povzročil napako pri dodelitvi Arene. Morda je eden od razlogov za to količina pomnilnika, ki je že uporabljena na končni splošni kodi za zagon kamere. Torej je naslednji korak v projektu optimizacija končne kode, s čimer se sprosti več pomnilnika za zagon modela. V mojem GitHub skladišču boste našli zadnjo različico kod: ESP32-TinyML [6].
Kot vedno upam, da bi lahko ta projekt pomagal drugim, da se znajdejo v razburljivem svetu umetne inteligence, elektronike in interneta stvari!
Viri:
1: https://bit.ly/3Ngmqd7
2: https://en.wikipedia.org/wiki/Kaggle
3: https://bit.ly/36Ub3ax
4: https://research.googleblog.com/2017/06/mobilenets-open-source-models-for.html
5: https://github.com/edgeimpulse/example-esp32-cam
6: https://github.com/Mjrovai/ESP32-TinyML
Povzeto po:
https://bit.ly/3DbF15I