Czy można podawać obrazy o zmiennej wielkości jako dane wejściowe do splotowej sieci neuronowej?
17
Czy możemy podać obrazy o zmiennej wielkości jako dane wejściowe do splotowej sieci neuronowej w celu wykrywania obiektów? Jeśli to możliwe, jak możemy to zrobić?
Ale jeśli spróbujemy przyciąć obraz, stracimy część obrazu i jeśli spróbujemy zmienić jego rozmiar, wówczas jasność obrazu zostanie utracona. Czy to oznacza, że korzystanie z wrodzonej właściwości sieci jest najlepsze, jeśli głównym celem jest klarowność obrazu?
Można to zrobić na wiele sposobów. Większość z nich została już opisana w wielu postach na stronach StackOverflow, Quora i innych witrynach z treścią.
Podsumowując, większość wymienionych technik można podzielić na dwie klasy rozwiązań, a mianowicie:
Transformacje
Nieodłącznym Network nieruchomości
W transformacjach można wyszukiwać techniki takie jak
Zmień rozmiar , co jest najprostszą ze wszystkich wymienionych technik
Kadrowanie , które można wykonać jako okno przesuwne lub jednorazowe z utratą informacji
Można również przyjrzeć się sieciom, które mają nieodłączną właściwość, aby być odpornym na rozmiar danych wejściowych na podstawie zachowania warstw, które buduje sieć. Przykłady tego można znaleźć pod względem,
Sieci w pełni splotowe (FCN) , które nie mają żadnych ograniczeń co do wielkości wejściowej, ponieważ po opisaniu rozmiarów jądra i stopni krok po kroku konwolucja w każdej warstwie może generować odpowiednie dane wyjściowe wymiarów zgodnie z odpowiednimi danymi wejściowymi.
Spatial Pyramid Pooling (SPP) , FCN nie mają w pełni połączonej gęstej warstwy, a zatem są agnostyczne w stosunku do wielkości obrazu, ale powiedzmy, że jeśli ktoś chciałby użyć gęstej warstwy bez rozważania transformacji wejściowych, to jest ciekawy artykuł, który wyjaśnia tę warstwę w sieć głębokiego uczenia się.
Teoretycznie to brzmi dobrze, ale nie działa w Tensorflow. Czy ktoś ma dla tego jakieś implementacje?
Hossein
1
@Hossein Wpadłem również na pewne problemy w praktycznej implementacji, ale mam dziś zmienną wielkość CNN pracującą w Tensorflow Keras 2.x z pewnymi ograniczeniami. W swojej odpowiedzi zamieściłem zarys tego podejścia w odniesieniu do niektórych praktycznych szczegółów. Powodzenia!
J Trana
4
Warstwy splotowe i same pule są niezależne od wymiarów wejściowych. Jednak wyjście warstw splotowych będzie miało różne rozmiary przestrzenne dla obrazów o różnych rozmiarach, a to spowoduje problem, jeśli później będziemy mieć w pełni połączoną warstwę (ponieważ nasza w pełni połączona warstwa wymaga wejścia o stałym rozmiarze). Istnieje kilka rozwiązań tego:
1. Globalne zestawianie: Unikaj w pełni połączonych warstw na końcu warstw splotowych i zamiast tego używaj tworzenia zestawów (takich jak globalne zestawianie średnie), aby zredukować mapy obiektów z kształtu (N, H, W, C) (przed zestawem globalnym ) do kształtu (N, 1,1, C) (za globalną pulą), gdzie:
N = liczba próbek mini-partii
H = wysokość przestrzenna mapy obiektów
W = szerokość przestrzenna mapy obiektów
C = liczba map obiektów (kanałów)
As Jak widać, wymiar wyjściowy (N * C) jest teraz niezależny od wielkości przestrzennej (H, W) map obiektów. W przypadku klasyfikacji możesz następnie użyć w pełni połączonej warstwy na wierzchu, aby uzyskać logi dla swoich klas.
2. Pula o zmiennej wielkości:Użyj regionów puli o zmiennej wielkości, aby uzyskać ten sam rozmiar mapy obiektów dla różnych rozmiarów wejściowych.
3. Przycinanie / zmiana rozmiaru / padanie obrazów wejściowych: Możesz spróbować przeskalować / przyciąć / padnąć obrazy wejściowe, aby wszystkie miały ten sam kształt.
W kontekście uczenia się transferu możesz chcieć użyć danych wejściowych o innym rozmiarze niż dane wejściowe, z którymi model został przeszkolony. Oto kilka opcji:
4. Utwórz nowe w pełni połączone warstwy: Możesz całkowicie porzucić oryginalne w pełni połączone warstwy i zainicjować nową w pełni połączoną warstwę o potrzebnych wymiarach i trenować ją od zera.
5. Traktuj całkowicie połączoną warstwę jako splot: Zwykle przekształcamy mapy funkcji z (N, H, W, C) na (N, H * W * C) przed podaniem jej do w pełni połączonej warstwy. Ale w pełni połączoną warstwę można również traktować jako splot z polem odbiorczym (H, W). Następnie możesz po prostu przekonwertować to jądro za pomocą map obiektów niezależnie od ich wielkości (w razie potrzeby użyj zerowania) [http://cs231n.github.io/transfer-learning/ ].
Musiałem dziś rozwiązać ten problem, więc pomyślałem, że podzielę się tym, co okazało się skuteczne. Przekonałem się, że w sieci było sporo odpowiedzi i „ciekawostek”, które mogłyby zadziałać w teorii, ale mniej z praktycznego „oto jak konkretnie to zaimplementować”.
Aby zaimplementować to za pomocą Tensorflow Keras, musiałem wykonać następujące czynności. Być może ktoś inny odkryje, że niektóre z nich można zmodyfikować, zrelaksować lub upuścić.
Ustaw wejście sieci, aby umożliwić wprowadzanie zmiennej wielkości, używając „Brak” jako wymiaru zastępczego w pliku_wejściowym. Zobacz odpowiedź Francoisa Cholleta tutaj .
Używaj warstw splotowych tylko do momentu wystąpienia globalnej operacji pulowania (np. GlobalMaxPooling2D). Następnie można użyć gęstych warstw itp., Ponieważ rozmiar jest teraz ustalony.
Użyj wielkości partii tylko 1. Pozwala to uniknąć radzenia sobie z mieszanymi rozmiarami w ramach partii.
Napisz małą niestandardową sekwencję, która tworzy partie wielkości 1 z listy danych wejściowych. Zrobiłem to, aby uniknąć radzenia sobie z różnymi rozmiarami w jednej tablicy Numpy.
Użyj Model.fit_generator na niestandardowej sekwencji do treningu i walidacji. (vs Model.fit)
Z jakiegoś powodu Model.predict_generator wyskoczył nawet podczas używania Sekwencji jak wyżej. Musiałem skorzystać z Model.predict na poszczególnych danych wejściowych.
Pamiętaj, że wywołania Model.predict narzekały na wydajność - co nie jest zaskakujące, biorąc pod uwagę nieefektywność rozwiązania - ale działa!
Tak, po prostu wybierz odpowiednią sieć szkieletową, która nie zależy od rozmiaru obrazu wejściowego, aby być jakąś dokładną wartością - większość sieci spełnia te kryteria.
Nie mylisz się, ale twoja odpowiedź nie jest zbyt pouczająca - co powiesz na jej rozszerzenie, aby wyjaśnić, dlaczego większość współczesnych CNN może pracować z obrazami o różnych rozmiarach? Jakie są ograniczenia tej zmienności (na przykład nie próbuj mieszać obrazów o różnych rozmiarach w tej samej mini-partii ...)? Większość osób pochodzących zarówno ze starych MLP (długość wejściowa jest ustalona), jak i ze starych CNN (AlexNet i VGG-1X), z ich nieznośnymi Flattenwarstwami, nie rozumie, w jaki sposób nowoczesne CNN mogą w zasadzie robić zdjęcia dowolnej wielkości.
Warstwy splotowe i same pule są niezależne od wymiarów wejściowych. Jednak wyjście warstw splotowych będzie miało różne rozmiary przestrzenne dla obrazów o różnych rozmiarach, a to spowoduje problem, jeśli później będziemy mieć w pełni połączoną warstwę (ponieważ nasza w pełni połączona warstwa wymaga wejścia o stałym rozmiarze). Istnieje kilka rozwiązań tego:
1. Globalne zestawianie: Unikaj w pełni połączonych warstw na końcu warstw splotowych i zamiast tego używaj tworzenia zestawów (takich jak globalne zestawianie średnie), aby zredukować mapy obiektów z kształtu (N, H, W, C) (przed zestawem globalnym ) do kształtu (N, 1,1, C) (za globalną pulą), gdzie:
N = liczba próbek mini-partii
H = wysokość przestrzenna mapy obiektów
W = szerokość przestrzenna mapy obiektów
C = liczba map obiektów (kanałów)
As Jak widać, wymiar wyjściowy (N * C) jest teraz niezależny od wielkości przestrzennej (H, W) map obiektów. W przypadku klasyfikacji możesz następnie użyć w pełni połączonej warstwy na wierzchu, aby uzyskać logi dla swoich klas.
2. Pula o zmiennej wielkości:Użyj regionów puli o zmiennej wielkości, aby uzyskać ten sam rozmiar mapy obiektów dla różnych rozmiarów wejściowych.
3. Przycinanie / zmiana rozmiaru / padanie obrazów wejściowych: Możesz spróbować przeskalować / przyciąć / padnąć obrazy wejściowe, aby wszystkie miały ten sam kształt.
W kontekście uczenia się transferu możesz chcieć użyć danych wejściowych o innym rozmiarze niż dane wejściowe, z którymi model został przeszkolony. Oto kilka opcji:
4. Utwórz nowe w pełni połączone warstwy: Możesz całkowicie porzucić oryginalne w pełni połączone warstwy i zainicjować nową w pełni połączoną warstwę o potrzebnych wymiarach i trenować ją od zera.
5. Traktuj całkowicie połączoną warstwę jako splot: Zwykle przekształcamy mapy funkcji z (N, H, W, C) na (N, H * W * C) przed podaniem jej do w pełni połączonej warstwy. Ale w pełni połączoną warstwę można również traktować jako splot z polem odbiorczym (H, W). Następnie możesz po prostu przekonwertować to jądro za pomocą map obiektów niezależnie od ich wielkości (w razie potrzeby użyj zerowania) [http://cs231n.github.io/transfer-learning/ ].
źródło
Musiałem dziś rozwiązać ten problem, więc pomyślałem, że podzielę się tym, co okazało się skuteczne. Przekonałem się, że w sieci było sporo odpowiedzi i „ciekawostek”, które mogłyby zadziałać w teorii, ale mniej z praktycznego „oto jak konkretnie to zaimplementować”.
Aby zaimplementować to za pomocą Tensorflow Keras, musiałem wykonać następujące czynności. Być może ktoś inny odkryje, że niektóre z nich można zmodyfikować, zrelaksować lub upuścić.
Pamiętaj, że wywołania Model.predict narzekały na wydajność - co nie jest zaskakujące, biorąc pod uwagę nieefektywność rozwiązania - ale działa!
źródło
Tak, po prostu wybierz odpowiednią sieć szkieletową, która nie zależy od rozmiaru obrazu wejściowego, aby być jakąś dokładną wartością - większość sieci spełnia te kryteria.
źródło
Flatten
warstwami, nie rozumie, w jaki sposób nowoczesne CNN mogą w zasadzie robić zdjęcia dowolnej wielkości.