"scaler" 是否乘以两次?
Does "scaler" multiply twice?
我一直在使用 openmdao 中的缩放选项时遇到一些问题。有时缩放在矩阵求解器中隐式工作,而有时则显式等。我现在遇到的问题是约束的缩放并记录它。我用过 Cantilever beam example
我添加了定标器=2
self.add_constraint('volume_comp.volume', equals=volume,scaler=2)
我没有更改 volume = 0.01 约束值。如果我设置 scaler=1,则约束体积的记录输出在优化结束时等于 0.01。但是,如果我设置 scaler=2 volume 变量是 0.04。对于 scaler=10,音量输出等于 1 等。是否有额外的乘法。
优化值无论如何都不会改变,我认为这是预期的,因为这种缩放只是为了规范化(据我所知)。
下面是改了一行的示例代码和记录器,我用的是OpenMDAO 2.5.0
from __future__ import division
import numpy as np
from openmdao.api import Group, IndepVarComp
from openmdao.test_suite.test_examples.beam_optimization.components.moment_comp import MomentOfInertiaComp
from openmdao.test_suite.test_examples.beam_optimization.components.local_stiffness_matrix_comp import LocalStiffnessMatrixComp
from openmdao.test_suite.test_examples.beam_optimization.components.states_comp import StatesComp
from openmdao.test_suite.test_examples.beam_optimization.components.displacements_comp import DisplacementsComp
from openmdao.test_suite.test_examples.beam_optimization.components.compliance_comp import ComplianceComp
from openmdao.test_suite.test_examples.beam_optimization.components.volume_comp import VolumeComp
class BeamGroup(Group):
def initialize(self):
self.options.declare('E')
self.options.declare('L')
self.options.declare('b')
self.options.declare('volume')
self.options.declare('num_elements', int)
def setup(self):
E = self.options['E']
L = self.options['L']
b = self.options['b']
volume = self.options['volume']
num_elements = self.options['num_elements']
num_nodes = num_elements + 1
force_vector = np.zeros(2 * num_nodes)
force_vector[-2] = -1.
inputs_comp = IndepVarComp()
inputs_comp.add_output('h', shape=num_elements)
self.add_subsystem('inputs_comp', inputs_comp)
I_comp = MomentOfInertiaComp(num_elements=num_elements, b=b)
self.add_subsystem('I_comp', I_comp)
comp = LocalStiffnessMatrixComp(num_elements=num_elements, E=E, L=L)
self.add_subsystem('local_stiffness_matrix_comp', comp)
comp = StatesComp(num_elements=num_elements, force_vector=force_vector)
self.add_subsystem('states_comp', comp)
comp = DisplacementsComp(num_elements=num_elements)
self.add_subsystem('displacements_comp', comp)
comp = ComplianceComp(num_elements=num_elements, force_vector=force_vector)
self.add_subsystem('compliance_comp', comp)
comp = VolumeComp(num_elements=num_elements, b=b, L=L)
self.add_subsystem('volume_comp', comp)
self.connect('inputs_comp.h', 'I_comp.h')
self.connect('I_comp.I', 'local_stiffness_matrix_comp.I')
self.connect(
'local_stiffness_matrix_comp.K_local',
'states_comp.K_local')
self.connect(
'states_comp.d',
'displacements_comp.d')
self.connect(
'displacements_comp.displacements',
'compliance_comp.displacements')
self.connect(
'inputs_comp.h',
'volume_comp.h')
self.add_design_var('inputs_comp.h', lower=1e-2, upper=10.)
self.add_objective('compliance_comp.compliance')
self.add_constraint('volume_comp.volume', equals=volume,scaler=10)
import numpy as np
from openmdao.api import Problem, ScipyOptimizeDriver,SqliteRecorder
E = 1.
L = 1.
b = 0.1
volume = 0.01
num_elements = 50
prob = Problem(model=BeamGroup(E=E, L=L, b=b, volume=volume, num_elements=num_elements))
prob.driver = ScipyOptimizeDriver()
prob.driver.options['optimizer'] = 'SLSQP'
prob.driver.options['tol'] = 1e-9
prob.driver.options['disp'] = True
recorder = SqliteRecorder('abc.sql')
prob.driver.add_recorder(recorder)
prob.driver.recording_options['includes'] = []
prob.driver.recording_options['record_inputs'] = True
# prob.driver.recording_options['record_outputs'] = True
prob.driver.recording_options['record_objectives'] = True
prob.driver.recording_options['record_constraints'] = True
prob.driver.recording_options['record_desvars'] = True
prob.driver.recording_options['record_derivatives'] = True
prob.setup()
prob.run_driver()
print(prob['inputs_comp.h'])
prob.cleanup()
#%%
import re
from openmdao.api import CaseReader
import matplotlib.pyplot as plt
import numpy as np
import os,json as js
import matplotlib
cr = CaseReader('abc.sql')
case_keys = cr.list_cases()
obj=[]
for i, case_key in enumerate(case_keys):
case = cr.get_case(case_key)
derivs = cr.get_case(i).jacobian
# for k in derivs:
# print(k,derivs[k])
recorded_objectives = case.get_objectives()
recorder_constraints = case.get_constraints()
recorder_desvars = case.get_design_vars()
recorder_responses = case.get_responses()
for k in recorder_desvars:
print(k,recorder_desvars[k])
for k in recorder_constraints:
print(k,recorder_constraints[k])
for k in recorded_objectives:
print(k,recorded_objectives[k])
obj.append(recorded_objectives[k])
print('-----------')
#
#print(obj)
#obj[2]=obj[1]
#print(len(obj))
plt.plot(obj,'*')
记录器中的变量确实被缩放了两次。在驱动程序中,值已正确缩放。您可以将最后一个案例与下面的代码进行比较。 _apply_voi_meta()
在 Case
class.
中完成缩放
#%%
cr = CaseReader('abc.sql')
case_keys = cr.list_cases()
obj=[]
for i, case_key in enumerate(case_keys):
case = cr.get_case(case_key)
derivs = cr.get_case(i).jacobian
# for k in derivs:
# print(k,derivs[k])
recorded_objectives = case.get_objectives()
recorder_constraints = case.get_constraints()
recorder_desvars = case.get_design_vars()
recorder_responses = case.get_responses()
for k in recorder_desvars:
print(k,recorder_desvars[k])
for k in recorder_constraints:
print(k,recorder_constraints[k])
for k in recorded_objectives:
print(k,recorded_objectives[k])
obj.append(recorded_objectives[k])
print('-----------')
print('\nDRIVER:\n\n')
for k, v in iteritems(driver.get_design_var_values()):
print(k, v)
for k, v in iteritems(driver.get_constraint_values()):
print(k, v)
for k, v in iteritems(driver.get_objective_values()):
print(k, v)
现在很清楚了,问题的根源是录音机。在你的情况下,你调用 both get_constraints()
和 get_responses()
方法。在这些方法中,可变变量被缩放。因此,当您 return 值时, _apply_voi_meta()
中的变量 vals
也会缩放。当您多次调用任何函数,即缩放相同的变量时,作为副作用,变量将在每次函数调用时缩放。
参见下面的示例:
#%%
cr = CaseReader('abc.sql')
case_keys = cr.list_cases()
obj=[]
scaled = True
for i, case_key in enumerate(case_keys):
case = cr.get_case(case_key)
derivs = cr.get_case(i).jacobian
# for k in derivs:
# print(k,derivs[k])
recorded_objectives = case.get_objectives(scaled=scaled)
recorder_constraints = case.get_constraints(scaled=scaled)
recorder_desvars = case.get_design_vars()
# recorder_responses = case.get_responses(scaled=scaled)
case.get_constraints(scaled=scaled)
case.get_constraints(scaled=scaled)
for k in recorder_desvars:
print(k,recorder_desvars[k])
for k in recorder_constraints:
print(k,recorder_constraints[k])
for k in recorded_objectives:
print(k,recorded_objectives[k])
obj.append(recorded_objectives[k])
print('-----------')
print('\nDRIVER:\n\n')
for k, v in iteritems(driver.get_design_var_values()):
print(k, v)
for k, v in iteritems(driver.get_constraint_values()):
print(k, v)
for k, v in iteritems(driver.get_objective_values()):
print(k, v)
如果缩放器为 10,约束将是未缩放值的 1000(或 10^3)倍,因为现在我调用了 get_constraints()
方法 3 次。
我一直在使用 openmdao 中的缩放选项时遇到一些问题。有时缩放在矩阵求解器中隐式工作,而有时则显式等。我现在遇到的问题是约束的缩放并记录它。我用过 Cantilever beam example
我添加了定标器=2
self.add_constraint('volume_comp.volume', equals=volume,scaler=2)
我没有更改 volume = 0.01 约束值。如果我设置 scaler=1,则约束体积的记录输出在优化结束时等于 0.01。但是,如果我设置 scaler=2 volume 变量是 0.04。对于 scaler=10,音量输出等于 1 等。是否有额外的乘法。
优化值无论如何都不会改变,我认为这是预期的,因为这种缩放只是为了规范化(据我所知)。
下面是改了一行的示例代码和记录器,我用的是OpenMDAO 2.5.0
from __future__ import division
import numpy as np
from openmdao.api import Group, IndepVarComp
from openmdao.test_suite.test_examples.beam_optimization.components.moment_comp import MomentOfInertiaComp
from openmdao.test_suite.test_examples.beam_optimization.components.local_stiffness_matrix_comp import LocalStiffnessMatrixComp
from openmdao.test_suite.test_examples.beam_optimization.components.states_comp import StatesComp
from openmdao.test_suite.test_examples.beam_optimization.components.displacements_comp import DisplacementsComp
from openmdao.test_suite.test_examples.beam_optimization.components.compliance_comp import ComplianceComp
from openmdao.test_suite.test_examples.beam_optimization.components.volume_comp import VolumeComp
class BeamGroup(Group):
def initialize(self):
self.options.declare('E')
self.options.declare('L')
self.options.declare('b')
self.options.declare('volume')
self.options.declare('num_elements', int)
def setup(self):
E = self.options['E']
L = self.options['L']
b = self.options['b']
volume = self.options['volume']
num_elements = self.options['num_elements']
num_nodes = num_elements + 1
force_vector = np.zeros(2 * num_nodes)
force_vector[-2] = -1.
inputs_comp = IndepVarComp()
inputs_comp.add_output('h', shape=num_elements)
self.add_subsystem('inputs_comp', inputs_comp)
I_comp = MomentOfInertiaComp(num_elements=num_elements, b=b)
self.add_subsystem('I_comp', I_comp)
comp = LocalStiffnessMatrixComp(num_elements=num_elements, E=E, L=L)
self.add_subsystem('local_stiffness_matrix_comp', comp)
comp = StatesComp(num_elements=num_elements, force_vector=force_vector)
self.add_subsystem('states_comp', comp)
comp = DisplacementsComp(num_elements=num_elements)
self.add_subsystem('displacements_comp', comp)
comp = ComplianceComp(num_elements=num_elements, force_vector=force_vector)
self.add_subsystem('compliance_comp', comp)
comp = VolumeComp(num_elements=num_elements, b=b, L=L)
self.add_subsystem('volume_comp', comp)
self.connect('inputs_comp.h', 'I_comp.h')
self.connect('I_comp.I', 'local_stiffness_matrix_comp.I')
self.connect(
'local_stiffness_matrix_comp.K_local',
'states_comp.K_local')
self.connect(
'states_comp.d',
'displacements_comp.d')
self.connect(
'displacements_comp.displacements',
'compliance_comp.displacements')
self.connect(
'inputs_comp.h',
'volume_comp.h')
self.add_design_var('inputs_comp.h', lower=1e-2, upper=10.)
self.add_objective('compliance_comp.compliance')
self.add_constraint('volume_comp.volume', equals=volume,scaler=10)
import numpy as np
from openmdao.api import Problem, ScipyOptimizeDriver,SqliteRecorder
E = 1.
L = 1.
b = 0.1
volume = 0.01
num_elements = 50
prob = Problem(model=BeamGroup(E=E, L=L, b=b, volume=volume, num_elements=num_elements))
prob.driver = ScipyOptimizeDriver()
prob.driver.options['optimizer'] = 'SLSQP'
prob.driver.options['tol'] = 1e-9
prob.driver.options['disp'] = True
recorder = SqliteRecorder('abc.sql')
prob.driver.add_recorder(recorder)
prob.driver.recording_options['includes'] = []
prob.driver.recording_options['record_inputs'] = True
# prob.driver.recording_options['record_outputs'] = True
prob.driver.recording_options['record_objectives'] = True
prob.driver.recording_options['record_constraints'] = True
prob.driver.recording_options['record_desvars'] = True
prob.driver.recording_options['record_derivatives'] = True
prob.setup()
prob.run_driver()
print(prob['inputs_comp.h'])
prob.cleanup()
#%%
import re
from openmdao.api import CaseReader
import matplotlib.pyplot as plt
import numpy as np
import os,json as js
import matplotlib
cr = CaseReader('abc.sql')
case_keys = cr.list_cases()
obj=[]
for i, case_key in enumerate(case_keys):
case = cr.get_case(case_key)
derivs = cr.get_case(i).jacobian
# for k in derivs:
# print(k,derivs[k])
recorded_objectives = case.get_objectives()
recorder_constraints = case.get_constraints()
recorder_desvars = case.get_design_vars()
recorder_responses = case.get_responses()
for k in recorder_desvars:
print(k,recorder_desvars[k])
for k in recorder_constraints:
print(k,recorder_constraints[k])
for k in recorded_objectives:
print(k,recorded_objectives[k])
obj.append(recorded_objectives[k])
print('-----------')
#
#print(obj)
#obj[2]=obj[1]
#print(len(obj))
plt.plot(obj,'*')
记录器中的变量确实被缩放了两次。在驱动程序中,值已正确缩放。您可以将最后一个案例与下面的代码进行比较。 _apply_voi_meta()
在 Case
class.
#%%
cr = CaseReader('abc.sql')
case_keys = cr.list_cases()
obj=[]
for i, case_key in enumerate(case_keys):
case = cr.get_case(case_key)
derivs = cr.get_case(i).jacobian
# for k in derivs:
# print(k,derivs[k])
recorded_objectives = case.get_objectives()
recorder_constraints = case.get_constraints()
recorder_desvars = case.get_design_vars()
recorder_responses = case.get_responses()
for k in recorder_desvars:
print(k,recorder_desvars[k])
for k in recorder_constraints:
print(k,recorder_constraints[k])
for k in recorded_objectives:
print(k,recorded_objectives[k])
obj.append(recorded_objectives[k])
print('-----------')
print('\nDRIVER:\n\n')
for k, v in iteritems(driver.get_design_var_values()):
print(k, v)
for k, v in iteritems(driver.get_constraint_values()):
print(k, v)
for k, v in iteritems(driver.get_objective_values()):
print(k, v)
现在很清楚了,问题的根源是录音机。在你的情况下,你调用 both get_constraints()
和 get_responses()
方法。在这些方法中,可变变量被缩放。因此,当您 return 值时, _apply_voi_meta()
中的变量 vals
也会缩放。当您多次调用任何函数,即缩放相同的变量时,作为副作用,变量将在每次函数调用时缩放。
参见下面的示例:
#%%
cr = CaseReader('abc.sql')
case_keys = cr.list_cases()
obj=[]
scaled = True
for i, case_key in enumerate(case_keys):
case = cr.get_case(case_key)
derivs = cr.get_case(i).jacobian
# for k in derivs:
# print(k,derivs[k])
recorded_objectives = case.get_objectives(scaled=scaled)
recorder_constraints = case.get_constraints(scaled=scaled)
recorder_desvars = case.get_design_vars()
# recorder_responses = case.get_responses(scaled=scaled)
case.get_constraints(scaled=scaled)
case.get_constraints(scaled=scaled)
for k in recorder_desvars:
print(k,recorder_desvars[k])
for k in recorder_constraints:
print(k,recorder_constraints[k])
for k in recorded_objectives:
print(k,recorded_objectives[k])
obj.append(recorded_objectives[k])
print('-----------')
print('\nDRIVER:\n\n')
for k, v in iteritems(driver.get_design_var_values()):
print(k, v)
for k, v in iteritems(driver.get_constraint_values()):
print(k, v)
for k, v in iteritems(driver.get_objective_values()):
print(k, v)
如果缩放器为 10,约束将是未缩放值的 1000(或 10^3)倍,因为现在我调用了 get_constraints()
方法 3 次。