Co powinienem zrobić, gdy moja sieć neuronowa się nie uczy?

146

Trenuję sieć neuronową, ale utrata treningu nie maleje. Jak mogę to naprawić?

Nie pytam o nadmierne dopasowanie lub regularyzację. Pytam o sposób rozwiązania problemu, w którym wydajność mojej sieci nie poprawia się w zestawie szkoleniowym .


To pytanie jest celowo ogólne, aby inne pytania dotyczące treningu sieci neuronowej można zamknąć jako duplikat tego, z postawą, że „jeśli dasz człowiekowi rybę, karmisz go na jeden dzień, ale jeśli uczysz człowieku, by łowić ryby, możesz go karmić do końca życia. ” Zobacz ten wątek Meta do dyskusji: Jaki jest najlepszy sposób na odpowiedź „moja sieć neuronowa nie działa, proszę naprawić” pytania?

Jeśli twoja sieć neuronowa nie uogólnia się dobrze, zobacz: Co powinienem zrobić, gdy moja sieć neuronowa nie uogólnia się dobrze?

Sycorax
źródło
1
Oto przypadek, w którym NN nie mógł się rozwijać. youtu.be/iakFfOmanJU?t=144
Joshua
4
Blog Iwanowa „ Powody, dla których twoja sieć neuronowa nie działa ”, szczególnie sekcje II, III i IV, może być pomocny.
user5228

Odpowiedzi:

186

Testowanie jednostkowe jest twoim przyjacielem

Wśród autorów jest powiedzenie, że „Całe pisanie jest pisaniem od nowa” - to znaczy większa część pisania jest rewizji. W przypadku programistów (lub przynajmniej naukowców zajmujących się danymi) wyrażenie to może zostać zmienione na „Debugowanie całego kodowania”.

Za każdym razem, gdy piszesz kod, musisz sprawdzić, czy działa on zgodnie z przeznaczeniem. Najlepszą metodą, jaką kiedykolwiek znalazłem do weryfikacji poprawności, jest rozbicie kodu na małe segmenty i sprawdzenie, czy każdy segment działa. Można to zrobić przez porównanie wyniku segmentu z odpowiedzią, o której wiesz, że jest poprawną odpowiedzią. Nazywa się to testowaniem jednostkowym . Pisanie dobrych testów jednostkowych jest kluczem do zostania dobrym statystykiem / naukowcem danych / ekspertem w dziedzinie uczenia maszynowego / praktykiem sieci neuronowych. Po prostu nie ma substytutu.

Musisz sprawdzić, czy Twój kod jest wolny od błędów, zanim będziesz mógł dostroić wydajność sieci! W przeciwnym razie równie dobrze możesz zmienić układ leżaków na RMS Titanic .

Istnieją dwie cechy sieci neuronowych, które sprawiają, że weryfikacja jest jeszcze ważniejsza niż w przypadku innych typów uczenia maszynowego lub modeli statystycznych.

  1. Sieci neuronowe nie są „gotowymi” algorytmami, tak jak losowy regres leśny lub logistyczny. Nawet w przypadku prostych sieci z przekazywaniem informacji spoczywa w dużej mierze na użytkowniku podejmowanie licznych decyzji dotyczących konfiguracji, połączenia, inicjalizacji i optymalizacji sieci. Oznacza to pisanie kodu, a pisanie kodu oznacza debugowanie.

  2. Nawet jeśli kod sieci neuronowej działa bez zgłaszania wyjątku, sieć może nadal zawierać błędy! Błędy te mogą nawet być podstępnym rodzajem, dla którego sieć będzie trenować, ale utknie na nieoptymalnym rozwiązaniu lub sieć wynikowa nie będzie miała pożądanej architektury. ( Jest to przykład różnicy między błędem składniowym a semantycznym ).

W tym średnim poście „ Jak testować kod uczenia maszynowego jednostki ” Chase Roberts bardziej szczegółowo omawia testy jednostkowe modeli uczenia maszynowego. Ten przykład błędnego kodu pożyczyłem z artykułu:

def make_convnet(input_image):
    net = slim.conv2d(input_image, 32, [11, 11], scope="conv1_11x11")
    net = slim.conv2d(input_image, 64, [5, 5], scope="conv2_5x5")
    net = slim.max_pool2d(net, [4, 4], stride=4, scope='pool1')
    net = slim.conv2d(input_image, 64, [5, 5], scope="conv3_5x5")
    net = slim.conv2d(input_image, 128, [3, 3], scope="conv4_3x3")
    net = slim.max_pool2d(net, [2, 2], scope='pool2')
    net = slim.conv2d(input_image, 128, [3, 3], scope="conv5_3x3")
    net = slim.max_pool2d(net, [2, 2], scope='pool3')
    net = slim.conv2d(input_image, 32, [1, 1], scope="conv6_1x1")
    return net

