Älä käytä Flatten() - maailmanlaajuista yhdistämistä CNN:ille, joissa on TensorFlow ja Keras PlatoBlockchain Data Intelligence. Pystysuuntainen haku. Ai.

Älä käytä Flatten() - maailmanlaajuista yhdistämistä CNN:ille, joissa on TensorFlow ja Keras

Useimmat harjoittajat oppivat ensin konvoluutiohermoverkon (CNN) arkkitehtuureista, että se koostuu kolmesta perussegmentistä:

  • Konvoluutiokerrokset
  • Kerrosten yhdistäminen
  • Täysin yhdistetyt kerrokset

Suurin osa resursseista on jonkin verran muunnelma tästä segmentoinnista, mukaan lukien oma kirjani. Erityisesti verkossa – täysin yhdistetyt kerrokset viittaavat a tasoittava kerros ja (yleensä) useita tiheät kerrokset.

Tämä oli ennen normaalia, ja tunnetut arkkitehtuurit, kuten VGGNets, käyttivät tätä lähestymistapaa, ja loppujen lopuksi:

model = keras.Sequential([
    
    keras.layers.MaxPooling2D((2, 2), strides=(2, 2), padding='same'),
    keras.layers.Flatten(),
    keras.layers.Dropout(0.5),
    keras.layers.Dense(4096, activation='relu'), 
    keras.layers.Dropout(0.5),
    keras.layers.Dense(4096, activation='relu'),
    keras.layers.Dense(n_classes, activation='softmax')
])

Tosin jostain syystä – usein unohdetaan, että VGGNet oli käytännössä viimeinen arkkitehtuuri, joka käytti tätä lähestymistapaa sen aiheuttaman ilmeisen laskennallisen pullonkaulan vuoksi. Heti kun ResNets, joka julkaistiin vain vuosi VGGNetsin jälkeen (ja 7 vuotta sitten), kaikki valtavirran arkkitehtuurit päättivät mallimäärittelynsä seuraavasti:

model = keras.Sequential([
    
    keras.layers.GlobalAveragePooling2D(),
    keras.layers.Dense(n_classes, activation='softmax')
])

CNN-verkkojen litistyminen on jatkunut 7 vuotta. 7 vuotta! Eikä tarpeeksi ihmiset näytä puhuvan haitallisista vaikutuksista, joita sillä on sekä oppimiskokemukseesi että käyttämiisi laskennallisiin resursseihin.

Globaali keskimääräinen yhdistäminen on monilla tileillä parempi kuin tasoitus. Jos suunnittelet pientä CNN:tä – käytä Global Poolingia. Jos opetat jollekin CNN:istä – käytä Global Poolingia. Jos olet tekemässä MVP:tä – käytä Global Poolingia. Käytä tasoituskerroksia muihin käyttötapauksiin, joissa niitä todella tarvitaan.

Tapaustutkimus – Tasoitus vs globaali yhdistäminen

Global Pooling tiivistää kaikki ominaisuuskartat yhdeksi, yhdistäen kaikki olennaiset tiedot yhdeksi kartaksi, joka voidaan helposti ymmärtää yhdellä tiheällä luokituskerroksella useiden kerrosten sijaan. Sitä käytetään tyypillisesti keskimääräisenä yhdistämisenä (GlobalAveragePooling2D) tai max pooling (GlobalMaxPooling2D) ja se voi toimia myös 1D- ja 3D-tulossa.

Sen sijaan, että litistäisi karttaa, kuten esim (7, 7, 32) vektoriksi, jonka pituus on 1536, ja harjoittelemme yhtä tai useampaa kerrosta erottamaan kuviot tästä pitkästä vektorista: voimme tiivistää sen (7, 7) vektori ja luokittele suoraan sieltä. Se on niin yksinkertaista!

