Проверка, поддерживает ли оптимизатор градиент - PullRequest
2 голосов
/ 13 октября 2019

Хочу различать оптимизаторы (градиенты на основе и бесплатные). Если я использую пример оптимизации на главной веб-странице OpenMDAO , которая использует SLSQP, и проверяю, поддерживает ли оптимизатор градиенты, я получаю "False", как в;

prob.driver.supports['gradients']

, это OpenMDAO или Scipyсвязанная проблема?

Есть ли другой способ проверить, будет ли оптимизатор использовать вычисления градиента или нет до запуска задачи.


Основываясь на ответе ниже, я добавил это в начале своегосценарий;Спасибо!

    prob = om.api.Problem()
    prob.driver = user_driver_object
    prob.setup()
    prob.final_setup()
    grads.append(prob.driver.supports['gradients'])

1 Ответ

3 голосов
/ 13 октября 2019

В ScipyOptimizeDriver не все оптимизаторы поддерживают оптимизацию градиента, поэтому вы не можете определить правильное значение, пока не настроите свой драйвер. Это сделано в final_setup() вашей проблемы (которая вызывает _setup_driver() в вашем драйвере). Этот метод вызывается в run_model() и run_driver(), но вы также можете вызывать его сам по себе, чтобы получить правильные свойства вашего оптимизатора.

В приведенном ниже примере я спрашиваю драйвер 3 раза, поддерживает ли он градиенты. В первый раз, после установки problem , он дает ложный ответ (по умолчанию), потому что драйвер еще не был затронут. Если я позвоню final_setup(), это настроит драйвер, и все свойства драйвера будут правильными. Если вызывается run_model() или run_driver(), конечно, это также настроит драйвер.

Поэтому я советую просто использовать final_setup(), прежде чем запрашивать у вашего драйвера что-либо, что может измениться во время установки (в основном это свойства, специфичные для оптимизатора).

import openmdao.api as om

# build the model
prob = om.Problem()
indeps = prob.model.add_subsystem('indeps', om.IndepVarComp())
indeps.add_output('x', 3.0)
indeps.add_output('y', -4.0)

prob.model.add_subsystem('paraboloid', om.ExecComp('f = (x-3)**2 + x*y + (y+4)**2 - 3'))

prob.model.connect('indeps.x', 'paraboloid.x')
prob.model.connect('indeps.y', 'paraboloid.y')

# setup the optimization
driver = prob.driver = om.ScipyOptimizeDriver()
prob.driver.options['optimizer'] = 'SLSQP'

prob.model.add_design_var('indeps.x', lower=-50, upper=50)
prob.model.add_design_var('indeps.y', lower=-50, upper=50)
prob.model.add_objective('paraboloid.f')

prob.setup()
print("\nSupports gradients (after setup)?")
print(prob.driver.supports['gradients'])

prob.final_setup()
print("\nSupports gradients (after final setup)?")
print(prob.driver.supports['gradients'])

prob.run_driver()
print("\nSupports gradients (after run)?")
print(prob.driver.supports['gradients'])

Это приводит к следующему выводу:

Supports gradients (after setup)?
False
Supports gradients (after final setup)?
True
Optimization terminated successfully.    (Exit mode 0)
            Current function value: -27.33333333333333
            Iterations: 5
            Function evaluations: 6
            Gradient evaluations: 5
Optimization Complete
-----------------------------------
Supports gradients (after run)?
True
...