Automatyczne różnicowanie - Automatic differentiation

W matematyki i algebry komputerowej , automatyczny różnicowania ( AD ), zwany również algorytmicznego różnicowania , obliczeniowej różnicowania , auto-różnicowania , lub po prostu autodiff , to zestaw technik oceny pochodną z funkcji określonej przez program komputerowy. AD wykorzystuje fakt, że każdy program komputerowy, nieważne jak skomplikowany, wykonuje sekwencję elementarnych operacji arytmetycznych (dodawanie, odejmowanie, mnożenie, dzielenie itp.) oraz podstawowych funkcji (exp, log, sin, cos itp.). Stosując wielokrotnie regułę łańcucha do tych operacji, pochodne dowolnego rzędu mogą być obliczane automatycznie, z dokładnością roboczą i przy użyciu co najwyżej małego współczynnika stałego więcej operacji arytmetycznych niż w programie oryginalnym.

Rysunek 1: Jak automatyczne różnicowanie ma się do różnicowania symbolicznego

Różnicowanie automatyczne różni się od różniczkowania symbolicznego i różniczkowania numerycznego (metody różnic skończonych). Różnicowanie symboliczne może prowadzić do nieefektywnego kodu i trudności z przekształceniem programu komputerowego w pojedyncze wyrażenie, podczas gdy różnicowanie numeryczne może wprowadzać błędy zaokrąglania w procesie dyskretyzacji i anulowania. Obie klasyczne metody mają problemy z obliczaniem wyższych pochodnych, gdzie wzrasta złożoność i błędy. Wreszcie, zarówno klasyczne metody są powolne obliczania pochodne cząstkowe funkcji w odniesieniu do wielu wejściowych, jaka jest potrzebna do gradientu opartych o optymalizacji algorytmów. Automatyczne różnicowanie rozwiązuje wszystkie te problemy.

Zasada łańcucha, akumulacja do przodu i do tyłu

Podstawą AD jest dekompozycja różniczek zapewniona przez regułę łańcucha . Za prostą kompozycję

daje regułę łańcucha

Zwykle prezentowane są dwa różne tryby AD, akumulacja do przodu (lub tryb do przodu ) i akumulacja odwrotna (lub tryb odwrotny ). Akumulacja w przód określa, że ​​użytkownik przechodzi przez regułę łańcucha od wewnątrz do zewnątrz (to znaczy najpierw oblicz, a następnie i na koniec ), podczas gdy akumulacja odwrotna ma przechodzenie z zewnątrz do wewnątrz (najpierw oblicz, a następnie i na koniec ). Bardziej zwięźle,

  1. akumulacja w przód oblicza relację rekurencyjną: z , i,
  2. akumulacja odwrotna oblicza relację rekurencyjną: with .

Akumulacja w przód

Rysunek 2: Przykład akumulacji w przód z wykresem obliczeniowym

W przedniej akumulacji ne jeden pierwsze ustala zmienną niezależną , względem którego wykonywana jest różnicowanie i oblicza się pochodną każdego sub ekspresji rekurencyjnie. W kalkulacji pióra i papieru polega to na wielokrotnym zastępowaniu pochodnej funkcji wewnętrznych w regule łańcucha:

Można to uogólnić na wiele zmiennych jako iloczyn macierzy jakobianów .

W porównaniu z akumulacją odwrotną, akumulacja w przód jest naturalna i łatwa do wdrożenia, ponieważ przepływ informacji pochodnych jest zbieżny z kolejnością oceny. Każda zmienna w jest powiększona o swoją pochodną (przechowywaną jako wartość liczbowa, a nie wyrażenie symboliczne),

jak oznaczono kropką. Pochodne są następnie obliczane zsynchronizowane z etapami oceny i łączone z innymi pochodnymi za pomocą reguły łańcucha.

Jako przykład rozważ funkcję:

Dla jasności, poszczególne podsektory wyrażenia zostały oznakowane zmiennych W I .

