簡體   English   中英

如何在二維數組上加速python curve_fit?

[英]How to speed up python curve_fit over a 2D array?

我必須對大量數據 (5 000 000) 使用 curve_fit numpy 函數。 所以基本上我已經創建了一個二維數組。 第一個維度是要執行的擬合數量,第二個維度是用於擬合的點數。

t = np.array([0 1 2 3 4])

for d in np.ndindex(data.shape[0]):
  try:
    popt, pcov = curve_fit(func, t, np.squeeze(data[d,:]), p0=[1000,100])
  except RuntimeError:
    print("Error - curve_fit failed")

可以使用 multiprocessing 來加速整個過程,但它仍然很慢。 有沒有辦法以“矢量化”的方式使用 curve_fit ?

加快速度的一種方法是向 curve_fit 添加一些先驗知識。

如果您知道期望參數的范圍,並且不需要達到第 100 個有效數字的精度,則可以大大加快計算速度。

這是一個示例,您將在其中擬合param1param2

t = np.array([0 1 2 3 4])
def func(t, param1, param2):
  return param1*t + param2*np.exp(t)

for d in np.ndindex(data.shape[0]):
  try:
    popt, pcov = curve_fit(func, t, np.squeeze(data[d,:]), p0=[1000,100], 
                           bounds=([min_param1, min_param2],[max_param1, max_param2]),
                           ftol=0.5, xtol=0.5)
  except RuntimeError:
    print("Error - curve_fit failed")

注意額外的關鍵參數boundsftolxtol 您可以在此處閱讀有關它們的信息。

曲線擬合擴展了scipy.optimize.leastsq的功能,它本身是底層 MINPACK lmdiflmder fortran 例程的包裝器。 看起來多線程是不可能的,看看這個鏈接,它說,

底層的 Fortran 77 例程(MINPACK lmder.f 和 lmdif.f)不可重入,因此無法釋放 GIL。 (因此沒有機會與線程並行處理。)

仍然有一個開放的來開發這個,但看起來它無法完成......您需要使用不同的庫或在較低級別的代碼中編寫包裝器/函數。 有關於並行 Levenberg-Marquardt 算法實現的論文

也許還有另一種解決方案,使用較少的數據或作為粗略估計,您可以將數據隨機分成幾部分,在單獨的線程(使用多處理器)上對每個部分進行曲線擬合,並在最后取系數的平均值.

根據我的經驗,如果可能,您應該將 jacobian 提供給 curve_fit。 通過避免一次又一次地調用func來計算雅可比,它將節省時間。 它會給您帶來顯着的速度提升,尤其是在您處理大量可優化參數時。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM