Как использовать внешний компонент кода в рамках оптимизации
Привет, я пытаюсь использовать компонент внешнего кода параболоида, чтобы получить те же результаты, что и в задаче оптимизации параболоида (openmdao v 2.2.0).
Поэтому, на мой взгляд, независимые переменные x,y должны быть обновлены и, таким образом, изменены входной файл внешнего компонента, чтобы минимизировать вывод f.
Не то чтобы у меня это работало, но я в основном добавляю выходные данные внешнего компонента в качестве цели и независимые переменные в качестве переменных проекта и т. Д. (См. Код ниже). Но что более важно, у меня есть проблема, чтобы концептуально понять, как оптимизатор узнает производные в таких внешних кодах. Я попробовал "COBYLA", думая, что это может быть подходом без градиента, но, похоже, в заявлении iprint есть ошибка, так как я не могу запустить примерную оптимизацию параболоида.
Я думаю, что у меня похожая проблема с суррогатами. Например, я использую метамодельноструктурированный компонент, чтобы найти мой суррогат, который хорошо работает, если я запрашиваю известное значение. Но я не вижу, как связать вывод этого компонента с целью оптимизатора. Я думаю, что делаю правильные вещи, задавая цель модели. но не уверен...
Ответ может быть таким, что я совершенно не согласен с логикой оптимизации, если это так, пожалуйста, отошлите меня к соответствующим статьям для алгоритмов.
заранее спасибо
from openmdao.api import Problem, Group, IndepVarComp
from openmdao.api import ScipyOptimizeDriver
from openmdao.components.tests.test_external_code import ParaboloidExternalCode
top = Problem()
top.model = model = Group()
# create and connect inputs
model.add_subsystem('p1', IndepVarComp('x', 3.0))
model.add_subsystem('p2', IndepVarComp('y', -4.0))
model.add_subsystem('p', ParaboloidExternalCode())
model.connect('p1.x', 'p.x')
model.connect('p2.y', 'p.y')
top.driver = ScipyOptimizeDriver()
top.driver.options['optimizer'] = 'SLSQP'
top.model.add_design_var('p1.x', lower=-50, upper=50)
top.model.add_design_var('p2.y', lower=-50, upper=50)
top.model.add_objective('p.f_xy')
top.driver.options['tol'] = 1e-9
top.driver.options['disp'] = True
top.setup()
top.run_driver()
# minimum value
# location of the minimum
print(top['p1.x'])
print(top['p2.y'])
1 ответ
Итак, я думаю, что главное, что вы спрашиваете, - как предоставить производные для внешних кодов. Я думаю, что для этого есть два варианта.
- Конечная разница по всему внешнему компоненту.
В тестовом примере не показано, как это сделать, что очень печально, но вы делаете это так же, как объявляете производные fd для чистого компонента python, а именно добавляя эту строку в метод установки внешнего компонента:
self.declare_partials(of='*', wrt='*', method='fd')
- Предоставьте другой внешний метод для вычисления производных и поместите его в метод "compute_partials".
Мы делаем это с кодами CFD, которые предоставляют сопряженное решение. Возможно, вы также можете использовать автоматическое дифференцирование во внешнем исходном коде для создания вызываемой функции таким образом. Тем не менее, я думаю, что метод 1 - это то, что вы просите здесь.