Klasyfikacja rysunków rękopiśmiennych. Zgłoś w Yandex

Kilka miesięcy temu nasi koledzy z Google zużyty na Kaggle konkurs na stworzenie klasyfikatora obrazów uzyskanych w trybie rewelacyjnym gra "Szybkie losowanie!" Zespół, w skład którego wchodził programista Yandex Roman Własow, zajął w konkursie czwarte miejsce. Na styczniowym szkoleniu z uczenia maszynowego Roman podzielił się pomysłami swojego zespołu, finalną implementacją klasyfikatora i ciekawymi praktykami swoich przeciwników.


- Cześć wszystkim! Nazywam się Roma Własow, dzisiaj opowiem Wam o Quick, Draw! Wyzwanie rozpoznawania bazgrołów.

Klasyfikacja rysunków rękopiśmiennych. Zgłoś w Yandex

W naszej drużynie było pięć osób. Dołączyłem tuż przed ostatecznym terminem połączenia. Mieliśmy pecha, byliśmy trochę wstrząśnięci, ale wstrząśnięto nami z pozycji pieniężnej, a ich z pozycji złotej. I zajęliśmy zaszczytne czwarte miejsce.

(W trakcie zawodów zespoły obserwowały siebie w ocenie, która została utworzona na podstawie wyników pokazanych w jednej części proponowanego zbioru danych. Z kolei ostateczna ocena została utworzona w innej części zbioru danych. Odbywa się to w ten sposób że uczestnicy konkursu nie dostosowują swoich algorytmów do konkretnych danych, dlatego w finale przy przełączaniu między ocenami pozycje nieco się trzęsą (od angielskiego shake up - to mix): na innych danych wynik może się okazać być inni. Zespół Romana był pierwszy w pierwszej trójce. W tym przypadku pierwsza trójka to pieniądze, strefa oceny pieniężnej, ponieważ tylko trzy pierwsze miejsca otrzymały nagrodę pieniężną. Po przetasowaniach zespół był już w czwarte miejsce. W ten sam sposób druga drużyna straciła zwycięstwo, złotą pozycję. - wyd.)

Klasyfikacja rysunków rękopiśmiennych. Zgłoś w Yandex

Rywalizacja była również znacząca, ponieważ Jewgienij Babachnin otrzymał arcymistrza, Iwan Sosin otrzymał mistrza, Roman Sołowiew pozostał arcymistrzem, Aleksiej Parinow otrzymał mistrza, ja zostałem ekspertem, a teraz jestem już mistrzem.

Klasyfikacja rysunków rękopiśmiennych. Zgłoś w Yandex

Co to jest ten Quick, Draw? To jest usługa Google. Celem Google było popularyzowanie sztucznej inteligencji i za pomocą tej usługi chciał pokazać, jak działają sieci neuronowe. Idziesz tam, klikasz Narysujmy i pojawia się nowa strona, na której mówisz: narysuj zygzak, masz na to 20 sekund. Próbujesz narysować zygzak w 20 sekund, jak na przykład tutaj. Jeśli ci się uda, sieć powie, że to zygzak i idziesz dalej. Takich zdjęć jest tylko sześć.

Jeżeli sieć Google nie rozpoznała tego, co narysowałeś, przy zadaniu umieszczano krzyżyk. Później powiem Ci, co będzie oznaczać w przyszłości to, czy rysunek zostanie rozpoznany przez sieć, czy nie.

Usługa ta skupiała dość dużą liczbę użytkowników, a wszystkie narysowane przez nich obrazki były logowane.

Klasyfikacja rysunków rękopiśmiennych. Zgłoś w Yandex

Udało nam się zebrać prawie 50 milionów zdjęć. Na tej podstawie powstał termin pociągu i testu naszych zawodów. Nawiasem mówiąc, ilość danych w teście i liczba klas nie bez powodu zostały wyróżnione pogrubioną czcionką. Opowiem o nich trochę później.

Format danych był następujący. To nie są tylko obrazy RGB, ale, z grubsza mówiąc, dziennik wszystkiego, co zrobił użytkownik. Naszym celem jest słowo, kod kraju to miejsce, z którego pochodzi autor doodla, a znacznik czasu to czas. Rozpoznana etykieta pokazuje tylko, czy sieć rozpoznała obraz z Google, czy nie. A sam rysunek jest sekwencją, przybliżeniem krzywej, którą użytkownik rysuje za pomocą punktów. I czasy. Jest to czas od rozpoczęcia rysowania obrazu.

Klasyfikacja rysunków rękopiśmiennych. Zgłoś w Yandex