Wybór zmiennej niezależnej, względem której dokonywane jest różnicowanie, wpływa na wartości nasion 1 i 2 . Biorąc pod uwagę zainteresowanie pochodną tej funkcji względem x 1 , wartości seed powinny być ustawione na:

Po ustawieniu wartości początkowych wartości są propagowane przy użyciu reguły łańcucha, jak pokazano. Rysunek 2 przedstawia obrazowy obraz tego procesu w postaci wykresu obliczeniowego.

Operacje obliczania wartości Operacje obliczania pochodnej
(nasionko)
(nasionko)

Aby obliczyć gradient tej przykładowej funkcji, która wymaga pochodnych f w odniesieniu nie tylko do x 1 , ale także x 2 , wykonuje się dodatkowe przeciągnięcie nad wykresem obliczeniowym przy użyciu wartości początkowych .

Złożoność obliczeniowa z jednego cyklu do przodu akumulacji jest proporcjonalna do złożoności oryginalnego kodu.

Akumulacja w przód jest bardziej wydajna niż akumulacja odwrotna dla funkcji f  : R nR m z mn, ponieważ konieczne jest tylko n przemiatań, w porównaniu do m przemiatań dla akumulacji odwrotnej.

Odwrócona akumulacja

Rysunek 3: Przykład akumulacji odwrotnej z wykresem obliczeniowym

W odwrotnym akumulacji AD, zmienna zależna być zróżnicowane i uzyskania pochodnej jest obliczana w odniesieniu do każdego z sub ekspresji rekurencyjnie. W obliczeniach pióra i papieru pochodna funkcji zewnętrznych jest wielokrotnie zastępowana w regule łańcucha:

W akumulacji odwrotnej wielkością zainteresowania jest sprzężony , oznaczony kreską ( ); jest pochodną wybranej zmiennej zależnej względem podwyrażenia w :

Odwrócona akumulacja przechodzi przez regułę łańcucha od zewnątrz do wewnątrz lub w przypadku wykresu obliczeniowego na rysunku 3, od góry do dołu. Przykładowa funkcja ma wartość skalarną, a zatem istnieje tylko jedno źródło dla obliczenia pochodnej, a do obliczenia gradientu (dwuskładnikowego) potrzebne jest tylko jedno przeciągnięcie wykresu obliczeniowego. To tylko połowa pracy w porównaniu z akumulacją postępującą, ale akumulacja odwrotna wymaga przechowywania zmiennych pośrednich w i, a także instrukcji, które je utworzyły, w strukturze danych znanej jako lista Wengerta (lub „taśma”), która może zużywają znaczną ilość pamięci, jeśli wykres obliczeniowy jest duży. Można to do pewnego stopnia złagodzić, przechowując tylko podzbiór zmiennych pośrednich, a następnie rekonstruując niezbędne zmienne robocze, powtarzając oceny, technikę znaną jako rematerializacja . Punkty kontrolne służą również do zapisywania stanów pośrednich.

Operacje obliczania instrumentu pochodnego za pomocą akumulacji odwrotnej przedstawiono w poniższej tabeli (zwróć uwagę na kolejność odwrotną):

Operacje obliczania pochodnej

Wykres przepływu danych obliczenia można manipulować w celu obliczenia gradientu jego pierwotnego obliczenia. Odbywa się to poprzez dodanie przylegającego węzła dla każdego węzła głównego, połączonego przylegającymi krawędziami, które są równoległe do krawędzi głównych, ale płyną w przeciwnym kierunku. Węzły w grafie sprzężonym reprezentują mnożenie przez pochodne funkcji obliczonych przez węzły w liczbie pierwotnej. Na przykład dodawanie w pierwotnym powoduje fanout w przyległym; fanout w pierwotnym powoduje dodanie w przyległym; jednoskładnikowa, funkcja y = f  ( x ) w pierwotnych przyczyn X = ȳ f  '( x ) w adjoint; itp.

