Technika Jedi redukcji sieci splotowych - przycinanie

Technika Jedi redukcji sieci splotowych - przycinanie

Przed tobą znowu zadanie wykrywania obiektów. Priorytetem jest szybkość działania przy akceptowalnej dokładności. Bierzesz architekturę YOLOv3 i dalej ją szkolisz. Dokładność (mAp75) jest większa niż 0.95. Ale tempo biegania jest nadal niskie. Gówno.

Dziś ominiemy kwantyzację. I pod nacięciem zajrzymy Przycinanie modelu — przycięcie zbędnych części sieci w celu przyspieszenia wnioskowania bez utraty dokładności. Jasne jest, gdzie, ile i jak ciąć. Zastanówmy się, jak to zrobić ręcznie i gdzie można to zautomatyzować. Na końcu znajduje się repozytorium na keras.

Wprowadzenie

W moim poprzednim miejscu pracy, Macroscop w Permie, nabyłem jednego nawyku - zawsze monitorować czas wykonania algorytmów. I zawsze sprawdzaj czas działania sieci poprzez filtr adekwatności. Zazwyczaj najnowocześniejsze rozwiązania w produkcji nie przechodzą przez ten filtr, co doprowadziło mnie do Pruningu.

Przycinanie to stary temat omawiany w Wykłady Stanforda w 2017 r. Główną ideą jest zmniejszenie rozmiaru wytrenowanej sieci bez utraty dokładności poprzez usunięcie różnych węzłów. Brzmi fajnie, ale rzadko słyszę o jego zastosowaniu. Prawdopodobnie nie ma wystarczającej liczby wdrożeń, nie ma artykułów w języku rosyjskim lub po prostu wszyscy uważają to za przycinanie know-how i milczą.
Ale rozbierzmy to

Rzut oka na biologię

Uwielbiam, gdy Deep Learning analizuje pomysły wywodzące się z biologii. Im, podobnie jak ewolucji, można ufać (czy wiesz, że ReLU jest bardzo podobne do Funkcja aktywacji neuronów w mózgu?)

Proces przycinania modelu jest również bliski biologii. Reakcję sieci można tu porównać do plastyczności mózgu. W książce znajduje się kilka ciekawych przykładów. Normana Doidge’a:

  1. Mózg kobiety, która urodziła się z tylko jedną połówką, przeprogramował się, aby pełnić funkcje brakującej połowy.
  2. Facet odstrzelił część mózgu odpowiedzialną za widzenie. Z biegiem czasu inne części mózgu przejęły te funkcje. (nie staramy się powtarzać)

Podobnie możesz wyciąć niektóre słabe sploty ze swojego modelu. W ostateczności pozostałe wiązki pomogą zastąpić wycięte.

Czy lubisz Transfer Learning, czy uczysz się od zera?

Opcja numer jeden. Korzystasz z Transfer Learning na Yolov3. Retina, Mask-RCNN lub U-Net. Ale przez większość czasu nie musimy rozpoznawać 80 klas obiektów, jak w COCO. W mojej praktyce wszystko ogranicza się do klas 1-2. Można założyć, że architektura dla 80 klas jest tu zbędna. Sugeruje to, że należy zmniejszyć architekturę. Co więcej, chciałbym to zrobić bez utraty dotychczasowych, wytrenowanych ciężarów.

Opcja numer dwa. Być może masz dużo danych i zasobów obliczeniowych lub po prostu potrzebujesz niestandardowej architektury. Nie ma znaczenia. Ale uczysz się sieci od zera. Typowa procedura polega na przyjrzeniu się strukturze danych, wybraniu architektury o NADMIERNEJ mocy i wypchnięciu osób, które porzuciły szkolenie. Karl, widziałem 0.6 osób, które porzuciły naukę.

W obu przypadkach sieć można zmniejszyć. Zmotywowany. Teraz zastanówmy się, jaki rodzaj przycinania polega na obrzezaniu

Algorytm ogólny

Zdecydowaliśmy, że możemy usunąć wiązki. Wygląda to całkiem prosto:

Technika Jedi redukcji sieci splotowych - przycinanie