Dane zaprezentowano w dwóch formatach. To jest pierwszy format, a drugi jest uproszczony. Wycięli stamtąd czasy i przybliżyli ten zestaw punktów za pomocą mniejszego zestawu punktów. Do tego używali Algorytm Douglasa-Peckera. Masz duży zbiór punktów, który po prostu przybliża linię prostą, ale w rzeczywistości możesz przybliżyć tę linię za pomocą tylko dwóch punktów. Taka jest idea algorytmu.

Dane zostały rozesłane w następujący sposób. Wszystko jest jednolite, ale są pewne odstępstwa. Kiedy rozwiązaliśmy problem, nie przyglądaliśmy się temu. Najważniejsze, że nie było klas, których byłoby naprawdę mało, nie musieliśmy robić ważonych próbek i oversamplingu danych.

Klasyfikacja rysunków rękopiśmiennych. Zgłoś w Yandex

Jak wyglądały zdjęcia? To jest klasa „samolot” i jej przykłady z rozpoznanymi i nierozpoznanymi etykietami. Ich stosunek oscylował w okolicach 1 do 9. Jak widać, dane są dość zaszumione. Przypuszczam, że to samolot. Jeśli spojrzysz na nierozpoznane, w większości przypadków jest to po prostu hałas. Ktoś nawet próbował napisać „samolot”, ale najwyraźniej po francusku.

Większość uczestników po prostu wzięła siatki, narysowała dane z tej sekwencji linii w postaci obrazów RGB i wrzuciła je do sieci. Rysowałem mniej więcej w ten sam sposób: wziąłem paletę kolorów, narysowałem pierwszą kreskę jednym kolorem, który był na początku tej palety, ostatnią kreskę innym, który był na końcu palety i pomiędzy nimi Interpolowałem wszędzie, używając tej palety. Swoją drogą dało to lepszy efekt niż rysowanie jak na pierwszym slajdzie – tylko na czarno.

Inni członkowie zespołu, jak na przykład Ivan Sosin, próbowali nieco innego podejścia do rysowania. Jednym kanałem narysował po prostu szary obraz, drugim kanałem narysował każdą kreskę z gradientem od początku do końca, od 32 do 255, a trzecim kanałem narysował gradient po wszystkich kreskach od 32 do 255.

Kolejną interesującą rzeczą jest to, że Alex Parinov przesłał informacje do sieci przy użyciu kodu kraju.

Klasyfikacja rysunków rękopiśmiennych. Zgłoś w Yandex

Miarą używaną w konkursie jest średnia średnia precyzja. Jaka jest istota tego miernika dla konkurencji? Można podać trzy predykaty i jeżeli w tych trzech nie będzie żadnego predyktora prawidłowego, to otrzymamy 0. Jeżeli jest predykat poprawny, wówczas brana jest pod uwagę jego kolejność. Wynik docelowy będzie liczony jako 1 podzielony przez kolejność przewidywań. Na przykład stworzyłeś trzy predyktory i ten pierwszy jest prawidłowy, następnie dzielisz 1 przez 1 i otrzymujesz 1. Jeśli predyktor jest poprawny i jego rząd wynosi 2, to dzielisz 1 przez 2, otrzymasz 0,5. Cóż, itp.

Klasyfikacja rysunków rękopiśmiennych. Zgłoś w Yandex

Jeśli chodzi o wstępne przetwarzanie danych - jak rysować obrazy i tak dalej - trochę zdecydowaliśmy. Z jakich architektur korzystaliśmy? Próbowaliśmy wykorzystać grube architektury takie jak PNASNet, SENet oraz takie już klasyczne architektury jak SE-Res-NeXt, coraz częściej wchodzą one w nowe konkursy. Były też ResNet i DenseNet.

Klasyfikacja rysunków rękopiśmiennych. Zgłoś w Yandex

Klasyfikacja rysunków rękopiśmiennych. Zgłoś w Yandex

Klasyfikacja rysunków rękopiśmiennych. Zgłoś w Yandex

Jak tego uczyliśmy? Wszystkie modele, które wzięliśmy, zostały wstępnie przeszkolone w imagenet. Chociaż jest dużo danych, 50 milionów obrazów, ale jeśli weźmiesz pod uwagę sieć wstępnie przeszkoloną w imagenet, uzyskasz lepsze wyniki, niż gdybyś po prostu przeszkolił ją od zera.

Jakie techniki nauczania stosowaliśmy? Jest to wyżarzanie Cosing z ciepłym ponownym uruchomieniem, o którym opowiem nieco później. Jest to technika, którą stosuję na prawie wszystkich moich ostatnich zawodach i okazuje się, że całkiem nieźle trenuję siatki, aby osiągnąć dobre minimum.

Klasyfikacja rysunków rękopiśmiennych. Zgłoś w Yandex

