Klasifikace ručně psaných kreseb. Zpráva v Yandexu

Před pár měsíci naši kolegové z Google strávil na Kaggle soutěž o vytvoření klasifikátoru pro obrázky získané v senzační hra "Rychle, kresli!" Tým, který zahrnoval vývojáře Yandex Roman Vlasov, obsadil čtvrté místo v soutěži. Na lednovém školení strojového učení se Roman podělil o nápady svého týmu, konečnou implementaci klasifikátoru a zajímavé postupy svých oponentů.


- Ahoj všichni! Jmenuji se Roma Vlasov, dnes vám řeknu o Quick, Draw! Výzva k rozpoznání svátečních log.

Klasifikace ručně psaných kreseb. Zpráva v Yandexu

V našem týmu bylo pět lidí. Připojil jsem se těsně před termínem sloučení. Měli jsme smůlu, byli jsme trochu otřeseni, ale byli jsme otřeseni z pozice peněz a oni byli otřeseni ze zlaté pozice. A obsadili jsme čestné čtvrté místo.

(Během soutěže týmy sledovaly samy sebe v hodnocení, které bylo vytvořeno na základě výsledků zobrazených na jedné části navrženého souboru dat. Výsledné hodnocení bylo zase vytvořeno na jiné části souboru dat. že účastníci soutěže nepřizpůsobují své algoritmy konkrétním datům. Proto se ve finále při přepínání mezi hodnoceními pozice trochu zatřepou (z anglického shake up - míchat): na jiných datech může výsledek dopadnout být jiný. Romanův tým byl první mezi třemi nejlepšími. V tomto případě jsou první tři zóny peněžní, peněžní, protože pouze první tři místa byla oceněna peněžní odměnou. Po přetřesu byl tým již v čtvrté místo. Stejně tak druhý tým přišel o vítězství, zlatou pozici. - Red.)

Klasifikace ručně psaných kreseb. Zpráva v Yandexu

Soutěž byla významná i tím, že Jevgenij Babachnin dostal velmistra, Ivan Sosin mistra, Roman Solovjev zůstal velmistrem, Alex Parinov dostal mistra, stal jsem se odborníkem a nyní jsem již mistrem.

Klasifikace ručně psaných kreseb. Zpráva v Yandexu

Co je to Quick, Draw? Toto je služba od společnosti Google. Google měl za cíl popularizovat AI a touto službou chtěl ukázat, jak fungují neuronové sítě. Jdete tam, kliknete na Let's Draw a objeví se nová stránka, kde je vám řečeno: nakreslete cikcak, máte na to 20 sekund. Snažíte se nakreslit cikcak za 20 sekund, jako například zde. Pokud uspějete, síť řekne, že je to cikcak a jedete dál. Takových obrázků je jen šest.

Pokud síť Google nerozpoznala, co jste nakreslili, byl na úkol umístěn křížek. Později vám řeknu, co to bude v budoucnu znamenat, zda je kresba sítí rozpoznána nebo ne.

Tato služba shromáždila poměrně velký počet uživatelů a všechny obrázky, které uživatelé nakreslili, byly logovány.

Klasifikace ručně psaných kreseb. Zpráva v Yandexu

Podařilo se nám shromáždit téměř 50 milionů snímků. Z toho vznikl vlak a termín zkoušky pro naši soutěž. Mimochodem, množství dat v testu a počet tříd jsou z nějakého důvodu zvýrazněny tučně. Řeknu vám o nich trochu později.

Formát dat byl následující. Nejsou to jen obrázky RGB, ale zhruba řečeno protokol všeho, co uživatel udělal. Slovo je náš cíl, kód země je místo, odkud pochází autor svátečního loga, časové razítko je čas. Rozpoznaný štítek pouze ukazuje, zda síť rozpoznala obrázek od Googlu nebo ne. A samotná kresba je posloupnost, aproximace křivky, kterou uživatel kreslí body. A načasování. Toto je čas od začátku kreslení obrázku.

Klasifikace ručně psaných kreseb. Zpráva v Yandexu

