OpenMDAO:什么时候需要定义偏导数?
OpenMDAO: When is it needed to define the partial derivative?
我注意到定义不必要的偏导数会显着降低优化器的速度。因此我试图理解:我怎么知道我是否应该为某个 input/output 关系定义偏导数?
我认为如果它们与优化中的响应(约束或 objective)相关,或者作为组内非线性求解的一部分,则需要对其进行定义。我个人的做法是始终定义它们。如果我经常更改我的优化问题,我不想返回并确保我始终定义适当的导数。
OpenMDAO 的主分支包含一些雅可比着色技术,如果您的问题本质上特别稀疏,这些技术可以显着提高性能。通过在驱动程序上设置以下选项来启用此方法:
p.driver.options['dynamic_simul_derivs'] = True
p.driver.options['dynamic_simul_derivs_repeats'] = 5
此方法的工作原理是用随机数填充用户描述的稀疏模式(在 declare partials 中用 rows
和 cols
指定)并计算总雅可比矩阵。重复选项可以提高对结果的信心,因为单次通过可能但不太可能导致雅可比矩阵中的 "incidental zero" 并不是真正的稀疏结构的一部分。
通过这种技术,通过计算向量化而不是使用嵌套 for 循环,我在很多情况下都获得了非常好的性能。当然,这些方法的有效性会因模型而异。
当您说 "unnecessary" 时,您是指始终为零的偏导数吗?
使用 declare_partials('*', '*')
,当组件确实比这更稀疏时,会显着降低模型速度。在偏导数始终为零的任何地方,您都不应该声明它。
此外,如果你有向量化运算,那么你的雅可比实际上是一个对角矩阵。在这种情况下,您应该通过向 declare_partial
调用 1 提供 rows
和 cols
参数来声明 [稀疏偏导数]。这通常会大大加快您的代码速度。
从技术上讲,如果您遵循从所有设计变量到每个组件的数据路径,再到 objective 和约束,那么您传递的任何变量都需要定义其部分。但实际上你应该声明并指定每个输出的所有部分 w.r.t。每个输入(除非它们为零),因此对模型连接的更改不会破坏您的导数。
更稀疏地声明你的部分需要多一点时间,但性能加速是值得的。
我注意到定义不必要的偏导数会显着降低优化器的速度。因此我试图理解:我怎么知道我是否应该为某个 input/output 关系定义偏导数?
我认为如果它们与优化中的响应(约束或 objective)相关,或者作为组内非线性求解的一部分,则需要对其进行定义。我个人的做法是始终定义它们。如果我经常更改我的优化问题,我不想返回并确保我始终定义适当的导数。
OpenMDAO 的主分支包含一些雅可比着色技术,如果您的问题本质上特别稀疏,这些技术可以显着提高性能。通过在驱动程序上设置以下选项来启用此方法:
p.driver.options['dynamic_simul_derivs'] = True
p.driver.options['dynamic_simul_derivs_repeats'] = 5
此方法的工作原理是用随机数填充用户描述的稀疏模式(在 declare partials 中用 rows
和 cols
指定)并计算总雅可比矩阵。重复选项可以提高对结果的信心,因为单次通过可能但不太可能导致雅可比矩阵中的 "incidental zero" 并不是真正的稀疏结构的一部分。
通过这种技术,通过计算向量化而不是使用嵌套 for 循环,我在很多情况下都获得了非常好的性能。当然,这些方法的有效性会因模型而异。
当您说 "unnecessary" 时,您是指始终为零的偏导数吗?
使用 declare_partials('*', '*')
,当组件确实比这更稀疏时,会显着降低模型速度。在偏导数始终为零的任何地方,您都不应该声明它。
此外,如果你有向量化运算,那么你的雅可比实际上是一个对角矩阵。在这种情况下,您应该通过向 declare_partial
调用 1 提供 rows
和 cols
参数来声明 [稀疏偏导数]。这通常会大大加快您的代码速度。
从技术上讲,如果您遵循从所有设计变量到每个组件的数据路径,再到 objective 和约束,那么您传递的任何变量都需要定义其部分。但实际上你应该声明并指定每个输出的所有部分 w.r.t。每个输入(除非它们为零),因此对模型连接的更改不会破坏您的导数。
更稀疏地声明你的部分需要多一点时间,但性能加速是值得的。