Usunięcie jakiegokolwiek splotu jest stresujące dla sieci, co zwykle prowadzi do pewnego wzrostu błędów. Z jednej strony ten wzrost błędu jest wskaźnikiem tego, jak poprawnie usuwamy sploty (np. duży wzrost wskazuje, że robimy coś źle). Ale niewielki wzrost jest całkiem akceptowalny i często jest eliminowany przez późniejsze lekkie dodatkowe szkolenie z małym LR. Dodaj dodatkowy etap szkoleniowy:

Technika Jedi redukcji sieci splotowych - przycinanie

Teraz musimy dowiedzieć się, kiedy chcemy zatrzymać pętlę Learning<->Pruning. Mogą tu pojawić się egzotyczne opcje, gdy musimy zmniejszyć sieć do określonego rozmiaru i prędkości (na przykład dla urządzeń mobilnych). Jednak najczęstszą opcją jest kontynuowanie cyklu, aż błąd stanie się większy niż akceptowalny. Dodaj warunek:

Technika Jedi redukcji sieci splotowych - przycinanie

Zatem algorytm staje się jasny. Pozostaje dowiedzieć się, jak określić usunięte zwoje.

Wyszukaj usunięte pakiety

Musimy usunąć niektóre sploty. Pędzenie przed siebie i „strzelanie” do kogokolwiek to zły pomysł, chociaż zadziała. Ale ponieważ masz głowę, możesz pomyśleć i spróbować wybrać „słabe” zwoje do usunięcia. Istnieje kilka opcji:

  1. Najmniejszy wymiar L1 lub przycinanie o małej wielkości. Pomysł, że sploty o małych masach mają niewielki wpływ na ostateczną decyzję
  2. Najmniejsza miara L1 uwzględniająca średnią i odchylenie standardowe. Uzupełniamy oceną charakteru dystrybucji.
  3. Maskowanie splotów i wykluczanie tych, które w najmniejszym stopniu wpływają na ostateczną dokładność. Dokładniejsze określenie nieistotnych splotów, ale bardzo czasochłonne i zasobożerne.
  4. Inne

Każda z opcji ma prawo do życia i własne cechy wykonawcze. Tutaj rozważamy opcję z najmniejszą miarą L1

Ręczny proces dla YOLOv3

Oryginalna architektura zawiera pozostałości bloków. Ale bez względu na to, jak fajne są dla głębokich sieci, będą nam nieco przeszkadzać. Trudność polega na tym, że nie można usunąć uzgodnień z różnymi indeksami w tych warstwach:

Technika Jedi redukcji sieci splotowych - przycinanie

Wybierzmy zatem warstwy, z których będziemy mogli dowolnie usuwać uzgodnienia:

Technika Jedi redukcji sieci splotowych - przycinanie

Teraz zbudujmy cykl pracy:

  1. Przesyłanie aktywacji
  2. Zastanawiam się, ile obciąć
  3. Wytnij to
  4. Uczenie się 10 epok z LR=1e-4
  5. Testowanie

Rozładowywanie splotów jest przydatne do oszacowania, ile części możemy usunąć w danym kroku. Przykłady rozładunku:

Technika Jedi redukcji sieci splotowych - przycinanie

Widzimy, że prawie wszędzie 5% splotów ma bardzo niską normę L1 i możemy je usunąć. Na każdym etapie rozładunek powtarzano i oceniano, które warstwy i ile można wyciąć.

Cały proces składał się z 4 kroków (liczby tutaj i wszędzie dla RTX 2060 Super):

Krok mapa75 Liczba parametrów, miliony Rozmiar sieci, mb Od początku,% Czas pracy, pani Stan obrzezania
0 0.9656 60 241 100 180 -
1 0.9622 55 218 91 175 5% wszystkich
2 0.9625 50 197 83 168 5% wszystkich
3 0.9633 39 155 64 155 15% dla warstw z ponad 400 zwojami
4 0.9555 31 124 51 146 10% dla warstw z ponad 100 zwojami

Do kroku 2 dodano jeszcze jeden pozytywny efekt – w pamięci wpasowała się porcja o rozmiarze 4, co znacznie przyspieszyło proces dodatkowego szkolenia.
W kroku 4 proces został zatrzymany, ponieważ nawet długotrwałe dodatkowe szkolenie nie podniosło mAp75 do starych wartości.
W rezultacie udało nam się przyspieszyć wnioskowanie o 15%, zmniejsz rozmiar o 35% i nie stracić dokładnie.

