2016-05-05 7 views
2

Ich habe ein Problem, dass ich die Designvariablen skalieren möchte. Ich habe den Scaler hinzugefügt, aber ich möchte das Derivat überprüfen, um sicherzustellen, dass es tut, was ich möchte. Gibt es eine Möglichkeit, das skalierte Derivat zu überprüfen? Ich habe versucht, check_total_derivatives() zu verwenden, aber das Derivat ist genau das gleiche, unabhängig davon, welchen Wert ich für Scaler setzen:Derivative Prüfung mit Scalern

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. 

Antwort

2

Eine andere Möglichkeit, genau zu sehen, was der Optimierer von calc_gradient sieht, ist, den Aufruf von calc_gradient nachzuahmen. Das ist nicht unbedingt leicht herauszufinden, aber ich dachte, ich würde es hier als Referenz einfügen.

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) 
3

Die Scaler und Addierern in ihrem Verhalten konsistent sind, so dass die Check-Derivate Routinen geben Ergebnisse in unscaled Begriffe, um intuitiver zu sein.

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

SNOPT_print.out:

Wenn Sie wirklich wollen, um zu sehen, welche Auswirkungen der Scaler mit, wenn der NLP den skalierten Wert sieht und Sie verwenden SNOPT, können Sie SNOPT des Derivats Prüfungs-Fähigkeiten hinzufügen enthalten, mit dem Scaler auf 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

Oder wenn wir es auf die x-Scaler bis 1000 ändern:

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 

Also in den Einheiten des Problems, das check_total_derivatives verwendet, ändert sich die Ableitung nicht. Der skalierte Wert, wie er vom Optimierer erkannt wird, ändert sich jedoch.