В Документ OpenMDAO есть описания 3 методов (полные, полу и смешанные аналитические градиенты).
Я хотел кое-что уточнить. Утверждается, что полуаналитический метод более эффективен, чем аппроксимация градиентов целых моделей.
Возьмем задачу с одной группой с 10 «только явными компонентами» и без зависимостей или циклических соединений, как в Селлар проблема. (Думаю, здесь явный или неявный не имеет значения, так как система в конечном итоге увидит компоненты как неявные, но в любом случае)
Насколько я понимаю из статьи, аппроксимация каждого компонента с помощью FD все же более точна, чем аппроксимация всей проблемы с помощью FD, как в model.approx()
.
Предполагая, что я правильно понимаю, я запутался в продвижении такого использования из-за недостатков, которые я вижу;
Каждый компонент требует нескольких вызовов для аппроксимации градиента. Это определенно более затратно в вычислительном отношении, чем аппроксимация всей проблемы, которая будет вызвана только столько переменных проекта (+1) для односторонней аппроксимации FD.
Каждый компонент требует настройки шагов FD и, возможно, нормализации ввода/вывода, поэтому это потребует дополнительной работы. Это правильно?
Если у вас есть модель только с экземплярами ExplicitComponent, ситуация становится немного более тонкой, и для нее становится гораздо труднее предоставить эмпирическое правило.
TL;DR: Реальность такова, что при использовании численных приближений для производных «лучшее» решение сильно зависит от модели. Вообще говоря, если есть какие-либо неявные компоненты с настоящими нелинейными решениями, вам лучше использовать полуаналитический метод. Если у вас есть модель с прямой подачей, состоящая только из явных компонентов (хотя и без обмана, инженерные коды в оболочке часто действительно неявны) без решателей OpenMDAO, используемых для конвергенции многодисциплинарной связи, то вы мощь получаете быстрее с монолитным FD (хотя полуаналитический подход здесь все равно будет более точным)
Вычислительные компромиссы гораздо более очевидны, когда в вашей модели есть экземпляры ImplicitComponent. Итак, давайте сначала рассмотрим это. Для простоты рассмотрим модель только с одним экземпляром ImplicitComponent, который предоставляет собственный внутренний методsolve_nonlinear. Здесь у вас есть два варианта:
1) традиционный метод FD, который вычислял d_outputs/d_inputs, выполняя шаги по методу solve_nonlinear
. Это потребует полной повторной сходимости модели для каждого приближения FD (один раз для каждого входа).
2) полуаналитический FD, который вычисляет partial_outputs/partial_inputs, выполняя шаги по методу apply_nonlinear
, а затем полагаясь на возможности аналитических производных OpenMDAO для вычисления итогов для вас.
Для варианта 1 существует несколько проблем, таких как шум сходимости решателя (зависит от допуска решателя), вычитание и вычислительные затраты на повторную сходимость для каждого шага. Если у вас было очень дорогое нелинейное решение (т. е. вызов solve_nonlinear
был дорогостоящим), то этот подход может стать очень дорогим, особенно если у вас много входных данных. Кроме того, вы должны быть в состоянии гарантировать, что решатель будет сходиться для каждого вашего шага, иначе вы не получите никаких производных. На практике эта гарантия является жесткой, поэтому также возникают проблемы с числовой стабильностью.
Для варианта 2, даже если вам нужно иметь дело с НАМНОГО больше неявных переменных, вы вызываете только apply_nonlinear
, что обычно на несколько порядков быстрее, чем полное нелинейное решение. Он также не будет страдать от многих числовых проблем. Гораздо проще обеспечить правильную остаточную оценку, чем полностью сошедшееся нелинейное решение, так что проблема стабильности практически устранена. Кроме того, вам не нужно беспокоиться о шуме, вызванном слабыми допусками решателя. Если вы используете FD, вы все равно будете страдать от вычитания крошечных шагов, но это единственная реальная слабость (и ее можно устранить с помощью CS).
Это правда, что для варианта 2 у вас может быть гораздо больше шагов FD, поскольку теперь вы берете частные производные по многим дополнительным переменным. Однако, поскольку apply_nonlinear
в итоге намного дешевле, это работает в вашу пользу.
Теперь вернемся к вашему первоначальному вопросу о больших моделях всех явных компонентов. Здесь у вас есть более сложный набор компромиссов. Во-первых, давайте предположим, что все ваши явные компоненты являются простыми аналитическими функциями (т. е. ни один из них на самом деле не вызывает какой-либо нелинейный решатель или внешний инженерный код).
Здесь вы не страдаете от проблемы численного шума из-за устойчивости решателя. и если у вас мало проектных переменных, вполне вероятно, что при выполнении FD в верхней части вашей модели. будет получено наименьшее количество вызовов функций. общая стоимость вычислений.
Но монолитный FD также затрудняет выбор правильного размера шага, потому что разные компоненты будут выполнять разные вычисления и в идеале иметь разные оптимальные размеры шага. Поскольку вы можете выбрать шаг только в самой переменной проекта, вы застряли с тем, что распространяется через вашу модель. Таким образом, вы можете получить менее точные общие (или полусуммарные, если вы делаете это в середине модели) производные, которые требуют от вас большего количества итераций оптимизации.
Теперь, если мы немного ослабим наши предположения о природе явных компонентов и скажем, что действительно есть инженерный код со своим собственным внутренним решателем, обернутым где-то в модели... то, что у вас действительно есть, это неявный компонент, которого вы не знали. Не говорите OpenMDAO об этом. Итак, опять же, здесь было бы лучше обернуть его как неявный компонент (выставляя напоказ остаточный расчет). В этом случае вы не можете монолитно FD модели, все еще пользуясь преимуществами полуаналитического метода. Так что здесь вы, как правило, предпочитаете FD для каждого компонента отдельно. В статье 2014 года под названием «Автоматическая оценка мультидисциплинарных производных с использованием формулировки задачи на основе графа в OpenMDAO» мы показали именно это. Даже если вы используете FD для самого дорогого анализа (решатель FEA) с множеством входных данных, полуаналитический метод все равно намного быстрее по сравнению с монолитным FD.
Еще одно преимущество полуаналитического метода, которого я еще не коснулся, заключается в том, что он позволяет вам смешивание FD, CS и аналитические производные. Вы можете начать с полного fd, перейти к CS для некоторых из ваших более нелинейных вычислений, а затем, когда ваше развитие замедлится, начать добавлять аналитические производные. Каждый раз, когда вы обновляете свои производные, вы будете видеть увеличение производительности.
Таким образом, даже если полуаналитический метод поначалу работает медленнее, он дает вам путь к обновлению, который никогда не может обеспечить монолитный подход FD.
спасибо за подробный ответ, читаю. некоторые уточнения: 1) вы говорите ; Это может дать вам самую низкую стоимость FD, но может привести к самой низкой стоимости оптимизации. разве это не должно быть «Это может дать вам самую низкую стоимость FD, но может привести к самой высокой стоимости оптимизации».