Czy widzisz błąd? Wiele różnych operacji nie jest faktycznie używanych, ponieważ poprzednie wyniki są nadpisywane nowymi zmiennymi. Korzystanie z tego bloku kodu w sieci nadal będzie się trenować, a wagi będą się aktualizować, a utrata może nawet spaść - ale kod zdecydowanie nie robi tego, co było zamierzone. (Autor jest również niekonsekwentny w stosowaniu pojedynczych lub podwójnych cudzysłowów, ale jest to czysto stylistyczny).

Najczęstsze błędy programowania dotyczące sieci neuronowych to

  • Zmienne są tworzone, ale nigdy nie są używane (zwykle z powodu błędów kopiowania i wklejania);
  • Wyrażenia dotyczące aktualizacji gradientu są niepoprawne;
  • Aktualizacje wagi nie są stosowane;
  • Funkcje strat nie są mierzone we właściwej skali (na przykład utratę entropii można wyrazić w kategoriach prawdopodobieństwa lub logarytmów)
  • Utrata nie jest odpowiednia dla zadania (na przykład przy użyciu kategorycznej utraty entropii krzyżowej dla zadania regresji).

Czołgaj się przed tobą; Idź zanim uciekniesz

Szerokie i głębokie sieci neuronowe oraz sieci neuronowe z egzotycznym okablowaniem są obecnie najważniejszym elementem uczenia maszynowego. Ale sieci te nie powstały w pełni uformowane; ich projektanci zbudowali je z mniejszych jednostek. Najpierw zbuduj małą sieć z jedną ukrytą warstwą i sprawdź, czy działa poprawnie. Następnie stopniowo zwiększaj złożoność modelu i sprawdź, czy każdy z nich również działa.

  • Zbyt mało neuronów w warstwie może ograniczyć reprezentację, której uczy się sieć, powodując niedopasowanie. Zbyt wiele neuronów może powodować nadmierne dopasowanie, ponieważ sieć „zapamiętuje” dane treningowe.

    Nawet jeśli możesz udowodnić, że matematycznie jest tylko niewielka liczba neuronów niezbędnych do modelowania problemu, często zdarza się, że posiadanie „kilku kolejnych” neuronów ułatwia optymalizatorowi znalezienie „dobrej” konfiguracji. (Ale nie sądzę, aby ktokolwiek w pełni rozumiał, dlaczego tak jest.) Podaję tutaj przykład tego w kontekście problemu XOR: Czy moje iteracje nie są potrzebne do trenowania NN dla XOR z MSE <0,001 zbyt wysokim? .

  • Wybór liczby ukrytych warstw pozwala sieci nauczyć się abstrakcji na podstawie surowych danych. Głębokie uczenie się jest obecnie modne, a sieci z dużą liczbą warstw pokazały imponujące wyniki. Ale dodanie zbyt wielu ukrytych warstw może spowodować zbyt duże ryzyko lub bardzo utrudnić optymalizację sieci.

  • Wybór sprytnego okablowania sieciowego może zrobić dla ciebie wiele pracy. Czy Twoje źródło danych jest dostosowane do wyspecjalizowanych architektur sieciowych? Konwolucyjne sieci neuronowe mogą osiągać imponujące wyniki w „strukturalnych” źródłach danych, danych obrazu lub dźwięku. Nawracające sieci neuronowe mogą dobrze sobie radzić z sekwencyjnymi typami danych, takimi jak język naturalny lub dane szeregów czasowych. Pozostałe połączenia mogą poprawić sieci z głębokim sprzężeniem zwrotnym.

Szkolenie w sieci neuronowej przypomina wybieranie blokady

Aby osiągnąć najnowszy stan techniki, a nawet po prostu dobre wyniki, musisz skonfigurować wszystkie części skonfigurowane tak, aby dobrze ze sobą współpracowały . Konfigurowanie konfiguracji sieci neuronowej, która faktycznie się uczy, jest bardzo podobne do wybierania blokady: wszystkie elementy muszą być ustawione w jednej linii . Podobnie jak nie wystarczy mieć jeden kubek we właściwym miejscu, tak samo nie wystarczy mieć tylko architekturę, czy tylko optymalizator, poprawnie skonfigurowany.

Strojenie opcji konfiguracji nie jest tak proste, jak stwierdzenie, że jeden rodzaj wyboru konfiguracji (np. Szybkość uczenia się) jest mniej lub bardziej ważny niż inny (np. Liczba jednostek), ponieważ wszystkie te opcje współdziałają ze wszystkimi innymi wyborami, więc jeden wybór może mieć się dobrze w połączeniu z innym wyborem dokonanym gdzie indziej .

Jest to niewyczerpująca lista opcji konfiguracji, które nie są również opcjami regularyzacji ani opcjami optymalizacji numerycznej.

Wszystkie te tematy są aktywnymi obszarami badań.

Optymalizacja niewypukła jest trudna

