【问题标题】:Scaled paraboloid and derivatives checking缩放抛物面和导数检查
【发布时间】:2016-06-08 06:02:50
【问题描述】:

我很惊讶check_partial_derivatives() 方法的输出应用于我之前的问题中显示的问题:Paraboloid optimization requiring scaling。当我添加对该方法的调用时:

从 __future__ 导入 print_function 导入系统 从 openmdao.api 导入 IndepVarComp,组件,问题,组,ScipyOptimizer 类抛物面(组件): def __init__(self): 超级(抛物面,自我).__init__() self.add_param('x', val=0.0) self.add_param('y', val=0.0) self.add_output('f_xy', val=0.0) def solve_nonlinear(self, params, unknowns, resids): x = 参数['x'] y = 参数['y'] #unknowns['f_xy'] = (x-3.0)**2 + x*y + (y+4.0)**2 - 3.0 未知数['f_xy'] = (1000.*x-3.)**2 + (1000.*x)*(0.01*y) + (0.01*y+4.)**2 - 3。 def 线性化(自我,参数,未知数,残差): """ 抛物面的雅可比行列式。""" x = 参数['x'] y = 参数['y'] J = {} #J['f_xy', 'x'] = 2.0*x - 6.0 + y #J['f_xy', 'y'] = 2.0*y + 8.0 + x J['f_xy', 'x'] = 2000000.0*x - 6000.0 + 10.0*y J['f_xy', 'y'] = 0.0002*y + 0.08 + 10.0*x 返回 J 如果 __name__ == "__main__": 顶部 = 问题() root = top.root = Group() #root.fd_options['force_fd'] = True root.add('p1', IndepVarComp('x', 3.0)) root.add('p2', IndepVarComp('y', -4.0)) root.add('p', 抛物面()) root.connect('p1.x', 'p.x') root.connect('p2.y', 'p.y') top.driver = ScipyOptimizer() top.driver.options['optimizer'] = 'SLSQP' top.driver.add_desvar('p1.x', lower=-1000, upper=1000, scaler=1000.) top.driver.add_desvar('p2.y', lower=-1000, upper=1000, scaler=0.001) top.driver.add_objective('p.f_xy') top.setup() top.check_partial_derivatives() # 添加行 顶部运行() 打印('\n') print('在 (%f, %f) 处找到 %f 的最小值' % (top['p.f_xy'], top['p.x'], top['p.y']))

我得到以下输出:

偏导数检查 ---------------- 组件:'p' ---------------- p: 'f_xy' wrt 'x' 正向幅度:6.000000e+03 反向幅度:6.000000e+03 Fd 幅度:2.199400e+07 绝对误差 (Jfor - Jfd) : 2.200000e+07 绝对误差(Jrev - Jfd):2.200000e+07 绝对误差(Jfor - Jrev):0.000000e+00 相对误差 (Jfor - Jfd):1.000273e+00 相对误差 (Jrev - Jfd):1.000273e+00 相对误差(Jfor - Jrev):0.000000e+00 原始前向导数 (Jfor) [[-6000.]] 原始逆导数 (Jrev) [[-6000.]] 原始 FD 导数 (Jfor) [[ 21994001.]] - - - - - - - - - - - - - - - - - - - - - - - - - - - - p: 'f_xy' wrt 'y' 正向幅度:8.000000e-02 反向幅度:8.000000e-02 Fd 幅度:2.200000e+07 绝对误差 (Jfor - Jfd) : 2.200000e+07 绝对误差(Jrev - Jfd):2.200000e+07 绝对误差(Jfor - Jrev):0.000000e+00 相对误差(Jfor - Jfd):1.000000e+00 相对误差(Jrev - Jfd):1.000000e+00 相对误差(Jfor - Jrev):0.000000e+00 原始前向导数 (Jfor) [[ 0.08]] 原始逆导数 (Jrev) [[ 0.08]] 原始 FD 导数 (Jfor) [[ 22000000.08]] 优化成功终止。 (退出模式 0) 当前函数值:[-27.33333333] 迭代次数:4 功能评估:6 梯度评估:4 优化完成 ---------------------------------- -27.333333 的最小值位于 (0.006667, -733.333333)

优化是正确的(即几乎可以肯定地证明导数是正确的),但 check_partial_derivatives 输出在 fd 和正向/反向方法之间没有显示一致的结果。

【问题讨论】:

    标签: python openmdao


    【解决方案1】:

    相对

    因此,您遇到了以前出现的限制,即您无法计算关于设计点的导数,直到您在该点运行模型。有限差分结果是错误的,因为模型从未运行过。要验证您的部分,您需要将check_partial_derivatives 移动到运行后。此外,当我检查导数时,我总是注释掉优化器,以便检查初始点的导数。当我做了这两件事时,我得到了很好的结果(见下面的代码)。

    top = Problem()
    
    root = top.root = Group()
    #root.fd_options['force_fd'] = True
    
    root.add('p1', IndepVarComp('x', 3.0))
    root.add('p2', IndepVarComp('y', -4.0))
    root.add('p', Paraboloid())
    
    root.connect('p1.x', 'p.x')
    root.connect('p2.y', 'p.y')
    
    #top.driver = ScipyOptimizer()
    #top.driver.options['optimizer'] = 'SLSQP'
    
    #top.driver.add_desvar('p1.x', lower=-1000, upper=1000, scaler=1000.)
    #top.driver.add_desvar('p2.y', lower=-1000, upper=1000, scaler=0.001)
    #top.driver.add_objective('p.f_xy')
    
    top.setup()
    top.run()
    top.check_partial_derivatives()  # added line
    
    print('\n')
    print('Minimum of %f found at (%f, %f)' % (top['p.f_xy'], top['p.x'], top['p.y']))
    

    我们的 github 上有一个功能请求,要求能够在不先运行模型的情况下运行 check_partial_derivatives。我认为我们可以通过告诉 root 去solve_nonlinear 来做到这一点,忽略驱动程序是可行的,所以它可能会在某个时候添加。

    【讨论】:

    • 谢谢肯尼斯。同时,如果用户在没有运行模型的情况下使用该方法,是否可以添加警告?
    猜你喜欢
    • 2016-06-03
    • 1970-01-01
    • 2014-11-26
    • 2014-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-21
    • 1970-01-01
    相关资源
    最近更新 更多