Huomaa, että ResNetin kaltaisten verkkojen pullonkaulakerroksissa on kymmeniä tuhansia ominaisuuksia, ei vain 1536. Tasoittaessasi kidutat verkkoasi oppiaksesi oudon muotoisista vektoreista erittäin tehottomalla tavalla. Kuvittele, että 2D-kuva leikataan jokaiselle pikseliriville ja ketjutetaan sitten litteäksi vektoriksi. Kaksi pikseliä, jotka olivat aiemmin pystysuunnassa 0 pikseliä toisistaan, eivät ole feature_map_width pikselin päässä vaakatasossa! Vaikka tällä ei ehkä ole liikaa merkitystä luokittelualgoritmille, joka suosii spatiaalista invarianssia, tämä ei olisi edes käsitteellisesti hyvä muille tietokonenäön sovelluksille.

Määritellään pieni demonstraatioverkko, joka käyttää tasoituskerrosta parilla tiheällä kerroksella:

model = keras.Sequential([
    keras.layers.Input(shape=(224, 224, 3)),
    keras.layers.Conv2D(32, (3, 3), activation='relu'),
    keras.layers.Conv2D(32, (3, 3), activation='relu'),
    keras.layers.MaxPooling2D((2, 2), (2, 2)),
    keras.layers.BatchNormalization(),
    keras.layers.Conv2D(64, (3, 3), activation='relu'),
    keras.layers.Conv2D(64, (3, 3), activation='relu'),
    keras.layers.MaxPooling2D((2, 2), (2, 2)),
    keras.layers.BatchNormalization(),
    keras.layers.Flatten(),
    keras.layers.Dropout(0.3),
    keras.layers.Dense(64, activation='relu'),
    keras.layers.Dense(32, activation='relu'),
    keras.layers.Dense(10, activation='softmax')
])
model.summary()

Miltä yhteenveto näyttää?

...                                                              
 dense_6 (Dense)             (None, 10)                330       
                                                                 
=================================================================
Total params: 11,574,090
Trainable params: 11,573,898
Non-trainable params: 192
_________________________________________________________________

11.5 miljoonaa parametria leluverkostoon – ja katso parametrien räjähdysmäistä kasvua suuremmalla tulolla. 11.5 miljoonaa parametria. EfficientNets, yksi parhaista koskaan suunnitelluista verkoista, toimii ~6 miljoonalla parametrilla, eikä sitä voida verrata tähän yksinkertaiseen malliin todellisen suorituskyvyn ja tietojen oppimiskyvyn suhteen.

Voisimme pienentää tätä määrää merkittävästi tekemällä verkkoa syvemmälle, mikä johtaisi enemmän max poolingiin (ja mahdollisesti jatkuvaan konvoluutioon) ominaisuuskarttojen vähentämiseksi ennen kuin ne litistyvät. Ajattele kuitenkin, että tekisimme verkosta monimutkaisemman tehdäksemme siitä laskennallisesti vähemmän kalliita, kaikki vain yhden kerroksen vuoksi, joka heittelee suunnitelmia.

Tasojen syvemmälle menemisen tulisi olla merkityksellisempien, epälineaaristen suhteiden poimiminen tietopisteiden välillä, eikä syötekokoa pienennetä tasoittavan kerroksen täyttämiseksi.

Tässä on verkosto globaalilla poolingilla:

model = keras.Sequential([
    keras.layers.Input(shape=(224, 224, 3)),
    keras.layers.Conv2D(32, (3, 3), activation='relu'),
    keras.layers.Conv2D(32, (3, 3), activation='relu'),
    keras.layers.MaxPooling2D((2, 2), (2, 2)),
    keras.layers.BatchNormalization(),
    keras.layers.Conv2D(64, (3, 3), activation='relu'),
    keras.layers.Conv2D(64, (3, 3), activation='relu'),
    keras.layers.MaxPooling2D((2, 2), (2, 2)),
    keras.layers.BatchNormalization(),
    keras.layers.GlobalAveragePooling2D(),
    keras.layers.Dropout(0.3),
    keras.layers.Dense(10, activation='softmax')
])

model.summary()

Yhteenveto?

 dense_8 (Dense)             (None, 10)                650       
                                                                 
=================================================================
Total params: 66,602
Trainable params: 66,410
Non-trainable params: 192
_________________________________________________________________

Paljon parempi! Jos menemme syvemmälle tämän mallin kanssa, parametrien määrä kasvaa ja voimme ehkä kaapata monimutkaisempia datakuvioita uusilla tasoilla. Jos kuitenkin tehdään naiivisti, ilmaantuu samat ongelmat, jotka rajoittivat VGGNettejä.