Data byla prezentována ve dvou formátech. Toto je první formát a druhý je zjednodušený. Odtud vystřihli časování a aproximovali tuto sadu bodů menší sadou bodů. K tomu použili Douglas-Peckerův algoritmus. Máte velkou sadu bodů, které jednoduše aproximují přímku, ale ve skutečnosti můžete tuto přímku aproximovat pouze dvěma body. Toto je myšlenka algoritmu.

Data byla distribuována následovně. Všechno je jednotné, ale jsou tu nějaké odlehlosti. Když jsme problém vyřešili, nedívali jsme se na něj. Hlavní věc je, že nebyly žádné třídy, kterých by bylo opravdu málo, nemuseli jsme dělat vážené samplery a převzorkování dat.

Klasifikace ručně psaných kreseb. Zpráva v Yandexu

Jak obrázky vypadaly? Toto je třída „letadlo“ a příklady z ní se štítky rozpoznané a nerozpoznané. Jejich poměr byl někde kolem 1 ku 9. Jak je vidět, data jsou poměrně zašuměná. Tipoval bych, že je to letadlo. Pokud se podíváte na nerozpoznáno, ve většině případů je to jen šum. Někdo se dokonce pokusil napsat „letadlo“, ale zřejmě ve francouzštině.

Většina účastníků jednoduše vzala mřížky, nakreslila data z této sekvence čar jako obrázky RGB a hodila je do sítě. Kreslil jsem přibližně stejným způsobem: vzal jsem paletu barev, nakreslil první čáru jednou barvou, která byla na začátku této palety, poslední čáru další, která byla na konci palety a mezi ně Všude jsem interpoloval pomocí této paletky. To mimochodem přineslo lepší výsledek, než když kreslíte jako na úplně prvním snímku – jen černě.

Další členové týmu, například Ivan Sosin, zkoušeli trochu jiné přístupy ke kreslení. Jedním kanálem jednoduše nakreslil šedý obrázek, druhým kanálem nakreslil každý tah s přechodem od začátku do konce, od 32 do 255, a třetím kanálem nakreslil přechod přes všechny tahy od 32 do 255.

Další zajímavostí je, že Alex Parinov nahrál informace do sítě pomocí kódu země.

Klasifikace ručně psaných kreseb. Zpráva v Yandexu

Metrikou používanou v soutěži je střední průměrná přesnost. Co je podstatou této metriky pro konkurenci? Můžete dát tři predikce, a pokud v těchto třech není správný predik, pak dostanete 0. Pokud je správný, pak se zohledňuje jeho pořadí. A cílový výsledek se bude počítat jako 1 děleno pořadím vaší předpovědi. Vytvořili jste například tři prediktory a ten správný je první, pak vydělíte 1 1 a dostanete 1. Pokud je prediktor správný a jeho pořadí je 2, pak vydělte 1 2, dostanete 0,5. No atd.

Klasifikace ručně psaných kreseb. Zpráva v Yandexu

S předzpracováním dat - jak kreslit obrázky a tak dále - jsme se trochu rozhodli. Jaké architektury jsme použili? Zkoušeli jsme používat tlusté architektury jako PNASNet, SENet a takové již klasické architektury jako SE-Res-NeXt, stále častěji vstupují do nových soutěží. Byly tam také ResNet a DenseNet.

Klasifikace ručně psaných kreseb. Zpráva v Yandexu

Klasifikace ručně psaných kreseb. Zpráva v Yandexu

Klasifikace ručně psaných kreseb. Zpráva v Yandexu

Jak jsme to učili? Všechny modely, které jsme pořídili, byly předem vycvičené na imagenetu. Sice je tam hodně dat, 50 milionů obrázků, ale přesto, když vezmete síť předem natrénovanou na imagenet, vykazovala lepší výsledky, než kdybyste ji jednoduše trénovali od začátku.

Jaké techniky výuky jsme použili? To je Cosing Annealing with Warm Restarts, o kterém budu mluvit o něco později. Toto je technika, kterou používám téměř na všech svých nedávných soutěžích a ukazuje se, že s nimi trénuji mřížky docela dobře, abych dosáhl dobrého minima.

Klasifikace ručně psaných kreseb. Zpráva v Yandexu