Funkcja celu sieci neuronowej jest wypukła tylko wtedy, gdy nie ma ukrytych jednostek, wszystkie aktywacje są liniowe, a matryca projektowa ma pełną rangę - ponieważ ta konfiguracja jest identycznym problemem regresji.

We wszystkich innych przypadkach problem optymalizacji nie jest wypukły, a optymalizacja niewypukła jest trudna. Wyzwania związane z treningiem sieci neuronowych są dobrze znane (patrz: Dlaczego trudno trenować głębokie sieci neuronowe? ). Ponadto sieci neuronowe mają bardzo dużą liczbę parametrów, co ogranicza nas do metod wyłącznie pierwszego rzędu (patrz: Dlaczego metoda Newtona nie jest szeroko stosowana w uczeniu maszynowym? ). To bardzo aktywny obszar badań.

  • Ustawienie zbyt dużej szybkości uczenia się spowoduje rozbieżność optymalizacji, ponieważ przeskoczysz z jednej strony „kanionu” na drugą. Ustawienie tej zbyt małej wartości uniemożliwi wykonywanie jakichkolwiek rzeczywistych postępów i możliwe, że hałas związany z SGD będzie przytłaczał oszacowania gradientu.

  • Obcinanie gradientu przeskalowuje normę gradientu, jeśli jest powyżej pewnego progu. Kiedyś myślałem, że jest to parametr „ustaw i zapomnij”, zwykle 1.0, ale odkryłem, że mogę znacznie ulepszyć model językowy LSTM, ustawiając go na 0,25. Nie wiem dlaczego tak jest.

  • Planowanie szybkości uczenia się może obniżyć szybkość uczenia się w trakcie szkolenia. Z mojego doświadczenia wynika, że ​​próba użycia harmonogramu jest bardzo podobna do wyrażenia regularnego : zastępuje jeden problem („Jak nauczyć się kontynuować po określonej epoce?”) Dwoma problemami („Jak mogę nauczyć się kontynuować po określonej epoce ? ”i„ Jak wybrać dobry harmonogram? ”). Inni twierdzą, że planowanie jest niezbędne. Pozwolę ci zdecydować.

  • Wybór dobrego rozmiaru mini-partii może pośrednio wpłynąć na proces uczenia się, ponieważ większa mini-partia będzie miała mniejszą wariancję ( ) niż mniejsza mini-partia. Chcesz, aby mini-partia była wystarczająco duża, aby informować o kierunku gradientu, ale wystarczająco mała, aby SGD mogła uregulować sieć.

  • Istnieje wiele wariantów stochastycznego spadku gradientu, które wykorzystują pęd, adaptacyjne wskaźniki uczenia się, aktualizacje Niestierowa i tak dalej, aby ulepszyć SGD waniliowy. Projektowanie lepszego optymalizatora jest bardzo aktywnym obszarem badań. Kilka przykładów:

  • Gdy pojawił się po raz pierwszy, optymalizator Adam cieszył się dużym zainteresowaniem. Jednak niektóre ostatnie badania wykazały, że SGD z pędem może przewyższyć adaptacyjne metody gradientu dla sieci neuronowych. „ Marginalna wartość adaptacyjnych metod gradientowych w uczeniu maszynowym ” Ashii C. Wilson, Rebecca Roelofs, Mitchell Sterna, Nathana Srebro, Benjamina Rechta

  • Ale z drugiej strony, ten bardzo niedawny artykuł proponuje nowy optymalizator adaptacyjnej szybkości uczenia się, który rzekomo zamyka lukę między metodami adaptacyjnej szybkości uczenia się a SGD. „ Zamykanie luki uogólniającej w adaptacyjnych metodach gradientowych w szkoleniu głębokich sieci neuronowych ” Jinghui Chen, Quanquan Gu

    Zaobserwowano, że metody gradientu adaptacyjnego, które przyjmują historyczne informacje o gradiencie w celu automatycznego dostosowania szybkości uczenia się, generalizują gorsze niż stochastyczne obniżanie gradientu (SGD) z pędem w uczeniu głębokich sieci neuronowych. To pozostawia otwarty problem, jak zamknąć lukę uogólniającą w metodach gradientu adaptacyjnego. W tej pracy pokazujemy, że metody gradientu adaptacyjnego, takie jak Adam, Amsgrad, są czasami „nadmiernie dostosowane”. Projektujemy nowy algorytm, zwany Częściowo adaptacyjną metodą szacowania pędu (Padam), który łączy Adama / Amsgrada z SGD, aby osiągnąć to, co najlepsze z obu światów. Eksperymenty na standardowych testach porównawczych pokazują, że Padam może utrzymać szybki wskaźnik konwergencji jako Adam / Amsgrad, jednocześnie uogólniając, a także SGD w szkoleniu głębokich sieci neuronowych.

Normalizacja

Skala danych może mieć duży wpływ na trening.

Regularyzacja