Jatketaan eteenpäin – Hand-Held päästä päähän -projekti

Utelias luonteesi saa sinut haluamaan pidemmälle? Suosittelemme tutustumaan meidän Ohjattu projekti: "Konvoluutiohermoverkot – perusarkkitehtuurien ulkopuolella".

Tutustu käytännönläheiseen, käytännölliseen Gitin oppimisoppaaseemme, jossa on parhaat käytännöt, alan hyväksymät standardit ja mukana tuleva huijauslehti. Lopeta Git-komentojen googlailu ja oikeastaan oppia se!

Otan sinut aikamatkalle – vuodesta 1998 vuoteen 2022, tuon esiin vuosien varrella kehitetyt määrittävät arkkitehtuurit, mikä teki niistä ainutlaatuisia, mitkä niiden haitat ovat, ja toteutan merkittävimmät alusta alkaen. Mikään ei ole parempaa kuin likainen käsissäsi, kun kyse on näistä.

Voit ajaa autoa tietämättä, onko moottorissa 4 vai 8 sylinteriä ja mikä on venttiilien sijoitus moottorissa. Jos kuitenkin haluat suunnitella ja arvostaa moottoria (tietokonenäkömalli), sinun kannattaa mennä hieman syvemmälle. Vaikka et halua käyttää aikaa arkkitehtuurien suunnitteluun ja haluat sen sijaan rakentaa tuotteita, mitä useimmat haluavat tehdä, löydät tärkeitä tietoja tältä oppitunnilta. Opit, miksi vanhentuneiden arkkitehtuurien, kuten VGGNet, käyttö heikentää tuotettasi ja suorituskykyäsi ja miksi sinun pitäisi jättää ne väliin, jos rakennat jotain modernia, ja opit, mitä arkkitehtuureja voit käyttää käytännön ongelmien ratkaisemiseen ja mitä plussat ja miinukset ovat jokaisessa.

Jos aiot soveltaa tietokonenäköä omalla alallasi tämän oppitunnin resurssien avulla – voit löytää uusimmat mallit, ymmärtää, miten ne toimivat ja millä kriteereillä voit verrata niitä ja tehdä päätöksen, mitä käyttää.

Voit älä täytyy Googlettaa arkkitehtuureja ja niiden toteutuksia varten – ne on yleensä hyvin selkeästi selitetty papereissa, ja Kerasin kaltaiset puitteet tekevät näistä toteutuksista helpompaa kuin koskaan. Tämän ohjatun projektin tärkein sisältö on opettaa sinua löytämään, lukemaan, toteuttamaan ja ymmärtämään arkkitehtuureja ja papereita. Mikään resurssi maailmassa ei pysty pysymään viimeisimmän kehityksen mukana. Olen lisännyt tähän uusimmat paperit – mutta muutaman kuukauden kuluttua ilmestyy uusia, ja se on väistämätöntä. Kun tiedät, mistä löytää uskottavia toteutuksia, vertailla niitä papereihin ja muokata niitä, voit saada kilpailuetua, jota tarvitaan monissa tietokonenäkötuotteissa, joita saatat haluta rakentaa.

Yhteenveto

Tässä lyhyessä oppaassa olemme tarkastelleet vaihtoehtoa litistämiselle CNN-arkkitehtuurin suunnittelussa. Vaikkakin lyhyt – opas käsittelee yleistä ongelmaa prototyyppien tai MVP:iden suunnittelussa ja neuvoo käyttämään parempaa vaihtoehtoa litistämiselle.

Jokainen kokenut Computer Vision Engineer tietää ja soveltaa tätä periaatetta, ja käytäntöä pidetään itsestäänselvyytenä. Valitettavasti sitä ei näytä välitetä kunnolla uusille harjoittajille, jotka ovat juuri tulossa kenttään, ja se voi luoda tahmeita tapoja, joista pääseminen eroon kestää hetken.

Jos olet siirtymässä Computer Visioniin – tee itsellesi palvelus äläkä käytä tasoittavia kerroksia ennen luokittelupäitä oppimismatkallasi.

Aikaleima:

Lisää aiheesta Stackabus