Pozwólcie mi ważyć się tutaj z kilkoma słowami ostrożności, poprzedzonymi historią. Dawno temu pracowałem z facetem, kiedy dopiero zaczynałem. Miał problem z optymalizacją do rozwiązania, z dość niechlujnym celem. Jego rozwiązaniem było wygenerowanie analitycznych pochodnych do optymalizacji.
Problem, który widziałem, był taki paskudny. Każdy z nich został wygenerowany za pomocą Macsyma i przekonwertowany na kod fortran. W rzeczywistości kompilator Fortran był tym zdenerwowany, ponieważ przekroczył maksymalną liczbę instrukcji kontynuacji. Chociaż znaleźliśmy flagę, która pozwoliła nam obejść ten problem, były też inne problemy.
W długich wyrażeniach, które są zwykle generowane przez systemy CA, istnieje ryzyko masywnego anulowania odejmowania. Oblicz wiele dużych liczb, ale okazuje się, że wszystkie się znoszą, dając niewielką liczbę.
Często analitycznie generowane pochodne są w rzeczywistości bardziej kosztowne do oszacowania niż pochodne generowane numerycznie z wykorzystaniem różnic skończonych. Gradient dla n zmiennych może zająć ponad n razy więcej niż koszt oceny funkcji celu. (Być może będziesz w stanie zaoszczędzić trochę czasu, ponieważ wiele terminów może być ponownie używanych w różnych pochodnych, ale to również zmusi cię do ostrożnego kodowania ręcznego, zamiast używania wyrażeń generowanych komputerowo. I za każdym razem, gdy kodujesz nieprzyjemne matematyczne wyrażeń, prawdopodobieństwo błędu nie jest trywialne. Upewnij się, że weryfikujesz pochodne pod względem dokładności).
Chodzi o to, że te wyrażenia generowane przez CA mają własne problemy. Zabawne jest to, że mój kolega był dumny ze złożoności problemu, że najwyraźniej rozwiązał naprawdę trudny problem, ponieważ algebra była tak paskudna. Nie sądzę, by zastanawiał się, czy ta algebra rzeczywiście oblicza prawidłową rzecz, czy robi to tak dokładnie i czy robi to tak skutecznie.
Gdybym był wówczas osobą starszą w tym projekcie, przeczytałbym mu akt zamieszek. Jego duma sprawiła, że zastosował rozwiązanie, które prawdopodobnie było niepotrzebnie złożone, nawet nie sprawdzając, czy gradient oparty na skończonej różnicy jest odpowiedni. Założę się, że spędziliśmy może tydzień pracy na optymalizację. Przynajmniej doradziłbym mu, aby dokładnie przetestował wytworzony gradient. Czy to było dokładne? Jaka była dokładność w porównaniu do pochodnych różnic skończonych? W rzeczywistości istnieją dziś narzędzia, które również zwrócą oszacowanie błędu w ich przewidywaniu pochodnych. Jest to z pewnością prawda w przypadku adaptacyjnego kodu różnicującego (wyprowadza się) , który napisałem w MATLAB.
Przetestuj kod. Sprawdź pochodne.
Ale zanim zrobisz KAŻDĄ z tych czynności, zastanów się, czy możliwe są inne, lepsze schematy optymalizacji. Na przykład, jeśli wykonujesz dopasowanie wykładnicze, istnieje bardzo duża szansa, że możesz użyć podzielonego nieliniowego najmniejszego kwadratu (czasami nazywanego separowalnym najmniejszym kwadratem. Myślę, że to był termin użyty przez Sebera i Wilda w ich książce.) Pomysł polega na rozbiciu zestawu parametrów na wewnętrznie liniowe i wewnętrznie nieliniowe zestawy. Użyj optymalizacji, która działa tylko na parametrach nieliniowych. Biorąc pod uwagę, że parametry te są „znane”, wówczas parametry wewnętrznie liniowe można oszacować za pomocą prostych liniowych najmniejszych kwadratów. Ten schemat zmniejszy przestrzeń parametrów w optymalizacji. Sprawia, że problem staje się bardziej niezawodny, ponieważ nie trzeba znaleźć wartości początkowych dla parametrów liniowych. Zmniejsza wymiary przestrzeni wyszukiwania, dzięki czemu problem działa szybciej. Znowu dostarczyłemnarzędzie do tego celu , ale tylko w MATLAB.
Jeśli korzystasz z analitycznych pochodnych, koduj je, aby ponownie wykorzystać warunki. Może to być poważną oszczędnością czasu i może faktycznie zmniejszyć liczbę błędów, oszczędzając Twój czas. Ale sprawdź te liczby!
codegen
pakietowi, ponieważ może on automatycznie generować kompaktowy i wydajny kod C lub Fortran dla każdego lub wszystkich wyrażeń automatycznie.