Następnie zmniejsz tempo uczenia się na płaskowyżu. Rozpoczynasz trenowanie sieci, ustalasz określoną szybkość uczenia się, kontynuujesz jej uczenie, a twoja strata stopniowo zbliża się do określonej wartości. Sprawdzasz to np. przez dziesięć epok strata w ogóle się nie zmieniła. Zmniejszasz tempo uczenia się o pewną wartość i kontynuujesz naukę. Znowu trochę spada, osiąga pewną minimalną zbieżność, a ty ponownie zmniejszasz szybkość uczenia się i tak dalej, aż twoja sieć w końcu osiągnie zbieżność.

Następna jest interesująca technika: nie zmniejszaj szybkości uczenia się, zwiększ rozmiar partii. Istnieje artykuł o tym samym tytule. Ucząc sieć, nie trzeba zmniejszać szybkości uczenia się, można po prostu zwiększyć rozmiar wsadu.

Nawiasem mówiąc, tę technikę zastosował Alex Parinov. Zaczął od partii równej 408, a kiedy jego sieć osiągnęła pewien poziom plateau, po prostu podwoił wielkość partii itp.

Tak naprawdę nie pamiętam, jaką wartość osiągnęła wielkość jego partii, ale ciekawe jest to, że na Kaggle były zespoły, które stosowały tę samą technikę, ich wielkość partii wynosiła około 10000 XNUMX. Swoją drogą nowoczesne frameworki do głębokiego uczenia się, takie jak Na przykład PyTorch pozwala to zrobić bardzo łatwo. Generujesz wsad i przesyłasz go do sieci nie w całości, ale dzielisz go na kawałki, tak aby zmieścił się na Twojej karcie graficznej, obliczasz gradienty i po obliczeniu gradientu dla całej wsadu aktualizujesz ciężary.

Nawiasem mówiąc, w tej konkurencji nadal uwzględniano duże partie, ponieważ dane były dość zaszumione, a duży rozmiar partii pomagał w dokładniejszym przybliżeniu gradientu.

Stosowano także pseudo-etykietowanie, stosowane głównie przez Romana Sołowjowa. Pobrał próbki około połowy danych z testu partiami i trenował siatkę na takich partiach.

Rozmiar zdjęć miał znaczenie, ale faktem jest, że danych jest dużo, trzeba długo trenować, a jeśli rozmiar zdjęcia jest dość duży, to będziesz trenował bardzo długo. Nie wpłynęło to jednak zbytnio na jakość końcowego klasyfikatora, dlatego warto było zastosować jakiś kompromis. Próbowaliśmy tylko zdjęć, które nie były zbyt duże.

Jak się tego wszystkiego nauczył? Najpierw robiono zdjęcia małych rozmiarów, nanoszono na nie kilka epok, co zajmowało sporo czasu. Potem dano zdjęcia wielkoformatowe, nauczono sieć, potem jeszcze więcej, jeszcze więcej, żeby nie uczyć jej od zera i nie tracić dużo czasu.

O optymalizatorach. Użyliśmy SGD i Adama. W ten sposób udało się uzyskać pojedynczy model, który na ogólnodostępnej tablicy wyników dawał prędkość na poziomie 0,941-0,946, co jest całkiem niezłym wynikiem.

Jeśli w jakiś sposób połączysz modele, otrzymasz wynik w okolicach 0,951. Jeśli zastosujesz jeszcze jedną technikę, otrzymasz końcowy wynik na tablicy publicznej 0,954, tak jak my. Ale o tym później. Następnie opowiem Wam jak składaliśmy modele i jak udało nam się osiągnąć tak końcową prędkość.

Następnie chciałbym porozmawiać o wyżarzaniu Cosing z ciepłymi restartami lub stochastycznym opadaniu gradientowym z ciepłymi restartami. Z grubsza rzecz biorąc, w zasadzie możesz użyć dowolnego optymalizatora, ale chodzi o to, że jeśli po prostu wytrenujesz jedną sieć i stopniowo osiągnie ona pewne minimum, to wszystko jest w porządku, otrzymasz jedną sieć, popełnia pewne błędy, ale ty można go trenować trochę inaczej. Ustawisz pewną początkową szybkość uczenia się i stopniowo ją obniżysz zgodnie z tym wzorem. Obniżasz go, twoja sieć dochodzi do pewnego minimum, następnie zapisujesz ciężary i ponownie ustawiasz tempo uczenia się, które było na początku treningu, w ten sposób przechodząc gdzieś w górę od tego minimum i ponownie obniżając tempo uczenia się.