Wybór i dostrajanie regularyzacji sieci jest kluczową częścią budowy modelu, który dobrze się uogólnia (tj. Modelu, który nie jest zbyt dopasowany do danych treningowych). Jednak w momencie, gdy twoja sieć stara się zmniejszyć utratę danych treningowych - gdy sieć się nie uczy - regularyzacja może ukryć problem.

Kiedy moja sieć się nie uczy, wyłączam wszelką regularyzację i sprawdzam, czy sieć nieregulowana działa poprawnie. Następnie dodaję z powrotem każdy element regulacyjny i sprawdzam, czy każdy z nich działa po drodze.

Ta taktyka może wskazać, gdzie pewna regularyzacja może być źle ustawiona. Niektóre przykłady to

Prowadź dziennik eksperymentów

Kiedy konfiguruję sieć neuronową, nie koduję na stałe ustawień parametrów. Zamiast tego robię to w pliku konfiguracyjnym (np. JSON), który jest odczytywany i używany do zapełniania szczegółów konfiguracji sieci w czasie wykonywania. Trzymam wszystkie te pliki konfiguracyjne. Jeśli dokonam modyfikacji parametru, utworzę nowy plik konfiguracyjny. Na koniec dołączam jako komentarz wszystkie straty przypadające na epokę w celu szkolenia i walidacji.

Powodem, dla którego mam obsesję na punkcie zachowania starych wyników, jest to, że bardzo łatwo jest wrócić i przejrzeć poprzednie eksperymenty. Zabezpiecza również przed błędnym powtórzeniem tego samego ślepego eksperymentu. Z psychologicznego punktu widzenia, ale także pozwala spojrzeć wstecz i obserwować „Cóż, projekt nie może być tam, gdzie chcę być dzisiaj, ale robię postępy w stosunku do miejsca, gdzie byłem tygodnie temu.”k

Jako przykład chciałem dowiedzieć się o modelach językowych LSTM, dlatego postanowiłem stworzyć bota Twittera, który będzie pisać nowe tweety w odpowiedzi na innych użytkowników Twittera. Pracowałem nad tym w wolnym czasie, między szkołą średnią a pracą. Zajęło to około roku, a ja przejrzałem ponad 150 różnych modeli, zanim dotarłem do modelu, który zrobił to, co chciałem: wygenerować nowy tekst w języku angielskim, który (w pewnym sensie) ma sens. (Jednym kluczowym punktem spornym i jednym z powodów, dla których tyle prób było, jest to, że nie wystarczyło po prostu uzyskać małą stratę poza próbą, ponieważ wczesne modele o niskiej stracie udało się zapamiętać dane treningowe, więc w odpowiedzi na podpowiedzi odtwarzał po prostu dosłownie bloki tekstu dosłownie - zajęło mi to trochę czasu, aby model stał się bardziej spontaniczny i nadal miał niską stratę).

Sycorax
źródło
11
Wiele dobrych porad. Interesujące jest to, ile z twoich komentarzy jest podobnych do komentarzy, które poczyniłem (lub widziałem inne) w związku z debugowaniem oszacowania parametrów lub prognoz dla złożonych modeli ze schematami próbkowania MCMC. (Na przykład kod może wydawać się działać, jeśli nie jest poprawnie zaimplementowany.)
Glen_b
11
@Glen_b Nie sądzę, aby najlepsze praktyki kodowania były wystarczająco doceniane w większości programów nauczania statystyk / uczenia maszynowego, dlatego tak mocno podkreśliłem ten punkt. Widziałem wiele postów NN, w których OP zostawił komentarz w stylu „och, znalazłem błąd, teraz działa”
Sycorax,
7
Uczę programowania w nauce o danych w Pythonie i tak naprawdę wykonujemy funkcje i testy jednostkowe pierwszego dnia, jako podstawowe pojęcia. Walcząc dobrą walkę.
Matthew Drury,
8
+1 dla „Całe kodowanie jest debugowane”. Dziwi mnie, jak wiele plakatów na SO wydaje się myśleć, że kodowanie to proste ćwiczenie wymagające niewielkiego wysiłku; którzy oczekują, że ich kod będzie działał poprawnie przy pierwszym uruchomieniu; i którzy wydają się nie być w stanie kontynuować, gdy tak nie jest. Zabawne jest to, że są w połowie poprawne: kodowanie jest łatwe - ale programowanie jest trudne.
Bob Jarvis,
41

Opublikowane odpowiedzi są świetne i chciałem dodać kilka „Sprawdzeń poczytalności”, które bardzo mi pomogły w przeszłości.

1) Trenuj swój model w jednym punkcie danych. Jeśli to zadziała, trenuj na dwóch wejściach o różnych wyjściach.

To weryfikuje kilka rzeczy. Po pierwsze, szybko pokazuje, że Twój model może się uczyć, sprawdzając, czy Twój model może przewyższyć Twoje dane. W moim przypadku ciągle popełniam głupie błędy popełniając Dense(1,activation='softmax')vs Dense(1,activation='sigmoid')dla predykcji binarnych, a pierwsza daje śmieciowe wyniki.

