Metoda mea de abordare a unui proiect real de Machine Learning
Te incurajez sa citesti pana la final acest articol, chiar daca este mai lung, pentru ca am o super surpriza pentru tine.
Acest articol reprezinta episodul [3/4] dintr-o mini serie pe care o transmit abonatilor mei la newsletter.
Deoarece este un episod foarte important in care descriu in detaliu metoda mea de abordare a unui proiect real, am decis sa il postez si aici.
Ce s-a discutat in materialele trecute?
Sa facem o foarte scurta recapitulare asupra a ce am discutat in primele 3 episoade:
- Oportunitatea uriasa oferita de AI in 2021 si de ce este cel mai bun moment din istorie sa incepi o cariera in acest domeniu
- Pentru a avea succes in AI nu trebuie sa te concentrezi doar pe algoritmi. Trebuie sa vezi imaginea de ansamblu. Datele sunt de multe ori cea mai importanta piesa din schema.
- Pentru a intelege un concept complex, trebuie sa abordezi problema de la coada la cap si sa intelegi mai intai conceptele simple care stau in spate. Sa o iei din aproape in aproape.
Bun, așa cum am zis, în acest material o sa detaliez fiecare etapa din metoda de care ti-am vorbit. Pe un caz concret.
Alegerea proiectului
In primul rand, va trebui sa alegem o tema de proiect. Data fiind situatia epidemiologica actuala, am considerat ca ar fi oportun sa implementam un sistem de supraveghere video in care sa detectam daca oamenii poarta sau nu masca de protectie.
De asemenea, consider ca aceasta tema:
- Reprezinta un proiect interesant/provocator
- Se poate pivota in foarte multe directii si sa se obtina un produs cu impact in societate
- Ne trece prin toate etapele de invatare, inclusiv colectarea semi-automatizata a datelor
Daca reusesti sa implementezi un astfel de proiect, vei putea replica si adapta metoda cu succes si in alte proiecte.
Fara sa o mai lungim, haideti sa incepem:
1. Intelegerea problemei
In aceasta etapa trebuie sa ne formam o imagine de ansamblu asupra proiectului.
Foarte important, inainte sa scriem orice linie de cod!
Trebuie sa ne punem intrebari (si sa gasim raspunsuri) precum:
- Ce fel de problema este aceasta? -> Pai este o problema de clasificare binara. Trebuie sa clasificam daca oamenii poarta sau nu poarta masca.
- Care este input-ul? -> In cazul nostru va fi stream-ul video (frame-uri) de la camera web, adica imagini RGB.
- Ce se intampla daca avem mai multe persoane simultan intr-un frame? -> Va trebui sa facem mai intai o detectie, adica sa gasim toate fetele oamenilor din imagine, apoi sa clasificam fiecare fata in parte.
Deci, va fi o abordare in 2 pasi, folosind doi algoritmi: unul pentru detectia fetei si unul pentru clasificarea binara.
- Cum realizam detectia de fete? -> Aici trebuie facut un research in prealabil. Putem folosi un algoritm bazat pe procesare de imagini (de ex HOG/Haar Cascade) sau o alta retea neurala (de ex Yolo).
- Cum masuram performanta algoritmului? -> Metrica care se foloseste pentru clasificare este in general scorul F1.
Aceasta este o medie ponderata dintre precizie si recall.
- Cum arata mediul in care va rula acest algoritm? -> Este foarte important sa cunoastem acest aspect, ca sa stim ce fel de date de antrenare vom folosi.
Pentru simplitate, sa spunem ca va rula in camera unde lucrezi, pe webcam-ul tau.
- Care este performanta minima la care vreau sa ajung? -> As spune ca un scor F1 de 95% ar face ca algoritmul sa fie suficient de robust.
Primele concluzii: in linii mari algoritmul nostru va rula in 2 pasi conform schemei de mai jos:
Acest proces (cei 6 pasi) este unul iterativ.
In prima faza ne straduim sa implementam un proof-of-concept (adica cea mai simpla varianta a algoritmului) cat mai repede cu putinta, observam rezultatele obtinute, iar apoi modificam si imbunatatim cu scopul de a atinge performanta dorita.
De asemenea, este important sa gandim foarte modular implementarea. Un anumit modul nu trebuie sa faca decat un task foarte simplu. In acest mod va iesi o solutie cat mai robusta.
In proiectul nostru, nu avea rost sa folosim aceeasi retea pentru ambele task-uri de detectie si clasificare.
Ar fi fost un task mult prea complicat pentru o singura retea neurala iar acuratatea ar fi avut de suferit.
2. Colectarea datelor
Aici, dragii mei cititori, incepe distractie. Vreau sa retineti urmatoarea afirmatia:
Un set de date bun este mai important decat o retea neurala foarte complexa.
Am sa ma repet!
Un set de date bun este mai important decat o retea neurala foarte complexa.
Vreau sa intelegi foarte bine acest aspect pentru ca reprezinta cheia succesului in Machine Learning.
Vei obtine rezultate grozave daca vei avea un set de date bun si aplici un algoritm mai vechi/slab. In schimb daca ai un set de date slab, poti aplica ultimul algoritm state-of-the-art de la Google, rezultatul va fi mult mai slab.
Un set de date ‘bun’ este caracterizat in mare prin doua atribute:
- Este suficient de mare
- Datele sunt de calitate
Ce inseamna de calitate, aici avem de asemenea o discutie lunga:
- Datele trebuiesc sa fie anotate corect.
- Sa nu fie date corupte
- Sa nu fie zgomot
- Sa existe suficient de multa varianta in date
- Datele de intrare sa fie reprezentative pentru cele de iesire
- Datele sa fie echilibrate din punct de vedere al distributiei claselor, fie ca vorbim de regresie/clasificare
Procesul de colectare a datelor se face in doi pasi:
- Facem achizitia efectiva de date. In cazul nostru, inregistram mai multe imagini de la camera web.
- Le anotam. Adica punem o eticheta fiecarei imagini in care spunem unde este fata noastra, si daca aveam sau nu masca.
Trebuie sa construim setul de date astfel incat acesta sa fie cat mai echilibrat si sa existe cat mai multa variabilitate in acelasi timp.
In cazul proiectului nostru, pentru a obtine variabilitate:
- Va trebui sa capturam imagini la diferite momente ale zilei, cand intensitatea luminii este diferita
- Va trebui sa avem mai multe persoane in imagini, pentru a evita ca algoritmul sa invete doar fata noastra. Ar fi ideal ca persoanele sa fie si ele variate (de la varsta, sex, culoarea pielii etc)
- Va trebui sa schimbam periodic pozitia camerei web, pozitia capului (sa fie mai multe unghiuri), poate hainele cu care suntem imbracati, masca pe care o purtam etc
In acest proces trebuie sa fim creativi.
Practic incercam sa simulam cat mai multe situatii ce pot aparea in momentul in care algoritmul va rula in productie.
Pentru echilibrare:
- Va trebui sa avem un numar aproximativ egal de imagini din fiecare clasa, pentru a evita bias-ul. Ce inseamna asta concret, numarul de imagini in care purtam masca sa fie egal cu cel in care nu purtam.
- Legat de intensitatea luminoasa. De exemplu, nu ar fi indicat sa avem 90 de imagini la pranz cand lumina este foarte buna si doar 10 imagini seara cand folosim lumina de la bec.
- Alte aspecte. De exemplu, nu ar trebui sa avem 90% din poze cu o singura masca albastra, si doar 10% cu o masca de alta culoare (negru spre exemplu)
Si lista poate fi foarte lunga, dar pentru un moment ne vom rezuma doar la acestea. Pe scurt, setul de date trebuie sa fie cat mai echilibrat din toate perspectivele.
Ne vom construi un script in Python, cu ajutorul caruia vom face achizitia de imagini, urmand sa le anotam.
In mod normal procesul de achizitie si anotare ar dura foarte mult timp, dar iti vor arata cum sa faci acest lucru intr-un mod foarte eficient, aproape automatizat.
Pentru detectia fetei poti folosi o retea neurala pre-antrenata pe acest task, iar la final sa corectezi cazurile unde reteaua a gresit (care vor fi foarte putine in comparatie cu anotarea tuturor)
Pentru clasificarea “masca VS nu masca” este foarte simplu. Poti face in prima faza doar poze cu masca si sa le pui intr-un folder, iar dupa pozele fara masca.
3. Preprocesarea datelor
In majoritatea proiectelor in care am lucrat aceasta etapa a fost cea mai costisitoare din punctul de vedere al timpului investit.
Acest lucru deoarece nu dispuneam eu de resurse pentru a construi setul de date si foloseam unul gata facut.
Asadar, pe setul de date pe care il aveam la dispozitie trebuia sa fac o inspectie manuala in care sa verific cat este de echilibrate, daca exista date corupte etc.
In aceasta etapa trebuie de asemenea sa fim creativi. Trebuie sa ne punem urmatoarea intrebare:
Ce pot face eu cu aceste date astfel incat modelului meu sa-i fie cat mai usor sa sa isi indeplineasca task-ul (in cazul nostru clasificarea fetelor)?
Un exemplu ar fi: cum pot eu selecta doar informatia relevanta din datele respective, astfel incat modelului sa-i fie usor sa clasifice masca/nu masca.
O solutie ar putea fi transormarea imaginilor RGB in alb-negru. Nu prea ne ajuta cu nimic informatia cu privire la culoare pentru a ne da seama daca purtam sau nu masca.
In acest mod cantitea de informatie care intra in model va fi de 3 ori mai mica, dar la fel de relevanta.
Cu cat oferim mai multa informatie modelului care nu este 100% relevanta pentru task-ul pe care il antrenam cu atata riscam ca el sa faca overfitting (adica va invata pe de rost datele din setul de train)
Ca sa afli cum gasesti informatia relevanta, poti sa-ti pui urmatoarea intrebare: “ca eu sa imi dau seama daca o persoana poarta sau nu masca, la ce ma uit?”.
Dupa ce avem un raspuns, incercam sa extragem acel lucru si obtinem un “feature” care va intra in model.
In acest proiect este evident (de aceea am ales si aceasta tema mai simpla), dar de multe ori acest pas poate fi dificil.
Informatia relevanta se afla doar de la barbie la nivelul nasului, deci ideal ar fi sa putem face un crop doar acelei portiuni si sa il servim modelului.
Acest lucru este putin dificil de facut deoarece vom mai avea nevoie de un model sa faca acel crop.
Insa, putem face crop intregii fete. Este o problema ce a mai fost rezolvata in trecut si avem multe materiale ajutatoare (adica modele deja antrenate sa faca acest lucru cu acuratete ridicata)
In continuare, trebuie sa facem datele sa arate similar din punct de vedere numeric, printr-un proces numit normalizare.
Un tip de normalizare ce se foloseste foarte des in practica re-scaleaza toate valorile pixelilor din imagini, astfel incat acestia sa fie in intervalul 0–1.
Reteaua va fi mai stabila in timpul antrenarii daca datele sunt intre 0 si 1.
Formula pentru rescalare este foarte simpla:
Unde x reprezinta pixelul curent, min(x) pixelul cu cea mai mica intensitate din imagine iar max(x) cu cea mai mare.
4. Pipeline de antrenare si testare
Foate multi din programatorii aflati la inceput de drum cred ca AI-ul presupune doar dezvoltare modelului si antrenarea/testarea acestuia, adica acest pas.
In acesa etapa se realizeaza implementarea retelei neurale (sau model, cum l-am mai numit) ce va primi ca si intrare o imagine cu fata, si va servi drept iesire o valoarea booleana: 0 (nu are masca) SAU 1 (are masca).
Trebuie sa implementam de asemenea si algoritmul pentru detectia de fete. Pentru a nu complica foarte mult lucrurile, putem folosi un algoritm gata implementat (de ex cel din libraria DLib)
Modelul pentru clasificare va fi o retea neurala convolutiva. Pentru a intelege acest tip de retele, trebuie sa scadem treptat complexitatea in felul urmator:
Trebuie sa inteleg cum functioneaza o retea neurala simpla mai intai.
Ca sa inteleg asta -> trebuie sa inteleg cum functioneaza o regresie logistica.
Ca sa inteleg asta -> trebuie sa inteleg cum functioneaza algoritmul backpropagation.
Ca sa inteleg asta -> trebuie sa inteleg cum functioneaza o derivata.
Ca sa inteleg asta -> trebuie sa inteleg ce este aceea o panta.
Vom aborda lucrurile de la coada la cap pentru a intelege in profunzime retelele neurale convolutive.
Cea mai mare parte din aceasta calatorie se va concentra pe intelegearea acestor notiuni.
La final, vom testa performanta modelului obtinut pe un sub set de date ‘secret’, care nu a fost folosit in timpul antrenarii.
Facem acest lucru deoarece vrem sa ne asiguram ca modelul nu a invatat ‘pe de rost’ imaginile vazute in timpul antrenarii, ci este capabil sa generalizeze.
Iti voi arata cum implementezi toate aceste lucruri folosind libraria Pytorch.
5. Imbunatatire
Daca am atins performanta dorita, poate va ganditi ca putem sari peste acest pas. Ce ar trebui sa facem de fapt este sa verificam potentiale bug-uri, deoarece in realitate acest lucru nu se prea intampla asa de repede.
Am zis la inceput ca acesta este un proces iterativ. Acum o sa intelegem si mai bine de ce.
In acest pas ne vom intoarce la pasul 1 si vom relua toate etapele.
De data aceasta, la partea de intelegere a problemei vom analiza cazurile in care modelul nostru a dat gres cu clasificarea/detectia si vom incerca sa intelegem de ce.
Spre exemplu, vedem ca modelul nostru se incurca daca in spatele nostru mai este o alta persoana. Ce facem in acest caz, ne intoarcem la pasul 2 si facem mai multe date in care avem persoane in spate.
SAU
facem augmentari in care introducem in mod artificial persoane in spatele nostru.
De asemenea este foarte indicat sa mai cautam si alte seturi de date publice pe care le putem folosi.
La pasul 3 vom incerca sa facem preprocesari mai bune. Aici putem include augmentari ale datelor (precum adaugarea unui mic zgomot, rotiri, deformari s.a.m.d) , crop-uri mai inteligente etc.
La pasul 4, vom lua fiecare modul din arhitectura noastra (in cazul nostru cele doua: detectia de fete si clasificarea) si vom incerca sa-l imbunatatim, astfel incat rezultatul final sa fie cat mai bun.
Exemple de cum putem imbunatati:
- Implementarea de arhitecturi ale retelei neurale diferite/mai complexe/din literatura de specialitate
- Introducerea mai multor pasi in pipeline daca se poate (pe langa detectie si clasificare).
Scopul este sa modularizam astfel incat fiecare algoritm sa fac doar un task simplu. - Optimizarea hiperparametrilor (mai scadem/crestem numarul de parametri ai retelei, adaugam regularizari, schimbam batch size, optimizatorul folosit, learning rate etc).
Se vor face multe experimente folosind diverse configurari.
Este foarte important sa fim organizati in aceasta etapa si sa documentam fiecare experiment pe care il rulam.
Iti voi arata cum poti face aceasta documentare intr-un mod foarte simplu si eficient cu ajutorul unor tool-uri speciale (precum CometML sau Tensorboard)
6. Productizarea
Odata ce ai obtinut un model cu o performanta satisfacatoare, este momentul sa il integrezi intr-un pachet/software.
Modelul poate ajunge undeva in cloud, unde va trebui sa dezvoltam servicii REST, sau pe un microcontroller, unde va trebui sa facem mici optimizari (sa mearga mai repede, sa consume mai putina memorie etc)
In cazul proiectului nostru vei folosi libraria Flask din Python pentru dezvoltarea serviciilor REST responsabile de predictie.
Aceste este cel mai simplu pas din toata ecuatia noastra.
Daca ai ajuns pana la finalul acestui email lung, vreai sa te felicit si sa iti multumesc! Denota faptul ca esti o persoana ambitioasa, hotarata sa invete AI cu adevarat!
Cu un astfel de proiect in portofoliu iti cresti exponential sansele de a gasi un JOB sau internship in AI.
Acum poti implementa proiectul de unul singur folosind informatiile de mai sus iar daca sunt nelamuriri voi raspunde cu mare bucurie la ele.
SAU
mai exista o varianta: poți să parcurgi toata aceasta calatorie alaturi de mine.
Așa că, am marea plăcere iti prezint o varianta prin care noi doi putem parcurge tot acest proces impreună avand ghidarea mea la fiecare pas.
In acest mod ne vom asigura ca esti pe drumul cel bun intotdeauna si nu te abati de la acesta + scrierea codului impreuna + explicarea tuturor conceptelor intr-o conversatie live.