Gram trochę z konwekcjami. W szczególności korzystam z zestawu danych kaggle koty kontra psy, który składa się z 25 000 obrazów oznaczonych jako kot lub pies (po 12500 każdego).
Udało mi się osiągnąć około 85% dokładności klasyfikacji na moim zestawie testowym, jednak wyznaczyłem sobie cel osiągnięcia 90% dokładności.
Moim głównym problemem jest nadmierne dopasowanie. Jakoś zawsze tak się dzieje (zwykle po epoce 8-10). Architektura mojej sieci jest luźno zainspirowana przez VGG-16, a dokładniej moje obrazy są zmieniane na , a następnie uruchamiam:
Convolution 1 128x128x32 (kernel size is 3, strides is 1)
Convolution 2 128x128x32 (kernel size is 3, strides is 1)
Max pool 1 64x64x32 (kernel size is 2, strides is 2)
Convolution 3 64x64x64 (kernel size is 3, strides is 1)
Convolution 4 64x64x64 (kernel size is 3, strides is 1)
Max pool 2 32x32x64 (kernel size is 2, strides is 2)
Convolution 5 16x16x128 (kernel size is 3, strides is 1)
Convolution 6 16x16x128 (kernel size is 3, strides is 1)
Max pool 3 8x8x128 (kernel size is 2, strides is 2)
Convolution 7 8x8x256 (kernel size is 3, strides is 1)
Max pool 4 4x4x256 (kernel size is 2, strides is 2)
Convolution 8 4x4x512 (kernel size is 3, strides is 1)
Fully connected layer 1024 (dropout 0.5)
Fully connected layer 1024 (dropout 0.5)
Wszystkie warstwy oprócz ostatniej mają relus jako funkcje aktywacyjne.
Zauważ, że próbowałem różnych kombinacji zwojów (zacząłem od prostszych zwojów).
Ponadto powiększyłem zestaw danych, tworząc kopię lustrzaną obrazów, dzięki czemu mam w sumie 50000 obrazów.
Ponadto normalizuję obrazy przy użyciu normalizacji min max, gdzie X jest obrazem
Kod jest zapisany w tensorflow, a wielkości partii to 128.
Mini-partie danych treningowych kończą się nadmiernym dopasowaniem i mają dokładność 100%, podczas gdy dane walidacyjne wydają się przestać się uczyć na poziomie około 84-85%.
Próbowałem także zwiększyć / zmniejszyć współczynnik rezygnacji.
Stosowanym optymalizatorem jest AdamOptimizer o współczynniku uczenia się 0,0001
W tej chwili gram z tym problemem przez ostatnie 3 tygodnie i wydaje się, że 85% postawiło przede mną barierę.
Dla przypomnienia, wiem, że mógłbym użyć uczenia się transferowego, aby osiągnąć znacznie wyższe wyniki, ale interesuje mnie budowanie tej sieci jako samodzielnego uczenia się.
Aktualizacja:
Używam sieci SAME z inną wielkością partii, w tym przypadku używam dużo mniejszej wielkości partii (16 zamiast 128) do tej pory osiągam 87,5% dokładności (zamiast 85%). To powiedziawszy, sieć i tak kończy się przeregulowaniem. Nadal nie rozumiem, w jaki sposób rezygnacja z 50% jednostek nie pomaga ... oczywiście robię tutaj coś złego. Jakieś pomysły?
Aktualizacja 2:
Wygląda na to, że problem miał związek z rozmiarem partii, ponieważ przy mniejszym rozmiarze (16 zamiast 128) osiągam teraz 92,8% dokładności na moim zestawie testowym, przy mniejszym rozmiarze partii sieć wciąż się przesadza (mini-partie kończą się z dokładnością 100%) strata (błąd) stale maleje i ogólnie jest bardziej stabilna. Wady są DUŻO wolniejsze, ale warto poczekać.
źródło
Odpowiedzi:
Ok, więc po wielu eksperymentach udało mi się uzyskać pewne wyniki / spostrzeżenia.
Po pierwsze, wszystko jest równe, mniejsze partie w zestawie treningowym bardzo pomagają w zwiększeniu ogólnej wydajności sieci, ponieważ po stronie negatywnej proces uczenia się jest o wiele wolniejszy.
Po drugie, dane są ważne, nic nowego tutaj, ale jak się dowiedziałem podczas walki z tym problemem, więcej danych zawsze wydaje się nieco pomagać.
Po trzecie, porzucenie jest przydatne w dużych sieciach z dużą ilością danych i dużą ilością iteracji, w mojej sieci zastosowałem porzucenie tylko na końcowych, w pełni połączonych warstwach, warstwy splotowe nie zostały zastosowane.
Czwarty punkt (i tego uczę się w kółko): sieci neuronowe dużo trenują, nawet na dobrych GPU (trenowałem tę sieć na Floydhub, który wykorzystuje dość drogie karty NVIDIA), więc PATIENCJA jest kluczem .
Ostateczny wniosek: Wielkość partii jest ważniejsza niż mogłoby się wydawać, najwyraźniej łatwiej jest osiągnąć lokalne minimum, gdy partie są większe.
Kod, który napisałem, jest dostępny jako notatnik Pythona, myślę, że jest dobrze udokumentowany
https://github.com/moriano/loco-learning/blob/master/cats-vs-dogs/cats-vs-dogs.ipynb
źródło
NOTE USE EITHER mean centering or min-max, NOT BOTH
. Obecnieinput_fn
dzielę moje obrazy wejściowe przez 255 wewnątrz mojego (API Tensorflow Estimator). Następnie w modelu uruchamiam te dane wejściowe za pomocą normy wsadowej. Czy nadal powinienem wykonać tylko jedną z tych normalizacji? Zobacz github.com/formigone/tf-imagenet/blob/master/models/…Sugeruję przeanalizowanie wykresów uczenia się pod kątem twojej dokładności walidacji, jak sugerował Neil Slater. Następnie, jeśli spadki dokładności sprawdzania poprawności spróbują zmniejszyć rozmiar sieci (wydaje się zbyt głęboka), dodaj porzucenie do warstw CONV i BatchNormalizacja po każdej warstwie. Może pomóc pozbyć się przeuczenia i zwiększyć dokładność testu.
źródło
Istnieje kilka możliwych rozwiązań Twojego problemu.
Użyj Dropout również we wcześniejszych warstwach (warstwach splotowych).
Twoja sieć wydaje się dość duża jak na tak „łatwe” zadanie; spróbuj to zmniejszyć. Duże architektury są również szkolone na znacznie większych zestawach danych.
Jeśli chcesz zachować swoją „dużą” architekturę, spróbuj:
Powiększanie obrazu w celu wirtualnego zwiększenia danych treningowych
Spróbuj treningu przeciwnika. Czasami pomaga.
źródło
Jedna rzecz, o której jeszcze nie wspomniano i którą możesz rozważyć na przyszłość: nadal możesz zwiększyć swój brak dostępu do w pełni połączonych warstw.
Czytałem kiedyś artykuł, w którym zastosowano 90% wskaźnik rezygnacji. Chociaż miał wiele wielu węzłów (2048, jeśli dobrze pamiętam), próbowałem tego na warstwach z mniejszą liczbą węzłów i w niektórych przypadkach było to bardzo pomocne.
Właśnie sprawdziłem, który to papier. Nie pamiętam, który papier właśnie zapamiętałem, ale znalazłem te, które również odniosły sukces dzięki 90% wskaźnikowi rezygnacji.
źródło
Też miałem ten problem. Po spędzeniu z nim godzinami, przez przypadek postanowiłem przetasować dane przed podaniem ich do systemu i voila, zaczęło działać. Trochę zajęło mi zrozumienie, że to właśnie przetasowanie załatwiło sprawę! Mam nadzieję, że to ocali kogoś przed frustracją!
źródło