7.2. Ce a schimbat ML

Modulul image conține câteva metode de detectare moștenite (legacy) – find_features() pentru detectarea fețelor cu cascade Haar, find_eye() pentru detectorul fix de pupile, find_hog() pentru rezumate de direcție a gradientului, căile find_keypoints() și find_lbp() pentru puncte-cheie arbitrare. Toate funcționează în continuare; toate au fost depășite de fluxul de lucru bazat pe învățarea automată.

7.2.1. Diviziunea clasică: rezumate concepute manual, decizii învățate

Un flux de lucru clasic de viziune era un proces în doi pași. Primul pas transforma pixelii bruți într-un set compact de numere alese pentru a rezuma ce se afla în imagine – nu valorile pixelilor în sine, ci o descriere mai scurtă a tiparelor care apăreau și unde. Al doilea pas prelua acel rezumat și lua o decizie: față sau nu, acest obiect sau altul, aceeași țintă sau alta.

Diviziunea conta deoarece cei doi pași aveau autori diferiți. Primul pas era scris de un om. Cineva se așeza și decidea că diferența de luminozitate dintre două dreptunghiuri specifice era un rezumat bun al unei regiuni de ochi, că direcția dominantă a muchiilor din fiecare celulă a unei grile era un rezumat bun al conturului unei persoane în picioare, că tiparul luminos-sau-întunecat din jurul fiecărui pixel era un rezumat bun al texturii locale. Fiecare dintre aceste alegeri era un algoritm scris manual – scris, depanat și publicat. Metodele moștenite de mai sus erau toate rezumate de acest tip care deveniseră instrumente standard:

  • find_features() rezumă o fereastră a imaginii adunând luminozitatea din interiorul mai multor dreptunghiuri și comparând totalurile. Configurațiile dreptunghiurilor au fost alese deoarece fețele umane prezintă contraste fiabile între zonele luminoase și cele întunecate: sprâncenele față de obraji, orbitele față de frunte, nasul față de pielea din jur.

  • find_hog() rezumă o imagine parcurgând o grilă de celule mici și înregistrând care direcție a muchiilor domină în fiecare celulă. Grila a fost aleasă deoarece conturul unei persoane în picioare produce un tipar recunoscibil de direcții ale muchiilor indiferent de îmbrăcăminte sau iluminare.

  • find_lbp() rezumă vecinătatea fiecărui pixel codificând care dintre pixelii din jur sunt mai luminoși și care sunt mai întunecați. Codificarea a fost aleasă deoarece aceste tipare mai-luminos / mai-întunecat surprind textura unei suprafețe independent de iluminarea de ansamblu.

  • find_keypoints() găsește puncte de colț în imagine și descrie zona din jurul fiecărui colț într-un mod care rămâne neschimbat atunci când colțul este rotit. Schema colț-și-rotație a fost aleasă deoarece aceleași colțuri reapar atunci când o scenă este privită dintr-un unghi diferit.

Odată ce un rezumat fusese scris manual, un mic pas de învățare deasupra lui putea combina numerele într-o decizie. Algoritmul de detectare a fețelor adăuga un pas de învățare peste rezumatul bazat pe diferențele dintre dreptunghiuri, antrenându-l pe imagini etichetate cu și fără față pentru a învăța care combinații de diferențe semnalează o față. Rezumatul de direcție a muchiilor alimenta un pas de învățare antrenat pe imagini etichetate cu și fără persoană. Descriptorii de colț alimentau un pas de potrivire care învăța câtă pondere să acorde fiecărui colț. Fiecare dintre acești al doilea pași este un algoritm de învățare – unul mic după standardele moderne, dar tot un algoritm de învățare.

Diviziunea contribuției era ceea ce conta. Omul contribuia cu rezumatul. Mașina învăța combinația. Adăugarea unei noi ținte însemna scrierea unui nou rezumat.

7.2.2. Ce au schimbat rețelele neuronale

O rețea neuronală șterge această diviziune. Primele straturi ale rețelei fac munca de rezumare pe care obișnuiau să o facă algoritmii scriși manual – detectarea muchiilor, colțurilor, barelor orientate, texturilor, exact lucrurile pe care metodele moștenite enumerate mai sus erau fiecare reglate să le detecteze – dar ele nu sunt scrise manual. Ele sunt învățate din aceleași date de antrenare din care este învățat pasul de decizie, într-o singură trecere de antrenare care ajustează ambele jumătăți ale rețelei deodată. Straturile mai adânci fac combinarea pe care obișnuia să o facă micul pas de învățare de deasupra rezumatelor scrise manual, de asemenea învățată, în aceeași trecere.

Schimbarea privind cine proiectează ce este totală:

  • Omul proiectează intrarea – cadre captate de o anumită dimensiune și format.

  • Omul proiectează ieșirea – structura tensorului de rezultat (câte un scor pe clasă pentru clasificare, o listă de casete pentru detectare, o grilă de puncte-cheie pentru repere).

  • Omul furnizează datele de antrenare etichetate – suficiente exemple ale țintei și suficiente exemple de non-ținte încât procesul de antrenare să aibă din ce învăța.

Tot ce se află între intrare și ieșire este generat de procesul de antrenare. Nu există un pas separat de scriere a rezumatelor. Straturile timpurii se așază pe rolul de detectoare de muchii și texturi nu pentru că le-a scris cineva astfel, ci pentru că detectarea muchiilor și a texturilor este ceea ce face ca predicțiile rețelei să se potrivească cu etichetele. Straturile mai adânci se așază pe rolul de detectoare de forme și obiecte din același motiv. Ambele jumătăți sunt antrenate împreună, ceea ce permite ca rezumatele produse de fiecare strat să fie exact rezumatele de care are nevoie stratul următor – nu cele generice cu care un flux de lucru scris manual trebuia să se mulțumească.

7.2.3. Combinarea cu modulul image

Fluxurile de lucru bazate pe rețele neuronale captează în continuare prin aceleași API-uri de senzor, desenează rezultatele prin aceleași primitive draw_rectangle() și draw_circle() și delimitează munca prin aceleași ROI-uri (x, y, w, h). Un flux de lucru tipic captează un cadru, găsește opțional o țintă grosieră cu un detector clasic precum find_blobs() și transmite caseta sa de încadrare inferenței ca ROI, rulează inferența și adnotează detectările returnate înapoi în cadrul original. Primitivele clasice constituie substratul; rețeaua este noul pas din mijloc.