Další Snižte rychlost učení na plošině. Začnete síť trénovat, nastavíte si určitou míru učení, dál ji učíte a vaše ztráta postupně konverguje k určité hodnotě. Ověříte si to, například po dobu deseti epoch se ztráta vůbec nezměnila. Snížíte rychlost učení o nějakou hodnotu a pokračujete v učení. Znovu to trochu klesne, konverguje na nějaké minimum a vy znovu snížíte rychlost učení a tak dále, dokud se vaše síť konečně nesblíží.

Další je zajímavá technika: Neztrácejte rychlost učení, zvyšte velikost dávky. Existuje článek se stejným názvem. Když trénujete síť, nemusíte snižovat rychlost učení, můžete jednoduše zvětšit velikost dávky.

Tuto techniku ​​mimochodem používal Alex Parinov. Začal s dávkou rovnou 408, a když jeho síť dosáhla určité úrovně, jednoduše zdvojnásobil velikost dávky atd.

Ve skutečnosti si nepamatuji, jaké hodnoty jeho velikost dávky dosáhla, ale zajímavé je, že na Kaggle byly týmy, které používaly stejnou techniku, jejich velikost dávky byla asi 10000 XNUMX. Mimochodem, moderní frameworky pro hluboké učení, jako např. Velmi jednoduše vám to umožňuje například PyTorch. Vygenerujete svou dávku a odešlete ji do sítě ne tak, jak je, celou, ale rozdělíte ji na kousky tak, aby se vešla do vaší grafické karty, vypočítáte gradienty a poté, co spočítáte gradient pro celou dávku, aktualizujte závaží.

Mimochodem, do této soutěže byly stále zahrnuty velké velikosti dávek, protože data byla poměrně hlučná a velká velikost dávky vám pomohla přesněji aproximovat gradient.

Používalo se také pseudonálepkování, které většinou používal Roman Solovjev. Vzorkoval asi polovinu dat z testu v dávkách a trénoval mřížku na takových dávkách.

Na velikosti obrázků záleželo, ale je fakt, že máte hodně dat, musíte trénovat dlouho a pokud je vaše velikost obrázku dost velká, tak budete trénovat hodně dlouho. To však na kvalitě vašeho konečného klasifikátoru příliš nepřidalo, takže se vyplatilo použít nějaký kompromis. A zkoušeli jsme jen obrázky, které nebyly příliš velké.

Jak se to všechno naučilo? Nejprve byly pořízeny malé snímky, na nich bylo spuštěno několik epoch, což zabralo poměrně hodně času. Pak se daly velké obrázky, trénovala se síť, pak ještě víc, ještě víc, aby se necvičila od začátku a neztrácela spoustu času.

O optimalizátorech. Použili jsme SGD a Adama. Tímto způsobem bylo možné získat jediný model, který udával rychlost 0,941-0,946 na veřejném žebříčku, což je docela dobré.

Pokud modely nějakým způsobem seskupíte, dostanete se někde kolem 0,951. Pokud použijete ještě jednu techniku, dostanete na veřejné desce konečné skóre 0,954, stejně jako my. Ale o tom později. Dále vám řeknu, jak jsme modely sestavovali a jak se nám podařilo dosáhnout takové konečné rychlosti.

Dále bych chtěl mluvit o Cosing Annealing s teplými restarty nebo Stochastic Gradient Descent s teplými restarty. Zhruba řečeno, v zásadě můžete použít jakýkoli optimalizátor, ale jde o to, že pokud natrénujete jen jednu síť a postupně se sblíží k nějakému minimu, pak je vše v pořádku, získáte jednu síť, dělá určité chyby, ale dá se to trénovat trochu jinak. Nastavíte nějakou počáteční rychlost učení a postupně ji snižujete podle tohoto vzorce. Snížíte to, vaše síť se dostane na nějaké minimum, pak uložíte váhy a znovu nastavíte rychlost učení, která byla na začátku tréninku, čímž půjdete někam nahoru od tohoto minima a zase snížíte rychlost učení.

Můžete tak navštívit několik minim najednou, ve kterých bude vaše ztráta plus mínus stejná. Faktem však je, že sítě s těmito váhami budou na vašem datu poskytovat různé chyby. Jejich zprůměrováním získáte určitou aproximaci a vaše rychlost bude vyšší.