Jeśli twój model nie jest w stanie przekroczyć kilku punktów danych, to albo jest za mały (co jest mało prawdopodobne w dzisiejszym wieku), albo coś jest nie tak z jego strukturą lub algorytmem uczenia się.

2) Zwróć uwagę na swoją początkową stratę.

Kontynuując przykład binarny, jeśli twoje dane to 30% zera i 70% 1, to twoja początkowa oczekiwana strata około . Wynika to z faktu, że Twój model powinien zacząć się od przypadkowego zgadywania.L=0.3ln(0.5)0.7ln(0.5)0.7

Wiele razy widzisz początkową utratę czegoś niedorzecznego, na przykład 6.5. Pod względem koncepcyjnym oznacza to, że twój wynik jest mocno nasycony, na przykład w kierunku 0. Na przykład , więc jeśli widzisz stratę większą niż 1, prawdopodobnie model jest bardzo przekrzywiony. Zwykle dzieje się tak, gdy wagi sieci neuronowej nie są odpowiednio zrównoważone, szczególnie bliżej softmax / sigmoid. To powie ci, jeśli twoja inicjalizacja jest zła.0.3ln(0.99)0.7ln(0.01)=3.2

Możesz przestudiować to dalej, przewidując model na kilku tysiącach przykładów, a następnie histogramując wyniki. Jest to szczególnie przydatne do sprawdzania, czy dane są poprawnie znormalizowane. Na przykład, jeśli oczekujesz silnego odchylenia wyników w kierunku 0, dobrym pomysłem może być transformacja oczekiwanych wyników (danych treningowych) poprzez wyprowadzenie pierwiastków kwadratowych z oczekiwanych wyników. Pozwoli to uniknąć problemów z gradientem dla nasyconych sigmoidów na wyjściu.

3) Uogólnij dane wyjściowe modelu do debugowania

Na przykład wyobraź sobie, że używasz LSTM do przewidywania na podstawie danych szeregów czasowych. Być może w twoim przykładzie zależy Ci tylko na najnowszej prognozie, więc Twój LSTM generuje pojedynczą wartość, a nie sekwencję. Przełącz LSTM, aby zwracać prognozy na każdym kroku (w keras to jest return_sequences=True). Następnie możesz spojrzeć na wyjścia w stanie ukrytym po każdym kroku i upewnić się, że są one rzeczywiście różne. Zastosowanie tego ma na celu upewnienie się, że podczas maskowania sekwencji (tj. Uzupełniania ich danymi, aby miały równą długość), LSTM poprawnie ignoruje zamaskowane dane. Bez uogólnienia modelu nigdy nie znajdziesz tego problemu .

4) Spójrz na poszczególne warstwy

Tensorboard zapewnia użyteczny sposób wizualizacji wyników warstwy . Może to pomóc upewnić się, że wejścia / wyjścia są prawidłowo znormalizowane w każdej warstwie. Może również łapać aktywacje błędne. Można również wyszukiwać dane wyjściowe warstw w kamerach w serii prognoz, a następnie szukać warstw, które mają podejrzanie wypaczone aktywacje (wszystkie 0 lub wszystkie niezerowe).

5) Najpierw zbuduj prostszy model

Zdecydowałeś, że najlepszym sposobem rozwiązania problemu jest użycie CNN w połączeniu z wykrywaczem obwiedni, który dalej przetwarza kadry obrazu, a następnie używa LSTM do połączenia wszystkiego. Inicjalizacja modelu zajmuje 10 minut.

Zamiast tego utwórz partię fałszywych danych (ten sam kształt) i podziel model na części. Następnie stwórz atrapowe modele zamiast każdego komponentu (twój „CNN” może być pojedynczym 2x2 20-krokowym splotem, LSTM z tylko 2 ukrytymi jednostkami). Pomoże to upewnić się, że struktura modelu jest poprawna i że nie występują żadne dodatkowe problemy. Przez jakiś czas walczyłem z takim modelem, a kiedy wypróbowałem prostszą wersję, dowiedziałem się, że jedna z warstw nie została odpowiednio zamaskowana z powodu błędu keras. Możesz łatwo (i szybko ) sprawdzać wewnętrzne warstwy modelu i sprawdzać, czy poprawnie skonfigurowałeś wykres.

6) Standaryzuj wersje przetwarzania wstępnego i wersje pakietów

W szczególności sieci neuronowe są wyjątkowo wrażliwe na niewielkie zmiany danych. Na przykład dwa popularne pakiety ładujące obrazy to cv2i PIL. Tylko z powodu otwarcia pliku JPEG oba te pakiety generują nieco inne obrazy. Różnice są zwykle bardzo małe, ale od czasu do czasu można zauważyć spadek wydajności modelu z powodu tego rodzaju rzeczy. Debugowanie staje się koszmarem: uzyskałeś wynik walidacji podczas treningu, a następnie używasz innego modułu ładującego i uzyskujesz inną dokładność w tym samym zbitym zestawie danych.