Akumulacja wsteczna jest bardziej wydajna niż akumulacja w przód dla funkcji f  : R nR m z mn, ponieważ konieczne jest tylko m przemiatań, w porównaniu z n przemiataniami dla akumulacji w przód.

Tryb odwrócony AD został po raz pierwszy opublikowany w 1976 roku przez Seppo Linnainmaa .

Propagacja wsteczna błędów w perceptronach wielowarstwowych, technika stosowana w uczeniu maszynowym , jest szczególnym przypadkiem AD w trybie odwrotnym.

Poza akumulacją do przodu i do tyłu

Akumulacja w przód i w tył to tylko dwa (skrajne) sposoby na pokonanie reguły łańcucha. Problem obliczania pełnego jakobianu f  : R nR m z minimalną liczbą operacji arytmetycznych jest znany jako problem optymalnej akumulacji jakobianu (OJA), który jest NP-zupełny . Centralnym elementem tego dowodu jest idea, że ​​między lokalnymi częściami cząstkowymi, które oznaczają krawędzie grafu, mogą istnieć zależności algebraiczne. W szczególności dwie lub więcej etykiet krawędzi może być rozpoznanych jako równe. Złożoność problemu pozostaje otwarta, jeśli założy się, że wszystkie etykiety krawędzi są niepowtarzalne i algebraicznie niezależne.

Automatyczne rozróżnianie przy użyciu liczb podwójnych

Tryb automatyczny przodu uzyskuje się przez zróżnicowanie zwiększając algebraiczne z liczb rzeczywistych , a uzyskanie nowego arytmetycznych . Do każdej liczby dodawany jest dodatkowy składnik reprezentujący pochodną funkcji pod liczbą, a wszystkie operatory arytmetyczne są rozszerzane dla algebry rozszerzonej. Algebra rozszerzona jest algebrą liczb podwójnych .

Zastąp każdą liczbę liczbą , gdzie jest liczbą rzeczywistą, ale jest liczbą abstrakcyjną o właściwości ( nieskończenie mała ; zobacz Smooth nieskończenie mała analiza ). Używając tylko tego, zwykła arytmetyka daje

podobnie do odejmowania i dzielenia.

Teraz wielomiany można obliczyć w tej rozszerzonej arytmetyce. Jeśli , to

gdzie oznacza pochodną w odniesieniu do swojego pierwszego argumentu, a , zwany ziarnem , może być wybrany arbitralnie.

Nowa arytmetyka składa się z par uporządkowanych , elementów zapisanych , z arytmetykami zwykłymi na pierwszej składowej i arytmetykami różnicowania pierwszego rzędu na drugiej składowej, jak opisano powyżej. Rozszerzenie powyższych wyników na wielomianach na

funkcje analityczne daje listę podstawowych funkcji arytmetycznych i niektórych standardowych funkcji dla nowej arytmetyki:
i ogólnie dla funkcji pierwotnej ,
gdzie i są pochodnymi względem odpowiednio pierwszego i drugiego argumentu.

Kiedy binarna podstawowa operacja arytmetyczna jest stosowana do mieszanych argumentów — pary i liczby rzeczywistej — liczba rzeczywista jest najpierw podnoszona do . Pochodna funkcji w punkcie jest teraz znaleziona przez obliczenie przy użyciu powyższej arytmetyki, która daje jako wynik.

Argumenty i funkcje wektorowe

Funkcje wielowymiarowe mogą być obsługiwane z taką samą wydajnością i mechanizmami jak funkcje jednowymiarowe poprzez przyjęcie kierunkowego operatora pochodnego. Oznacza to, że jeśli jest to wystarczające, aby obliczyć kierunkowa pochodną o w w kierunku , może być obliczane jako stosując tę samą arytmetyczną powyżej. Jeśli wszystkie elementy są pożądane, wymagane są oceny funkcji. Zauważ, że w wielu zastosowaniach optymalizacyjnych pochodna kierunkowa jest rzeczywiście wystarczająca.

Wysoki porządek i wiele zmiennych

