Pozdrav svima. 

 

Zadnji članak koji sam bio napisao bio je na temu prepoznavanja znakovne abecede pomoću umjetne inteligencije – https://exact-byte.com/hr/mobilna-aplikacija-za-prepoznavanje-znakovne-abecede/

 

U međuvremenu, radio sam još jednu aplikaciju, ovaj puta za jednu firmu u okolici.

Izradio sam aplikaciju koja na uređaju sličnom RaspberryPI (više informacija ovdje – https://www.raspberrypi.com/) može prepoznavati da li je auto zauzelo parkirno mjesto i da li je koje parkirno mjesto slobodno. RaspberryPI nije baš moćan uređaj, a i ne radi baš idealno sa nekim zahtjevnim operacijama kao što je prepoznavanje objekata u realnom vremenu, ali rješenje do kojeg sam došao prilično je solidno.

Uređaj, iako se grije i zahtjeva aktivno hlađenje, može prepoznavati 20ak vozila za nekih 5 sekundi. Može raditi sa više parkinga, ali redom – drugim riječima, dva parkinga za 10 sekundi.

 

Orange PI na slici:

 

Inicijalna ideja

Originalna ideja iza projekta je bila koristiti nešto jako slično ovome ovdje – https://school.geekwall.in/p/SJRJn01Nr

 

Dakle, ako imamo jedan parking, kao na slici:

I da možemo definirati parkirno mjesto kako mi želimo – mi u samoj aplikaciji definiramo (“narctamo”) gdje je parkirno mjesto, te ga označimo na samoj slici, kao na sljedećem primjeru.

Da na parkingu bude detektirano svako vozilo, kao na slici:

I ako je na tom označenom mjestu stvarno auto, parkirno mjesto je zauzeto.

Rezultat na kraju želimo dobiti putem API-a – dakle, rezultat se upisuje u bazu podataka, te u svakom trenutku možemo dohvatiti podatak putem REST API-a.

Kako bi izgledao primjer jednog REST API poziva? Ovako nekako:

{
“parking_spots”:[
{
“camera_code”:”KAR”,
“camera_no”:1,
“code”:”001″,
“occupied”:true,
“occupied_prob”:0.8399547182707505
},
{
“camera_code”:”KAR”,
“camera_no”:1,
“code”:”002″,
“occupied”:true,
“occupied_prob”:0.6102702405195662
}
]
}

Za izradu projekta korišten je Python 3.7, Flask, SQLAlchemy, PyTorch i ostali pomoćni library.

Što odabrati za arhitekturu?

Pitanje je koju arhitekturu odabrati za ovakav jedan projekt. 

 

Inicijalna arhitektura bazirala se na dva servisa, jedna regularna Python Flask web aplikacija sa bazom koja sadržava backend i frontend, a drugi servis ML servis na koji se šalju upiti.

Taj drugi ML servis je u biti wrappiran sa TorchServe (https://pytorch.org/serve/) te servira model out of the box.

 

Iako je u inicijalnom primjeru Mask R-CNN korišten kao arhitektura jer zbog svoje preciznosti, što je ujedno arhitektura za detekciju objekata, teško je tako nešto koristiti na jednom malom uređaju kao što je RPi.

To je zato što takvoj arhitekturi, koja je prilično zahtjevna, treba otprilike 30-40 sekundi da obradi jednu sliku! Točno, 30-40 sekundi za jednu sliku!

 

Ne moram objašnjavati koliko se taj mali uređaj zagrije kada pokuša tako nešto. Pogotovo ako pokuša raditi sa više parkinga koji sadržavaju više parkirnih mjesta.

 

Definitivno ne može raditi cijelo vrijeme jer se nakon 20 minuta pregrije i počne gasiti. Čak sam testirao mjerenje temperature sa 3 različitih parkinga i pauzom od 5 sekundi između da vidim kako radi i zaključak slijedi:

The temperature starts to jump closer and closer to 70, where the device simply starts to shut down the cores, which increases the load on the processor, heats up further, and after a while, it shuts down.

Is it necessary to use object detection architecture at all? Can we do something with the “ordinary” image recognition?

Klasifikacija slika

Klasifikacija slika je puno manje zahtjevan problem od detekcije objekata. Program uzme pojedinu sliku i vrati što “vidi” na slici.

Nije potrebno da algoritam vrati i regije gdje je pronašao objekte, već postoji pretpostavka da je na slici jedan objekt, te je potrebno taj jedan objekt klasificirati.

Ali problem nastaje kada na slici imamo dva objekta, a od programa zatražimo da nam da jedan odgovor oko toga što se nalazi na slici.

Što je ono što ćemo dobiti ovdje nazad? Ne možemo reći da naš algoritam radi krivo ako dobijemo odgovor “mačka” ili “pas” nazad. Ali ono što nas zanima nije samo što se nalazi na slici već i da li postoji više objekta na slici. Zašto? Jer možemo zamisliti ovakvu situaciju.

Da li želimo detektirati da je ovdje stablo prisutno na slici, ili želimo (i?) detektirati da je auto na slici? To jesu dva zasebna objekta, ali greška bi bi bila da netko ovako označi parkirno mjesto, koliko bi bila i greška kada bi odgovor koji bi dobili nazad bio “stablo”, jer bi time broj parkirnih mjesta bio manji nego što zapravo jest.

 

U svakom slučaju, problem sa klasifikacijom slika je što ne dobijemo sve podatke nazad i teško možemo zamisliti kako bi program radio kada bi korisnik označio sliku i mi bismo samo rekli da li je na slici auto ili nije. Jer samo sa tim podatkom ne možemo odgovoriti nekome kada pita “zašto se ja nisam mogao ovdje parkirati iako piše da je ovdje slobodno mjesto za parkiranje?”. Odgovor “naša neuralna mreža nije detektirala slobodno mjesto jer mislila da je na tom mjestu stablo” nije odgovor koji netko želi čuti.

 

Naravno, primjer je preuveličan sa razlogom. Ali pogledajmo malo realniji primjer, koji se isto nalazi na slici.

Tko nama garantira da pod nekim uvjetima naš algoritam, koji je “glup” po puno pitanja, te se teško može usporediti sa zdravim razumom čovjeka, neće u jednom trenutku vratiti odgovor na pitanje što se nalazi na slici – “grmlje” ili “livada”?

 

Tko nam garantira da ako osoba u tom trenutku prelazi preko parkirnog mjesta, iako je tamo parkiran auto, naš algoritam odluči vratiti “osoba” kao odgovor na pitanje što vidi na tom mjestu?

 

Da skratimo ovu priču, sama klasifikacija slika, u ovom slučaju, nije dovoljno robusna – nije dovoljno otporna na greške, ili na situacije koje se mogu pojaviti u svakodnevnici. Samim time, ovo nije dobro rješenje za detekciju parkirnih mjesta.

Detekcija objekata

Moguće je, naravno, da čak i kada se koristi detekcija objekata da imamo slične probleme.

 

Na koji način, čak i kada detektiramo sva vozila na slici, možemo biti sigurni da je određeno parkirno mjesto zauzeto?

Ako uzmemo primjer, opet sa slike, sa ovakvom konfiguracijom, možemo jednostavno procijeniti da li je auto na parkirnom mjestu. Vidimo da je crveni kvadratić koji označava parkirno mjesto unutar zelenog, stoga je to mjesto očito zauzeto.

Ali što da na to mjesto dođe kamion? Da li bi to važilo? Ne. A da na to mjesto dođe malo veće vozilo? Isto tako, moguće da ne bi radio. Da bi onda trebali svaliti krivnju na glupe ljude koji ne razumiju da je ovo “samo program” i da treba savršeno jasno definirati granicu parkirnog mjesta? Ili postoji bolji način?

Odgovor koji je autor članka dao (https://school.geekwall.in/p/SJRJn01Nr) čini se prilično smislen. Jednostavno ćemo izračunati da li je presjek tih dviju kvadrata velik. Takva mjera, zvana “Intersection over Union” (presjek naspram unije) je jednostavna mjera koja računa koliko je kvadrat parkirnog mjesta preklopio pronađeno vozilo? U ovom, našem slučaju, to je super. Stvar radi.

Ali kolika je ta mjera? Koliko mora biti preklapanje? 50%? 60%? 70%?

Problem nastaje u definicije ove preciznosti. Na 100%, došli smo na originalni problem – kvadrati se moraju savršeno podudarati. To je teško. 

 

Što bi bilo da stavimo ovu vrijednost na 50%? Ili manje? Jer, ruku na srce, što je najgore što se može dogoditi?

 

Pa može se dogoditi ovo.

Sada, možemo čak i odokativno vidjeti da ako vrijednost ovog preklapanja negdje oko 0.7 onda će algoritam vratiti vrijednost da auto je na toj poziciji. Zašto? Zato što oko 30% auta sa drugog parkirnog mjesta “ulazi” u naš kvadrat. Ali prepotstavimo da je to riješivo tako da stavim da vjerojatnost bude oko 50%. 

 

Što se može dogoditi? Možemo zamisliti da se netko parkirao pored na mjesto pored. Ako je to veće vozilo ili se parkiralo bliže našem parkirnom mjestu jako lako možemo zamisliti da je kvadrat pun sa više od 50%. To je rješivo ako gledamo preklapanje samo jednog vozila, ali opet možemo zamisliti situaciju gdje automobil može zauzimati manje od 50%.

 

Da skratim ovu priču, postoji u praksi jako puno dobrih razloga zašto je ovako nešto previše rigidno kada se koristi na jednom manje idealnom parkingu.

Finalno rješenje

Što je onda finalno rješenje? Finalno rješenje je prilično jednostavno i prilično briljantno, jer se ne čini tako očito na prvu. Isto tako, puno je brže za računanje.

Ta ideja da mi imam parkirno mjesto na koje dolazi vozilo je točno, ali zbog samog načina na koji smo definirali taj korisnički zahtjev, vezani smo da taj veći kvadrat bude parkirno mjesto, a manji kvadrat vozilo.

Jesmo li vezani ili možemo nešto napraviti po tom pitanju?

Dakle, tu stoji rješenje cijele zagonetke. Definiramo male kvadrate koje stavimo na parkirno mjesto na sredinu i vozilo htjelo ili ne, mora zauzeti centar parkirnog mjesta. Na slici možemo vidjeti male zelene kvadrate (desno od ovog selektiranog).

Više nema dodatnih računica i razmišljanja i stvar je jako jednostavna – da li se kvadrat parkirnog mjesta nalazi unutar detektiranog vozila?

 

Da – parking je zauzet, ne – slobodan je.

 

Ovakva rješenja su jako lijepa jer nisu intuitivna a savršeno se poklapaju sa zahtjevom.

Ograničenja

Naravno da postoje ograničenja. Na upit korisnika pogledao sam koliko je neuralna mreža uspješna u detekciji vozila iz “ptičje perspektive”.

 

Zaključak je da aplikacija nije baš uspješna u detekciji vozila iz zraka, te ima jako malu točnost. Otprilike, detektira 5 od 50 vozila kada “gledamo” iz “ptičje perspektive”. Pretpostavka je da je to posljedica malog broja slika snimanih iz “ptičje perspektive” koji su se koristili za trening te neuralne mreže.

 

Idealno bi bilo kada bismo došli do slika takvih parkirališta i neuralnu mrežu istrenirali da prepoznaje vozila i iz takve perspektive. Da bismo to mogli, morali bismo označiti sva vozila (labelirati) na velikom broju slika, kako bi pravilno naučila prepoznavati vozila.

Zaključak

Da sumiram cijelu priču, potrebno je koristiti detekciju objekata sa nekim bržim arhitekturama neuralnih mreža. 

 

Isto tako, najlakše bi bilo koristiti manji kvadratić ili jednostavnu točku za oznaku parkirnih mjesta, kako bi onda detekcija objekata mogla detektirati vozilo na parkirnom mjestu sa što robusnijim rezultatom.

 

Aplikacija radi jako precizno kada koristimo kamere nekakvih uobičajenih perspektiva, ali kada te kamere pomaknemo iz “ptičje perspektive”, program nije moguće koristiti osim ako se ne trenira na dodatnim primjerima iz takve perspektive.