Дозвольте мені зважити тут декілька слів обережності, напередодні історії. Давно я працював з товаришем, коли тільки починав. Він мав вирішити проблему оптимізації з досить безладним завданням. Його рішення полягало в створенні аналітичних похідних для оптимізації.
Проблема, яку я бачив, - ці похідні були неприємними. Згенеровані за допомогою Macsyma, перетвореного на код fortran, вони тривали десятки заяв про продовження. Насправді компілятор Fortran засмутився тим, що перевищив максимальну кількість операторів продовження. Хоча ми знайшли прапор, який дозволив нам подолати цю проблему, були й інші проблеми.
У довгих виразах, як це зазвичай породжується системами CA, існує ризик масового віднімання відміни. Обчисліть багато великих чисел, лише щоб знайти, що всі вони скасовують один одного, щоб отримати невелике число.
Часто аналітичні похідні похідні фактично дорожче оцінювати, ніж чисельно генеровані похідні з використанням кінцевих різниць. Градієнт для n змінних може зайняти більш ніж n разів більше витрат на оцінку вашої цільової функції. (Можливо, ви зможете зекономити деякий час, оскільки багато термінів можна повторно використовувати в різних похідних, але це також змусить вас робити ретельне кодування вручну, а не використовувати вирази, створені комп'ютером. І будь-який час ви кодуєте неприємні математичні вирази, ймовірність помилки не є тривіальною. Переконайтесь, що ви перевіряєте ці похідні на точність.)
Сенс моєї історії полягає в тому, що ці вирази, створені ЦА, мають власні проблеми. Найсмішніше, що мій колега справді пишався складністю проблеми, що він чітко вирішував справді складну проблему, оскільки алгебра була такою неприємною. Я не думаю, що він вважав, що якщо ця алгебра насправді обчислює правильну річ, чи робила це так точно і чи робила це так ефективно.
Якби я на той час був старшим за цим проектом, я б прочитав йому акт про бунт. Його гордість змусила його використовувати рішення, яке, ймовірно, було зайвим, навіть не перевіряючи, чи гранієнт на основі обмежених різниць є адекватним. Б'юсь об заклад, що ми витратили, можливо, тиждень людини, щоб запустити цю оптимізацію. Як мінімум, я б порадив йому ретельно перевірити отриманий градієнт. Це було точно? Наскільки точним це було порівняно з похідними з кінцевою різницею? Насправді сьогодні існують інструменти, які також повернуть оцінку помилки в їх похідному прогнозуванні. Це, безумовно, справедливо для коду адаптивного диференціювання (витікаючого), який я написав у MATLAB.
Перевірте код. Перевірте похідні.
Але перш ніж робити це з будь-якого, подумайте, чи є інші, кращі схеми оптимізації варіант. Наприклад, якщо ви робите експоненціальну підгонку, то є дуже хороший шанс, що ви можете використовувати нелінійні розділені найменші квадрати (іноді їх називають відокремленими найменшими квадратами. Я думаю, що це був термін, який в своїй книзі використовували Seber і Wild.) полягає в тому, щоб розбити набір параметрів на внутрішньолінійні та суто нелінійні множини. Використовуйте оптимізацію, яка працює лише на нелінійних параметрах. З огляду на те, що ці параметри є "відомими", то внутрішньолінійні параметри можна оцінити, використовуючи прості лінійні найменші квадрати. Ця схема зменшить простір параметрів при оптимізації. Це робить проблему більш надійною, оскільки не потрібно знаходити початкові значення для лінійних параметрів. Це зменшує розмірність вашого пошукового простору, тому змушує проблему працювати швидше. Знову я поставивінструмент для цієї мети , але тільки в MATLAB.
Якщо ви використовуєте аналітичні похідні, кодуйте їх для повторного використання термінів. Це може бути серйозною економією часу, а може фактично зменшити помилки, заощаджуючи власний час. Але тоді перевірте ці цифри!
codegen
пакет в ньому, оскільки він може генерувати компактний та ефективний код C або Fortran для кожного або всіх виразів автоматично.