7.7. Normalisointi¶
ml.Model.predict() ottaa listan syötteitä, koska joillakin verkoilla on enemmän kuin yksi syötetensori, mutta listalla ei ole tapaa kuljettaa syötekohtaisia argumentteja sisäisesti – ei ole kwarg-paikkaa sanoa ”rajaa tämä syöte alueeseen (x, y, w, h) mutta jätä muut syötteet ennalleen”. ml.preprocessing.Normalization on kääre, joka täyttää tämän aukon. Normalization -instanssi pitää sisällään yhden syötteen parametrit; skripti välittää käärityn syötteen predict-listassa aina, kun se tarvitsee jotain muuta kuin oletuksia.
Yleisin syy turvautua siihen on rajata kaapatusta kehyksestä tietty alue verkkoon koko kuvan sijaan.
7.7.1. Parametrit¶
Normalization(scale=(0.0, 1.0),
mean=(0.0, 0.0, 0.0),
stdev=(1.0, 1.0, 1.0),
roi=None)
roi–(x, y, w, h)-suorakulmio lähdekehyksessä, joka rajataan ennen skaalausta. Oletuksena koko kehys. Useimmat käyttötapaukset, joissaNormalizationesiintyy, asettavat vain tämän parametrin.scale–(min, max)-alue, jota liukulukusyötetensorit odottavat normalisoinnin jälkeen. Pikselialue0..255kuvataan lineaarisesti tähän alueeseen. Yleisiä arvoja ovat(0.0, 1.0)ReLU-koulutetuille verkoille ja(-1.0, 1.0)symmetrisesti normalisoiduille verkoille.mean– kanavakohtainen(R, G, B)-keskiarvo, joka vähennetään kuvasta skaalauksen jälkeen. Vastaa kanavatilastoja, joita vastaan verkko koulutettiin –(0.485, 0.456, 0.406)ImageNetistä johdetuille verkoille on kanoninen esimerkki. Harmaasävyverkot pelkistävät keskiarvon luma-arvoksi käyttäen vakiokaavaa0.299*R + 0.587*G + 0.114*B.stdev– kanavakohtainen(R, G, B)-keskihajonta, jolla kuva jaetaan keskiarvon vähentämisen jälkeen, jälleen verkon koulutustilastoja vastaten. Pelkistetään lumaksi samalla tavoin harmaasävyverkoille.
7.7.2. Milloin parametreilla on merkitystä¶
scale, mean ja stdev jätetään huomiotta, kun verkon input_dtype on int8 tai uint8. Kokonaislukusyötteen verkoille rajatun kuvan tavut kirjoitetaan tensoriin suoraan, ja verkon oma input_scale ja input_zero_point hoitavat kokonaisluvusta reaaliarvoksi -muunnoksen. Nämä kolme parametria merkitsevät vain, kun verkko odottaa liukulukusyötettä.
roi luetaan joka tapauksessa – se hallitsee, mikä osa lähdekehyksestä saavuttaa verkon riippumatta syötteen dtype-tyypistä.
7.7.3. ROI ja skaalaus¶
ROI skaalataan bilineaarisesti lähdemitoistaan verkon syötemittoihin. Kuva keskitetään kohteeseen ja skaalaus täyttää kohteen – se ei säilytä kuvasuhdetta. Neliömäiseen verkon syötteeseen syötetty ei-neliömäinen ROI tulee ulos vaaka- tai pystysuunnassa venytettynä.
Onko venytyksellä merkitystä, riippuu verkosta. Kasvojentunnistus- ja maamerkkimallit, kuten MediaPipe-perhe (BlazeFace, FaceLandmarks, HandLandmarks, MoveNet), on koulutettu neliömäisillä rajauksilla ja heikkenevät nopeasti, kun syötteen kuvasuhde on väärä; niitä varten sovelluksen on annettava neliömäinen ROI – joko kaappaamalla neliömäisellä kehyskoolla metodin window() kautta tai rajaamalla parametrilla roi=. YOLO-perheen objektintunnistimet on tyypillisesti koulutettu augmentoinnilla, joka sisältää satunnaisia venytyksiä, ja ne hyväksyvät ei-neliömäiset ROI:t ilman suurta tarkkuuden menetystä; koko kaapatun kehyksen syöttäminen suoraan on yleensä hyvä vaihtoehto.
Kun verkon syötemitat vastaavat ROI:ta tarkalleen, skaalaus supistuu kopioksi, mikä on halvin tapaus.
7.7.4. Oletuksen ohittaminen¶
predict() kääräisee kunkin image.Image -syötteen automaattisesti olioon Normalization() – yllä mainituilla oletusparametreilla. Useimmat kameran mukana toimitettavat mallit on koulutettu pikselialueilla, jotka oletukset jo kattavat, joten yleinen tapaus on välittää kuva suoraan:
result = model.predict([img])
Mukautetun ROI:n käyttämiseksi – yleisin ohitus – rakenna Normalization, jossa ROI on asetettu, ja sido kuva siihen:
from ml.preprocessing import Normalization
norm = Normalization(roi=(80, 60, 160, 120))
result = model.predict([norm(img)])
Jotta verkon koulutusajan kanavatilastot vastaisivat, aseta liukulukuparametrit:
norm = Normalization(scale=(0.0, 1.0),
mean=(0.485, 0.456, 0.406),
stdev=(0.229, 0.224, 0.225))
result = model.predict([norm(img)])
Normalization -instanssin kutsuminen kuvalle palauttaa uuden sidotun instanssin, josta moottori täyttää tensorin. Sidottu instanssi on se, jonka predict hyväksyy raakakuvan sijaan, ja koska se on syötekohtainen olio, monisyötteinen verkko voi sekoittaa kuvia eri ROI:illa samassa predict-listassa.
Verkoille, jotka odottavat syötteitä, jotka sovellus on jo tuottanut tensorimuodossa – puskuri oheislaitteelta, toisen putken laskema ndarray, ei-kuvallinen numeerinen data – ohita Normalization kokonaan ja välitä ndarray tai sen tuottava kutsuttava olio. predict() välittää ne moottorille ilman kääriä.