2

我有一个问题,我想缩放设计变量。我已经添加了缩放器,但我想检查导数以确保它正在做我想要它做的事情。有没有办法检查比例导数?我曾尝试使用 check_total_derivatives() 但无论我为缩放器设置什么值,导数都是完全相同的:

from openmdao.api import Component, Group, Problem, IndepVarComp, ExecComp
from openmdao.drivers.pyoptsparse_driver import pyOptSparseDriver

class Scaling(Component):
    def __init__(self):
        super(Scaling, self).__init__()
        self.add_param('x', shape=1)
        self.add_output('y', shape=1)

    def solve_nonlinear(self, params, unknowns, resids):
        unknowns['y'] = 1000. * params['x']**2 + 2

    def linearize(self, params, unknowns, resids):
        J = {}
        J['y', 'x'] = 2000. * params['x']
        return J


class ScalingGroup(Group):
    def __init__(self,):
        super(ScalingGroup, self).__init__()
        self.add('x', IndepVarComp('x', 0.0), promotes=['*'])
        self.add('g', Scaling(), promotes=['*'])

p = Problem()
p.root = ScalingGroup()

# p.driver = pyOptSparseDriver()
# p.driver.options['optimizer'] = 'SNOPT'
p.driver.add_desvar('x', lower=0.005, upper=100., scaler=1000)
p.driver.add_objective('y')
p.setup()
p['x'] = 3.

p.run()
total = p.check_total_derivatives()
# Derivative is the same regardless of what the scaler is.
4

2 回答 2

3

定标器和加法器的行为是一致的,因此检查导数例程以未定标的形式给出结果更直观。

如果您真的想看看当 NLP 看到缩放值并且您正在使用 SNOPT 时缩放器有什么影响,您可以添加 SNOPT 的导数检查功能:

p.driver.opt_settings['Verify level'] = 3

SNOPT_print.out 将包含,缩放器设置为 1: Column x(j) dx(j) Element no. Row Derivative Difference approxn 1 3.00000000E+00 2.19E-06 Objective 6.00000000E+03 6.00000219E+03 ok

或者,如果我们将 x 缩放器更改为 1000:

Column       x(j)        dx(j)    Element no.    Row        Derivative    Difference approxn
      1  3.00000000E+03  1.64E-03           Objective    6.00000000E+00    6.00000164E+00  ok

因此,在 check_total_derivatives 使用的问题单位中,导数不会改变。但是优化器看到的缩放值正在发生变化。

于 2016-05-06T02:37:11.343 回答
2

另一种准确查看优化器从 calc_gradient 看到的内容的方法是模拟对 calc_gradient 的调用。这不一定很容易弄清楚,但我想我会把它贴在这里以供参考。

print p.calc_gradient(list(p.driver.get_desvars().keys()),
                      list(p.driver.get_objectives().keys()) + list(p.driver.get_constraints().keys()),
                      dv_scale=p.driver.dv_conversions,
                      cn_scale=p.driver.fn_conversions)
于 2016-05-06T13:52:23.440 回答