7.2. Wat ML veranderde¶
De image-module bevat een handvol verouderde detectiemethoden – find_features() voor Haar-cascade-gezichtsdetectie, find_eye() voor de vaste pupilvinder, find_hog() voor samenvattingen van gradiëntrichtingen, en de paden find_keypoints() en find_lbp() voor willekeurige sleutelpunten. Ze werken allemaal nog steeds; ze zijn allemaal vervangen door de machine learning-pijplijn.
7.2.1. De klassieke splitsing: handontworpen samenvattingen, aangeleerde beslissingen¶
Een klassieke visiepijplijn was een tweetraps geheel. De eerste stap zette ruwe pixels om in een compacte set getallen die gekozen waren om samen te vatten wat er op de afbeelding stond – niet de pixelwaarden zelf, maar een kortere beschrijving van welke patronen waar voorkwamen. De tweede stap nam die samenvatting en nam een beslissing: gezicht of niet, dit object of dat object, hetzelfde doel of een ander.
De splitsing was van belang omdat de twee stappen verschillende auteurs hadden. De eerste stap werd door een mens geschreven. Iemand ging zitten en besloot dat het helderheidsverschil tussen twee specifieke rechthoeken een goede samenvatting was van een oogregio, dat de dominante randrichting in elke cel van een raster een goede samenvatting was van het silhouet van een staand persoon, dat het heldere-of-donkere patroon rond elke pixel een goede samenvatting was van lokale textuur. Elk van deze keuzes was een handgeschreven algoritme – geschreven, gedebugd en gepubliceerd. De bovenstaande verouderde methoden waren allemaal samenvattingen van dit soort die standaardgereedschap waren geworden:
find_features()vat een venster van de afbeelding samen door de helderheid binnen verschillende rechthoeken op te tellen en de totalen te vergelijken. De rechthoekindelingen werden gekozen omdat menselijke gezichten betrouwbare licht-tegen-donker-contrasten vertonen: wenkbrauwen tegen wangen, oogkassen tegen voorhoofd, neus tegen omringende huid.find_hog()vat een afbeelding samen door een raster van kleine cellen af te lopen en vast te leggen welke randrichting in elke cel domineert. Het raster werd gekozen omdat het silhouet van een staand persoon een herkenbaar patroon van randrichtingen oplevert, ongeacht kleding of belichting.find_lbp()vat de buurt van elke pixel samen door te coderen welke van de omringende pixels helderder zijn en welke donkerder. De codering werd gekozen omdat deze helderder-dan-/donkerder-dan-patronen de textuur van een oppervlak vastleggen, onafhankelijk van de algehele belichting.find_keypoints()zoekt hoekpunten in de afbeelding en beschrijft het gebied rond elke hoek op een manier die hetzelfde blijft wanneer de hoek wordt geroteerd. Het hoek-en-rotatieschema werd gekozen omdat dezelfde hoeken weer verschijnen wanneer een scène vanuit een andere hoek wordt bekeken.
Zodra een samenvatting met de hand was geschreven, kon een kleine leerstap erbovenop de getallen combineren tot een beslissing. Het gezichtsdetectie-algoritme koppelde een leerstap aan de rechthoekverschilsamenvatting en trainde die op gelabelde gezicht- en niet-gezichtafbeeldingen om te leren welke combinaties van verschillen op een gezicht wijzen. De randrichtingssamenvatting voedde een leerstap die getraind was op gelabelde persoon- en niet-persoonafbeeldingen. De hoekdescriptoren voedden een matchingstap die leerde hoeveel gewicht aan elke hoek moest worden toegekend. Elk van deze tweede stappen is een leeralgoritme – klein naar moderne maatstaven, maar een leeralgoritme.
De verdeling van de bijdragen was wat van belang was. De mens leverde de samenvatting. De machine leerde de combinatie. Een nieuw doel toevoegen betekende een nieuwe samenvatting schrijven.
7.2.2. Wat neurale netwerken veranderden¶
Een neuraal netwerk wist de splitsing uit. De eerste lagen van het netwerk doen het samenvattingswerk dat de handgeschreven algoritmen vroeger deden – randen, hoeken, georiënteerde balken en texturen detecteren, precies de dingen waarop de hierboven genoemde verouderde methoden elk waren afgestemd – maar ze zijn niet handgeschreven. Ze worden geleerd uit dezelfde trainingsdata waaruit de beslissingsstap wordt geleerd, in één enkele trainingsronde die beide helften van het netwerk tegelijk aanpast. De diepere lagen doen het combineren dat de kleine leerstap bovenop de handgeschreven samenvattingen vroeger deed, eveneens geleerd, in dezelfde ronde.
De verandering in wie wat ontwerpt is totaal:
De mens ontwerpt de invoer – vastgelegde frames van een gegeven grootte en formaat.
De mens ontwerpt de uitvoer – de indeling van de resultaattensor (één score per klasse voor classificatie, een lijst vakken voor detectie, een raster van sleutelpunten voor herkenningspunten).
De mens levert gelabelde trainingsdata – genoeg voorbeelden van het doel en genoeg voorbeelden van niet-doelen zodat het trainingsproces iets heeft om van te leren.
Alles tussen invoer en uitvoer wordt gegenereerd door het trainingsproces. Er is geen aparte stap voor het schrijven van samenvattingen. De vroege lagen vormen zich tot rand- en textuurdetectoren, niet omdat iemand ze zo heeft geschreven, maar omdat rand- en textuurdetectie is wat de voorspellingen van het netwerk met de labels laat overeenkomen. De diepere lagen vormen zich om dezelfde reden tot vorm- en objectdetectoren. Beide helften worden samen getraind, waardoor de samenvattingen die elke laag produceert precies de samenvattingen kunnen zijn die de volgende laag nodig heeft – niet de generieke waar een handgeschreven pijplijn genoegen mee moest nemen.
7.2.3. Samenstellen met de image-module¶
Neuraal-netwerkpijplijnen leggen nog steeds vast via dezelfde sensor-API’s, tekenen resultaten via dezelfde primitieven draw_rectangle() en draw_circle(), en bakenen werk af via dezelfde (x, y, w, h)-ROI’s. Een typische pijplijn legt een frame vast, vindt eventueel een grof doel met een klassieke detector zoals find_blobs() en geeft het begrenzingsvak daarvan als ROI door aan de inferentie, voert de inferentie uit en annoteert de teruggegeven detecties weer in het oorspronkelijke frame. De klassieke primitieven vormen het substraat; het netwerk is de nieuwe stap in het midden.