Więc jeśli pobierasz czyjś model z github, zwróć szczególną uwagę na jego wstępne przetwarzanie. Jakich programów ładujących używają? Jakich procedur przetwarzania obrazu używają? Jakiej interpolacji używają podczas zmiany rozmiaru obrazu? Czy najpierw zmieniają rozmiar, a następnie normalizują obraz? Albo na odwrót? Jaka jest kolejność kanałów dla obrazów RGB?

Najbezpieczniejszym sposobem standaryzacji pakietów jest użycie requirements.txtpliku, który przedstawia wszystkie twoje pakiety, tak jak w konfiguracji systemu szkoleniowego, aż do keras==2.1.5numerów wersji. Teoretycznie użycie Dockera razem z tym samym GPU, co w systemie treningowym, powinno dać takie same wyniki.

Alex R.
źródło
7
(+1) Sprawdzanie początkowej straty jest świetną sugestią. Żałuję, że pominąłem tę odpowiedź.
Sycorax,
7
Zapewnienie, że Twój model może się dopasować, jest doskonałym pomysłem. Jestem tak przyzwyczajony do myślenia o nadmiernym dopasowaniu jako o słabości, że nigdy nie myślałem wprost (dopóki o tym nie wspomniałeś), że zdolność do nadmiernego dopasowania jest siłą.
John Coleman,
15

Na początku nie trenuj sieci neuronowej!

Wszystkie odpowiedzi są świetne, ale jest jedna kwestia, o której należy wspomnieć: czy można się czegoś nauczyć z danych? (co można uznać za pewien rodzaj testowania).

Jeśli etykieta, którą próbujesz przewidzieć, jest niezależna od twoich funkcji, prawdopodobne jest, że utrata treningów będzie trudna do zredukowania.

Zamiast tego zacznij kalibrować regresję liniową, losowy las (lub dowolną metodę, którą lubisz, której liczba hiperparametrów jest niska i której zachowanie możesz zrozumieć).

Następnie, jeśli osiągniesz przyzwoitą wydajność na tych modelach (lepiej niż przypadkowe zgadywanie), możesz zacząć dostrajać sieć neuronową (a odpowiedź @Sycorax rozwiąże większość problemów).

RUser4512
źródło
5
Zgadzam się z tą odpowiedzią. Sieci neuronowe i inne formy ML są „tak gorące teraz”. Często pomija się prostsze formy regresji. Ponadto, jeśli chodzi o wyjaśnienie twojego modelu, ktoś przyjdzie i zapyta „jaki jest wpływ na wynik?” i wszystko, co będziesz w stanie zrobić, to wzruszyć ramionami. Szukaj rozwiązań Machine Learning tylko wtedy, gdy zawiodły Cię prostsze techniki. xk
Ingolifs,
11

U podstaw podstawowego przepływu pracy dotyczącego szkolenia modelu NN / DNN jest zawsze mniej więcej to samo:

  1. zdefiniuj architekturę NN (ile warstw, jaki rodzaj warstw, połączenia między warstwami, funkcje aktywacyjne itp.)

  2. odczytaj dane z jakiegoś źródła (Internet, baza danych, zestaw plików lokalnych itp.), spójrz na kilka próbek (aby upewnić się, że import poszedł dobrze) i wykonaj czyszczenie danych w razie potrzeby. Ten krok nie jest tak trywialny, jak się zwykle uważa. Powodem jest to, że w przypadku DNN zwykle mamy do czynienia z gigantycznymi zestawami danych, o kilka rzędów wielkości większych niż to, do czego jesteśmy przyzwyczajeni, kiedy dopasowujemy bardziej standardowe nieliniowe parametryczne modele statystyczne (teoretycznie NN należą do tej rodziny).

  3. w jakiś sposób znormalizować lub ujednolicić dane. Ponieważ NN są modelami nieliniowymi, normalizacja danych może wpływać nie tylko na stabilność numeryczną, ale także na czas treningu i wyniki NN (funkcja liniowa, taka jak normalizacja, nie działa z nieliniową funkcją hierarchiczną).

  4. podzielić dane w zestawie szkoleniowym / walidacyjnym / testowym lub w wielu miejscach, jeśli stosowana jest walidacja krzyżowa.

  5. trenuj sieć neuronową, jednocześnie kontrolując straty w zestawie walidacyjnym. Tutaj możesz cieszyć się oszałamiającymi przyjemnościami nie wypukłej optymalizacji, w której nie wiesz, czy istnieje jakieś rozwiązanie, czy istnieje wiele rozwiązań, które są najlepszym rozwiązaniem pod względem błędu uogólnienia i jak blisko jesteś to. Porównanie utraty treningu i krzywej utraty weryfikacji prowadzi cię oczywiście, ale nie lekceważ twardej postawy NN (a zwłaszcza DNN): często wykazują (może powoli) malejącą utratę treningu / walidacji, nawet jeśli masz paraliżujące błędy w twoim kodzie.

  6. Sprawdź dokładność zestawu testowego i zrób kilka wykresów / tabel diagnostycznych.

  7. Wróć do punktu 1, ponieważ wyniki nie są dobre. Powtórz ad nauseam .

