在最小化問題和他們的雅可比行列式的約束條件之間存在相當多的共享計算,直到我幾乎可以免費獲得雅可比行列式。有什麼辦法可以分享計算嗎?scipy.optimize.minimize,一次性計算約束條件和他們的雅可比行程
回答
由於約束條件和雅各布可能並不總是一起評估,所以您只能期待較小的改進。
import scipy.optimize as opt
from functools import lru_cache
# only for the dummy example:
import scipy as sp
from time import sleep
def cost(x):
'''dummy cost function to minimize on [1,11]'''
return sp.log(x)
@lru_cache(maxsize=None) # careful with this choice
def heavy_stuff(x):
'''idle computation representing common work in constraint and jacobian'''
sleep(0.1)
return 0
def constraint(x):
'''constraint for [1,11], with simulated idle work'''
# the following only works for 1d arrays, needs more work for nd
throwaway = heavy_stuff(tuple(x))
return 5 - abs(6 - x) # non-negative between 1 and 11
def jacobian(x):
'''return the jacobiam with the same simulated idle work'''
throwaway = heavy_stuff(tuple(x))
return 1/x
x0 = 11
tol = 0
opts = {'disp': True}
cons = {'type': 'ineq', 'fun': constraint}
kwargs = {'method':'SLSQP', 'constraints': cons,
'jac': jacobian, 'tol': tol, 'options': opts}
res = opt.minimize(cost,x0,**kwargs)
print(heavy_stuff.cache_info())
上述嘗試啞例子在減少log(x)
:但是,如果你可以把常見的計算成一個單獨的函數/方法,你可以讓你不需要以後重新計算其cache其返回值區間[1,11]
。我不定義界限,而是定義了一個給我們間隔的約束,這樣我就可以顯示我對你的問題的意思。
constraint
和jacobian
都做同樣的工作,這是你想在多個評估發生同樣的論點時想要的。您必須將所有這些常用計算放入一個常用函數(這裏命名爲heavy_stuff
),並使用constraint
和jacobian
中的返回值。
我的觀點是,你應該使用functools.lru_cache
來記憶沉重的東西。通過設置適當的緩存大小,使用相同的x
的多個評估heavy_stuff
將立即爲您提供先前計算的返回值,而不必重新計算。
如果我的懷疑是正確的,maxsize=1
可能就足夠了lru_cache
裝飾者。設置maxsize=None
(沒有上限)會造成失去太多內存的危險,因爲沒有理由。你應該試驗一下,看看是否有多個記憶值是必要的,或者是少數還是隻有一個就足夠了。
但是,請注意,lru_cache
使用一個詞典來查找先前計算的結果,其中鍵是裝飾函數的輸入參數。這意味着輸入參數必須是可哈希的,這實際上意味着它們應該是不可變的。 Numpy數組與列表非常相似,它們同樣是而不是可哈希。這就是爲什麼我們使用tuple(x)
將heavy_stuff
稱爲:1d數組輸入被轉換爲元組。如果x
是一個多維數組,則每一層的嵌套都必須轉換爲一個元組。更糟的是,heavy_stuff
幾乎肯定必須將元組轉換回numpy ndarrays才能完成繁重的工作。但是,如果計算雅可比/約束實際上是CPU密集型的,那麼你總體上可能還是更好。
如果你想評估你的緩存的性能,你應該仔細看看最後打印的heavy_stuff.cache_info()
。它會告訴你使用緩存值的頻率,以及需要計算新值的次數。
- 1. Scipy.optimize.minimize SLSQP線性約束失敗
- 2. Scipy.optimize.minimize method ='SLSQP'忽略約束
- 3. scipy.optimize.minimize在python中進行約束優化
- 4. 條件MYSQL的唯一約束條件
- 5. 主鍵和約束條件
- 6. UILabel sizeToFit和約束條件
- 7. ER圖和約束條件
- 8. 在線性編程中將條件約束轉換爲線性約束
- 9. 乾淨的方式來計算雅可比陣的總和
- 10. Oracle中的完整性約束條件
- 11. 唯一約束在兩個字段和他們的反向
- 12. 「SQLSTATE [23000]:完整性約束違規」與有效約束條件
- 13. 'asm'中的不可約束條件
- 14. SQLServer2000約束條件
- 15. 當其他人隱藏一個按鈕時的約束條件
- 16. 有條件的唯一約束的DB2
- 17. 具有適當比率約束和重量約束的揹包算法
- 18. 使用MYSQL條件的唯一約束
- 19. 子類的唯一約束條件
- 20. 有條件的唯一約束
- 21. 表列上的唯一約束條件
- 22. oracle db中的條件唯一約束
- 23. NodeEntity的唯一約束條件
- 24. Postgres的條件唯一約束
- 25. Mnesia中的唯一約束條件
- 26. Postgresql:有條件的唯一約束
- 27. POSTGRESQL的約束條件
- 28. Mysql的約束與條件
- 29. 檢查約束的條件
- 30. 如何定義基於其他列計算的約束列
你可以添加一個例子嗎? – Cleb
由於函數是python中的一等公民,我想你可以嘗試定義一個函數來處理jacobian和constraint,並使用實例屬性來存儲常用的東西。但是,那麼你將不得不首先處理哪一個......也許通過設置一個帶有「回調」的標誌?我只是在猜測,我從來沒有做過類似的事情。 –