W ten sposób możesz odwiedzić kilka minimów jednocześnie, w których Twoja strata będzie taka sama, plus lub minus. Ale faktem jest, że sieci z tymi wagami będą dawać różne błędy w Twojej dacie. Uśredniając je, otrzymasz pewnego rodzaju przybliżenie, a Twoja prędkość będzie wyższa.

Klasyfikacja rysunków rękopiśmiennych. Zgłoś w Yandex

O tym, jak składaliśmy nasze modele. Na początku prezentacji mówiłem, żeby zwracać uwagę na ilość danych w teście i ilość zajęć. Jeśli do liczby celów w zestawie testowym dodamy 1 i podzielimy przez liczbę klas, otrzymamy liczbę 330, a na forum pisano o tym, że klasy w teście są zbilansowane. Można to wykorzystać.

Na tej podstawie Roman Soloviev opracował wskaźnik, który nazwaliśmy Proxy Score, który całkiem dobrze korelował z tabelą liderów. Rzecz w tym, że dokonujesz przewidywania, wybierasz 1 z pierwszych predyktorów i liczysz liczbę obiektów dla każdej klasy. Następnie odejmij 330 od każdej wartości i dodaj otrzymane wartości bezwzględne.

Uzyskano następujące wartości. Pomogło nam to nie tworzyć wnikliwej tabeli liderów, ale zweryfikować lokalnie i wybrać współczynniki dla naszych zespołów.

Z zespołem można by osiągnąć taką prędkość. Co jeszcze mógłbym zrobić? Załóżmy, że użyłeś informacji, że klasy w twoim teście są zrównoważone.

Balansowanie było inne. Przykład jednego z nich — balansując pomiędzy chłopakami, którzy zajęli pierwsze miejsce.

Co zrobiliśmy? Nasze balansowanie było dość proste, zasugerował to Evgeny Babakhnin. Najpierw posortowaliśmy nasze przewidywania według pierwszej 1 i wybraliśmy z nich kandydatów - tak, aby liczba klas nie przekroczyła 330. Jednak w przypadku niektórych klas otrzymujemy mniej niż 330 predyktorów. OK, posortujmy także według pierwszych 2 i najlepszych 3 , a także wybierzemy kandydatów.

Czym różniło się nasze równoważenie od równoważenia na pierwszym miejscu? Zastosowali podejście iteracyjne, biorąc najpopularniejszą klasę i zmniejszając prawdopodobieństwa dla tej klasy o niewielką liczbę, aż przestała być ona najpopularniejszą klasą. Wybraliśmy następną najpopularniejszą klasę. I tak dalej je obniżali, aż liczba wszystkich klas się zrównała.

Wszyscy stosowali podejście plus minus jeden do sieci kolejowych, ale nie wszyscy stosowali równoważenie. Korzystając z balansu, możesz zamienić się w złoto, a jeśli będziesz miał szczęście, w pieniądze.

Jak wstępnie przetworzyć datę? Wszyscy wstępnie przetwarzali datę, plus lub minus, w ten sam sposób – tworząc ręcznie wykonane elementy, próbując zakodować taktowanie różnymi kolorami obrysów itp. Dokładnie o tym mówił Aleksiej Nozdrin-Płotnicki, który zajął 8. miejsce.

Klasyfikacja rysunków rękopiśmiennych. Zgłoś w Yandex

Zrobił to inaczej. Powiedział, że wszystkie te Twoje ręcznie wykonane funkcje nie działają, nie musisz tego robić, Twoja sieć powinna się tego wszystkiego nauczyć. Zamiast tego wymyślił moduły edukacyjne, które wstępnie przetwarzają Twoje dane. Wrzucił do nich oryginalne dane bez wstępnego przetwarzania – współrzędne punktów i czasy.

Następnie wziął różnicę na podstawie współrzędnych i uśrednił ją na podstawie czasów. I wymyślił dość długą matrycę. Zastosował do niego kilkakrotnie splot 1D, aby otrzymać macierz o rozmiarze 64xn, gdzie n jest całkowitą liczbą punktów, a 64 wykonuje się w celu doprowadzenia powstałej macierzy do warstwy dowolnej sieci splotowej, która akceptuje liczbę kanałów - 64. otrzymał macierz 64xn, następnie należało z niej utworzyć tensor o pewnej wielkości, aby liczba kanałów wynosiła 64. Znormalizował wszystkie punkty X, Y w zakresie od 0 do 32, aby utworzyć tensor o wymiarach 32x32. Nie wiem dlaczego chciał 32x32, po prostu tak wyszło. I pod tą współrzędną umieścił fragment tej matrycy o rozmiarze 64xn. Skończyło się więc na tensorze 32x32x64, który można umieścić dalej w swojej splotowej sieci neuronowej. To wszystko, co chciałem powiedzieć.

Źródło: www.habr.com

Dodaj komentarz