Automatyzacja dla prostszych architektur

W przypadku prostszych architektur sieci (bez dodawania warunkowego, łączenia i bloków resztkowych) całkiem możliwe jest skupienie się na przetwarzaniu wszystkich warstw splotowych i zautomatyzowanie procesu wycinania splotów.

Zaimplementowałem tę opcję tutaj.
To proste: potrzebujesz tylko funkcji straty, optymalizatora i generatorów wsadowych:

import pruning
from keras.optimizers import Adam
from keras.utils import Sequence

train_batch_generator = BatchGenerator...
score_batch_generator = BatchGenerator...

opt = Adam(lr=1e-4)
pruner = pruning.Pruner("config.json", "categorical_crossentropy", opt)

pruner.prune(train_batch, valid_batch)

W razie potrzeby możesz zmienić parametry konfiguracyjne:

{
    "input_model_path": "model.h5",
    "output_model_path": "model_pruned.h5",
    "finetuning_epochs": 10, # the number of epochs for train between pruning steps
    "stop_loss": 0.1, # loss for stopping process
    "pruning_percent_step": 0.05, # part of convs for delete on every pruning step
    "pruning_standart_deviation_part": 0.2 # shift for limit pruning part
}

Dodatkowo zaimplementowano ograniczenie oparte na odchyleniu standardowym. Celem jest ograniczenie usuwanej części, z wyłączeniem splotów z już „wystarczającymi” miarami L1:

Technika Jedi redukcji sieci splotowych - przycinanie

Tym samym pozwalamy na usunięcie tylko słabych splotów z rozkładów podobnych do prawego i nie wpływamy na usunięcie z rozkładów podobnych do lewego:

Technika Jedi redukcji sieci splotowych - przycinanie

Gdy rozkład zbliża się do normalnego, współczynnik przycinania_standart_deviation_part można wybrać spośród:

Technika Jedi redukcji sieci splotowych - przycinanie
Zalecam założenie 2 sigma. Możesz też zignorować tę funkcję, pozostawiając wartość < 1.0.

Wynikiem jest wykres rozmiaru sieci, strat i czasu działania sieci dla całego testu, znormalizowany do 1.0. Na przykład tutaj rozmiar sieci został zmniejszony prawie 2 razy bez utraty jakości (mała sieć splotowa o wagach 100 tys.):

Technika Jedi redukcji sieci splotowych - przycinanie

Prędkość obrotowa podlega normalnym wahaniom i pozostaje praktycznie niezmieniona. Jest na to wyjaśnienie:

  1. Liczba zwojów zmienia się z wygodnej (32, 64, 128) na niezbyt wygodną dla kart graficznych - 27, 51 itd. Mogę się tu mylić, ale najprawdopodobniej ma to wpływ.
  2. Architektura nie jest szeroka, ale spójna. Zmniejszając szerokość nie wpływamy na głębokość. W ten sposób zmniejszamy obciążenie, ale nie zmieniamy prędkości.

Dlatego poprawa wyrażała się w zmniejszeniu obciążenia CUDA podczas biegu o 20-30%, ale nie w skróceniu czasu działania

Wyniki

Zastanówmy się. Rozważaliśmy 2 opcje przycinania - dla YOLOv3 (kiedy musisz pracować rękami) i dla sieci o prostszej architekturze. Można zauważyć, że w obu przypadkach możliwe jest zmniejszenie rozmiaru sieci i przyspieszenie jej bez utraty dokładności. Wyniki:

  • Zmniejszenie rozmiaru
  • Bieg przyspieszający
  • Zmniejszanie obciążenia CUDA
  • W rezultacie przyjazność dla środowiska (Optymalizujemy przyszłe wykorzystanie zasobów obliczeniowych. Gdzieś jest się szczęśliwym Greta Thunberg)

dodatek

  • Po etapie przycinania możesz dodać kwantyzację (na przykład za pomocą TensorRT)
  • Tensorflow zapewnia możliwości dla Przycinanie o małej wielkości. Pracuje.
  • magazyn Chcę się rozwijać i chętnie pomogę

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

Dodaj komentarz