Powyższą arytmetykę można uogólnić do obliczania pochodnych funkcji wielowymiarowych drugiego rzędu i wyższych. Jednak reguły arytmetyczne szybko się komplikują: złożoność jest kwadratowa w najwyższym stopniu różniczkowania. Zamiast tego można użyć obciętej algebry wielomianowej Taylora . Wynikowa arytmetyka, zdefiniowana na uogólnionych liczbach podwójnych, umożliwia wydajne obliczenia przy użyciu funkcji tak, jakby były typem danych. Gdy znany jest wielomian Taylora funkcji, pochodne są łatwo wyodrębniane.

Realizacja

AD w trybie postępowym jest implementowany przez niestandardową interpretację programu, w której liczby rzeczywiste są zastępowane liczbami podwójnymi, stałe są podnoszone do liczb podwójnych o zerowym współczynniku epsilon, a prymitywy numeryczne są podnoszone, aby operować na liczbach podwójnych. Ta niestandardowa interpretacja jest zazwyczaj implementowana przy użyciu jednej z dwóch strategii: transformacji kodu źródłowego lub przeciążania operatora .

Transformacja kodu źródłowego (SCT)

Rysunek 4: Przykład, jak może działać transformacja kodu źródłowego

Kod źródłowy funkcji zostaje zastąpiony automatycznie generowanym kodem źródłowym, który zawiera instrukcje obliczania instrumentów pochodnych przeplatane oryginalnymi instrukcjami.

Transformację kodu źródłowego można zaimplementować dla wszystkich języków programowania, a także kompilatorowi łatwiej jest przeprowadzać optymalizacje czasu kompilacji. Jednak wdrożenie samego narzędzia AD jest trudniejsze.

Przeciążenie operatora (OO)

Rysunek 5: Przykład działania przeciążania operatora

Przeciążanie operatorów to możliwość dla kodu źródłowego napisanego w języku je obsługującym. Obiekty dla liczb rzeczywistych i elementarnych operacji matematycznych muszą być przeciążone, aby zaspokoić przedstawioną powyżej arytmetykę rozszerzoną. Nie wymaga to zmiany formy ani sekwencji operacji w oryginalnym kodzie źródłowym w celu rozróżnienia funkcji, ale często wymaga zmian w podstawowych typach danych liczb i wektorów w celu obsługi przeciążania, a także często wiąże się z wstawianiem specjalnych operacji oznaczania.

Przeciążanie operatora przy akumulacji do przodu jest łatwe do wdrożenia, a także możliwe przy akumulacji wstecznej. Jednak obecne kompilatory pozostają w tyle w optymalizacji kodu w porównaniu z akumulacją do przodu.

Przeciążanie operatorów, zarówno w przypadku akumulacji w przód, jak i w tył, może być dobrze dostosowane do aplikacji, w których obiekty są wektorami liczb rzeczywistych, a nie skalarami. Dzieje się tak, ponieważ taśma zawiera wtedy operacje wektorowe; może to ułatwić obliczeniowo wydajne implementacje, w których każda operacja wektorowa wykonuje wiele operacji skalarnych. Techniki wektorowego sprzężonego różnicowania algorytmicznego (wektorowe AAD) mogą być stosowane, na przykład, do różnicowania wartości obliczonych przez symulację Monte-Carlo.

Przykładami przeciążających operatorów implementacji automatycznego różnicowania w C++ są biblioteki Adept i Stan .

Zobacz też

Uwagi

Bibliografia

Dalsza lektura

Linki zewnętrzne

implementacja automatycznego rozróżniania opartego na szablonach
  • Styczna źródło-źródło Debuggable pochodnych
  • [1] , Dokładni Grecy pierwszego i drugiego rzędu według zróżnicowania algorytmicznego
  • [2] , sprzężone algorytmiczne różnicowanie aplikacji akcelerowanych przez GPU
  • [3] , Adjoint Methods in Computational Finance Software Tool Support for Algorithmic Differentialop