Oczywiście szczegóły zmienią się w zależności od konkretnego przypadku użycia, ale mając na uwadze to szorstkie płótno, możemy pomyśleć o tym, co może pójść nie tak.

Podstawowe kontrole architektury

Może to być źródłem problemów. Zazwyczaj dokonuję wstępnych kontroli:

  • poszukaj prostej architektury, która dobrze działa na twoim problemie (na przykład MobileNetV2 w przypadku klasyfikacji obrazów) i zastosuj odpowiednią inicjalizację (na tym poziomie zwykle będzie działać losowo). Jeśli to poprawnie ćwiczy na twoich danych, przynajmniej wiesz, że nie ma rażących problemów w zestawie danych. Jeśli nie możesz znaleźć prostej, przetestowanej architektury, która działa w twoim przypadku, pomyśl o prostej linii bazowej . Na przykład klasyfikator Naive Bayes do klasyfikacji (lub nawet tylko klasyfikacja zawsze najbardziej powszechnej klasy) lub model ARIMA do prognozowania szeregów czasowych

  • Zbuduj testy jednostkowe. Zaniedbanie tego (i użycie cholernego notesu Jupyter) są zwykle głównymi przyczynami problemów w kodzie NN, o których sprawdzenie muszę poprosić, szczególnie gdy model ma zostać wdrożony w środowisku produkcyjnym. Ponieważ najbardziej pozytywna odpowiedź obejmowała już testy jednostkowe, dodam tylko, że istnieje biblioteka, która obsługuje opracowywanie testów jednostkowych dla NN (niestety tylko w Tensorflow).

Zestaw treningowy

Dokładnie sprawdź swoje dane wejściowe. Sprawdź, czy odwróciłeś etykiety zestawu treningowego i zestawu testów, na przykład (zdarzyło mi się to raz -___-), czy też zaimportowałeś niewłaściwy plik. Spójrz na kilka próbek wejściowych i powiązane etykiety i upewnij się, że mają one sens. Sprawdź, czy znormalizowane dane są naprawdę znormalizowane (spójrz na ich zakres). Ponadto rzeczywiste zestawy danych są brudne: do celów klasyfikacji może występować wysoki poziom szumu na etykiecie (próbki posiadające niewłaściwą etykietę klasy) lub w przypadku wielowymiarowych prognoz szeregów czasowych, niektóre składniki szeregów czasowych mogą zawierać wiele brakujących danych ( Widziałem liczby nawet 94% dla niektórych danych wejściowych).

Kolejność, w jakiej zestaw treningowy jest podawany do siatki podczas treningu, może mieć wpływ. Spróbuj losowo przetasować zestaw treningowy ( bez przerywania powiązania między danymi wejściowymi i wyjściowymi ) i sprawdź, czy strata treningowa spadnie.

Wreszcie najlepszym sposobem sprawdzenia, czy masz problemy z zestawem treningowym, jest użycie innego zestawu treningowego. Jeśli zajmujesz się klasyfikacją obrazów, zamiast zebranych obrazów, użyj standardowego zestawu danych, takiego jak CIFAR10 lub CIFAR100 (lub ImageNet, jeśli możesz sobie na to pozwolić). Te zestawy danych są dobrze przetestowane: jeśli Twoja utrata treningu spadnie tutaj, ale nie na oryginalnym zestawie danych, możesz mieć problemy w zestawie danych.

Wykonaj złote testy

Są dwa testy, które nazywam Złotymi Testami, które są bardzo przydatne do znalezienia problemów w NN, które nie trenują:

  • zredukuj zestaw treningowy do 1 lub 2 próbek i trenuj na tym. NN powinien natychmiast prześcignąć zestaw treningowy, bardzo szybko osiągając dokładność 100% na zestawie treningowym, podczas gdy dokładność na zestawie walidacyjnym / testowym spadnie do 0%. Jeśli tak się nie stanie, oznacza to błąd w kodzie.

  • test odwrotny: zachowujesz pełny zestaw treningowy, ale przetasujesz etykiety. Jedynym sposobem, w jaki NN może się teraz nauczyć, jest zapamiętanie zestawu treningowego, co oznacza, że ​​utrata treningu maleje bardzo powoli, a utrata testu rośnie bardzo szybko. W szczególności powinieneś osiągnąć losową utratę szansy na zestawie testowym . Oznacza to, że jeśli masz 1000 klas, powinieneś osiągnąć dokładność 0,1%. Jeśli nie widzisz żadnej różnicy między utratą treningu przed i po tasowaniu etykiet, oznacza to, że Twój kod jest wadliwy (pamiętaj, że już sprawdziliśmy etykiety zestawu szkoleniowego w kroku wcześniej).

Sprawdź, czy Twoje dane treningowe mają sens

Dokładność (utrata 0-1) to kiepska miara, jeśli masz silną nierównowagę klasy. Wypróbuj coś bardziej znaczącego, na przykład utratę entropii: nie tylko chcesz poprawnie klasyfikować, ale chcesz klasyfikować z dużą dokładnością.

Wydobądź wielkie pistolety

Jeśli nic nie pomogło, nadszedł czas, aby zacząć bawić się hiperparametrami. Jest to z pewnością najgorsza część treningu NN, ale są to gigantyczne, nierozpoznawalne modele, których parametry są dopasowane, rozwiązując niewypukłą optymalizację, więc tych iteracji często nie można uniknąć.

  • wypróbuj różne optymalizatory: SGD trenuje wolniej, ale prowadzi to do mniejszego błędu generalizacji, podczas gdy Adam trenuje szybciej, ale utrata testu zatrzymuje się na wyższej wartości
  • spróbuj zmniejszyć rozmiar partii
  • początkowo zwiększyć współczynnik uczenia się, a następnie go zmniejszyć lub zastosować cykliczny współczynnik uczenia się
  • dodaj warstwy
  • dodaj ukryte jednostki
  • usuń regularyzację stopniowo (może zmienić normę wsadową na kilka warstw). Strata treningowa powinna się teraz zmniejszyć, ale utrata testowa może wzrosnąć.
  • wizualizować rozkład wag i odchyleń dla każdej warstwy. Nigdy nie musiałem się tu dostać, ale jeśli używasz BatchNorm, możesz spodziewać się w przybliżeniu standardowych normalnych dystrybucji. Sprawdź, czy norma wag rośnie nienormalnie z epokami.
  • jeśli podczas szkolenia wystąpi jakiś błąd, google google . Zmarnowałem jeden ranek, próbując naprawić doskonale działającą architekturę, ale tylko po to, aby dowiedzieć się, że zainstalowana wersja Keras miała wadliwe wsparcie dla wielu GPU i musiałem ją zaktualizować. Czasami musiałem zrobić coś przeciwnego (obniżyć wersję pakietu).
  • zaktualizuj swoje CV i zacznij szukać innej pracy :-)
DeltaIV
źródło
+1, ale „cholerny notatnik Jupyter”? Chcesz to skomentować? :)
ameba
2
Oto dlaczego nienawidzę notesów Jupyter . TL; DR: stan ukryty, różnicowanie to ból, problemy z bezpieczeństwem i zachęca do złych praktyk programistycznych, takich jak niestosowanie testów jednostkowych / regresyjnych / integracyjnych. Szkolenie NN jest już wystarczająco trudne, bez ludzi zapominających o podstawach programowania.
DeltaIV
2
Być może jestem zbyt negatywny, ale szczerze mówiąc, mam dość ludzi, którzy klonują notesy Jupyter z GitHub, myśląc, że dostosowanie kodu do ich przypadku użycia zajmie tylko kilka minut, a potem przyjdzie mi narzekać, że nic nie działa. Na litość boską, zdobądź prawdziwe IDE, takie jak PyCharm lub VisualStudio Code i stwórz dobrze skonstruowany kod, zamiast gotować Notatnik! Zwłaszcza jeśli planujesz wysłać model do produkcji, znacznie to ułatwi.
DeltaIV
2
Lol. „Notatnik Jupyter” i „testowanie jednostkowe” są anty-skorelowane.
Sycorax
2
(+1) To jest dobry zapis. Sugestie dotyczące testów randomizacji to naprawdę świetne sposoby na uzyskanie dostępu do uszkodzonych sieci.
Sycorax
6

Jeśli model się nie uczy, istnieje spora szansa, że ​​Twoja propagacja wsteczna nie działa. Ale jest tak wiele rzeczy, które mogą pójść nie tak z modelem czarnej skrzynki, takim jak Neural Network, jest wiele rzeczy, które musisz sprawdzić. Myślę, że zarówno Sycorax, jak i Alex zapewniają bardzo dobre kompleksowe odpowiedzi. Chcę tylko dodać jedną technikę, która nie została jeszcze omówiona.

W kursie uczenia maszynowego Andrew Ng sugeruje uruchomienie sprawdzania gradientu w pierwszych kilku iteracjach, aby upewnić się, że propagacja wsteczna działa prawidłowo. Zasadniczo chodzi o obliczenie pochodnej poprzez zdefiniowanie dwóch punktów z interwałem . Upewnienie się, że pochodna w przybliżeniu odpowiada wynikowi z propagacji wstecznej, powinno pomóc w zlokalizowaniu problemu.ϵ

Anthony Lei
źródło