Klasifikace ručně psaných kreseb. Zpráva v Yandexu

O tom, jak jsme sestavovali naše modely. Na začátku prezentace jsem řekl, že si dejte pozor na množství dat v testu a počet tříd. Pokud k počtu cílů v testovací sadě přičtete 1 a vydělíte počtem tříd, dostanete číslo 330, a to bylo na fóru napsáno - že třídy v testu jsou vyrovnané. To by se dalo použít.

Na základě toho Roman Soloviev přišel s metrikou, nazvali jsme ji Proxy Score, která docela dobře korelovala s žebříčkem. Jde o to: uděláte předpověď, vezmete 1 z vašich prediktorů a spočítáte počet objektů pro každou třídu. Dále od každé hodnoty odečtěte 330 a sečtěte výsledné absolutní hodnoty.

Byly získány následující hodnoty. To nám pomohlo nevytvořit žebříček sondování, ale ověřit lokálně a vybrat koeficienty pro naše soubory.

Se souborem byste mohli dosáhnout takové rychlosti. Co jiného jsem mohl dělat? Předpokládejme, že jste použili informaci, že třídy ve vašem testu jsou vyvážené.

Vyvážení bylo jiné. Příklad jednoho z nich — balancování od kluků, kteří obsadili první místo.

co jsme udělali? Naše vyvážení bylo docela jednoduché, navrhl to Jevgenij Babachnin. Nejprve jsme seřadili naše předpovědi podle top 1 a vybrali z nich kandidáty - tak, aby počet tříd nepřesáhl 330. Ale u některých tříd skončíte s méně než 330 prediktory. Dobře, pojďme také seřadit podle top 2 a top 3 , a také vybereme kandidáty.

V čem se naše bilancování lišilo od bilancování prvního místa? Použili iterativní přístup, vzali nejoblíbenější třídu a snižovali pravděpodobnosti pro tuto třídu o nějaké malé číslo, dokud tato třída přestala být nejoblíbenější. Zúčastnili jsme se další nejoblíbenější třídy. Pokračovali v jejich snižování, dokud se počet všech tříd nevyrovnal.

Všichni používali plus mínus jeden přístup k vlakovým sítím, ale ne všichni používali balancování. Pomocí vyvažování jste mohli jít do zlata, a pokud jste měli štěstí, pak do peněz.

Jak předzpracovat datum? Všichni plus mínus stejným způsobem předzpracovávali datum – vyráběli ručně vyráběné prvky, snažili se zakódovat časování různými barvami tahu atd. O tom mluvil Alexey Nozdrin-Plotnitsky, který obsadil 8. místo.

Klasifikace ručně psaných kreseb. Zpráva v Yandexu

Udělal to jinak. Řekl, že všechny tyto vaše ručně vyrobené funkce nefungují, to nemusíte dělat, vaše síť by se to všechno měla naučit sama. A místo toho přišel s výukovými moduly, které předzpracovávaly vaše data. Vhodil do nich původní data bez předzpracování – souřadnice bodů a časování.

Pak vzal rozdíl na základě souřadnic a zprůměroval to všechno na základě časování. A přišel s poměrně dlouhou matricí. Několikrát na něj aplikoval 1D konvoluci, aby získal matici o velikosti 64xn, kde n je celkový počet bodů a 64 je vytvořeno, aby se výsledná matice přivedla do vrstvy libovolné konvoluční sítě, která přijímá počet kanálů. - 64. získal matici 64xn, z toho pak bylo nutné vytvořit tenzor nějaké velikosti, aby počet kanálů byl roven 64. Normalizoval všechny body X, Y v rozsahu od 0 do 32, aby vytvořil tenzor o velikosti 32x32. Nevím, proč chtěl 32x32, prostě se to tak stalo. A na tuto souřadnici umístil fragment této matice o velikosti 64xn. Takže to skončilo s tenzorem 32x32x64, který byste mohli vložit dále do své konvoluční neuronové sítě. To je vše, co jsem chtěl říct.

Zdroj: www.habr.com

Přidat komentář