我已经注意到,定义不相关的偏导数可以显著减缓优化器的速度。因此,我试图理解:我如何知道是否应该为某个输入/输出关系定义偏导数?
发布于 2018-05-18 17:23:45
当你说“不必要”时,你是指总是零的偏导数吗?
使用declare_partials('*', '*')时,当组件确实更稀疏时,将大大降低模型的速度。任何偏导数总是为零的地方,你都不应该声明它。
此外,如果你有一个矢量化运算,那么你的雅可比实际上是一个对角矩阵。在这种情况下,您应该通过给rows和cols参数给declare_partial调用1来声明稀疏的偏导数。这通常会大大加快代码的速度。
从技术上讲,如果您遵循从所有设计变量到目标和约束的所有设计变量的数据路径,那么您传递的任何变量都需要定义其部分。但实际上,您应该声明并指定每个输出w.r.t的所有部分。每个输入(除非它们是零),这样模型连通性的变化就不会破坏你的衍生产品。
需要更多的时间来更少地声明您的部分,但是性能的提高是值得的。
发布于 2018-05-18 13:41:02
我认为,如果它们与优化中的响应(约束或目标)相关,或作为组内非线性求解的一部分,则需要对它们进行定义。我个人的做法是永远定义它们。如果我每次改变我的优化问题,我经常这样做,我不想回到过去,并确保我总是定义适当的导数。
OpenMDAO的主分支包含一些jacobian着色技术,如果您的问题本质上特别稀疏,这些技术可以显著提高性能。通过在驱动程序上设置以下选项,可以启用此方法:
p.driver.options['dynamic_simul_derivs'] = True
p.driver.options['dynamic_simul_derivs_repeats'] = 5该方法的工作原理是用随机数填充用户描述的稀疏模式(用rows和cols在声明部分指定)并计算总雅可比。重复选项是在提高对结果的信心,因为它是可能的,但不太可能,一次通过将导致“偶然的零”在雅可比,而不是真正的稀疏结构的一部分。
使用这种技术,并通过通过计算而不是使用嵌套的for循环进行矢量化等操作,我在很多情况下都能获得很好的性能。当然,这些方法的有效性将随着模型的变化而变化。
https://stackoverflow.com/questions/50408137
复制相似问题