使用scipy.optimize时如何评估执行时间?
How to evaluate execution time when using scipy.optimize?
我正在编写一个 python 脚本,该脚本利用 scipy.optimize
中的 minimize()
函数。该脚本工作正常,但速度相对较慢,我正在尝试弄清楚如何 (a) 弄清楚时间花在了哪里) 所以我可以 (b) 加快速度。
我当前的基准 "slow" 我有一个实体数据集,其中每个实体包含约 5000 个样本(即,我需要 minimize()
5000 times/entity。我有大约 2000 个实体. 我当前的 运行 时间在每个实体 35-45 秒之间变化,所以我正在查看总共 运行 时间 80k 秒(或 22.2 小时)。如果它只是一个就好了-关闭,但这是需要测试多个模型等的东西。所以我需要减少 运行 次。
脚本主要部分如下:
###Initializing Export Arrays
Vmin1 = np.array([])
Vmin2 = np.array([])
Vmin3 = np.array([])
Vmin4 = np.array([])
Vmin5 = np.array([])
Vmin6 = np.array([])
Vclay = np.array([])
Vker = np.array([])
###Initial Estimate
x0 = np.array([0.5, 0.1, 0.1, 0.0, 0.01, 0.07, 0.2, 0.02,])
bounds = ((0,1), (0,1), (0,1), (0,1), (0,1), (0,1), (0,1), (0,1))
C =np.array([[rhob_Vmin1, rhob_Vmin2, rhob_Vmin3, rhob_Vmin4, rhob_Vmin5, rhob_Vmin6, rhob_Vclay, rhob_Vker],
[nphi_Vmin1, nphi_Vmin2, nphi_Vmin3, nphi_Vmin4, nphi_Vmin5, nphi_Vmin6, nphi_Vclay, nphi_Vker],
[pe_Vmin1, pe_Vmin2, pe_Vmin3, pe_Vmin4, pe_Vmin5, pe_Vmin6, pe_Vclay, pe_Vker],
[dt_Vmin1, dt_Vmin2, dt_Vmin3, dt_Vmin4, dt_Vmin5, dt_Vmin6, dt_Vclay, dt_Vker],
[0,0,0,0,0,0,1,0],
[0,0,0,0,0,0,0,1],
[1,1,1,1,1,1,1,1]])
def mineral_inversion(x, L, C):
L_pred = np.matmul(C, x)
if not np.isnan(L[0][0]):
I1 = (np.subtract(L[0][0], L_pred[0])/unc_rhob)**2
else:
I1=0
if not np.isnan(L[0][1]):
I2 = (np.subtract(L[0][1], L_pred[1])/unc_nphi)**2
else:
I2 = 0
if not np.isnan(L[0][2]):
I3 = (np.subtract(L[0][2], L_pred[2])/unc_pe)**2
else:
I3 = 0
if not np.isnan(L[0][3]):
I4 = (np.subtract(L[0][3], L_pred[3])/unc_dt)**2
else:
I4 = 0
if not np.isnan(L[0][4]):
I5 = (np.subtract(L[0][4], L_pred[4])/unc_vwcl)**2
else:
I5 = 0
if not np.isnan(L[0][5]):
I6 = (np.subtract(L[0][5], L_pred[5])/unc_vker)**2
else:
I6 = 0
I7 = ((1-x.sum())/unc_unity)**2
incoherence = I1+I2+I3+I4+I5+I6+I7
return incoherence
from datetime import datetime
t0 = datetime.now()
vpor_init = np.float(0.1)
for dd in range(len(depth)):
###Log values used in mineral inversion + unity value
L = np.array([[rhob[dd], nphi[dd], pe[dd], dt[dd], vwcl[dd], vkero[dd], 1]])
res = minimize(fun = mineral_inversion, x0 = x0, args = (L, C), bounds=bounds, method='SLSQP')
Vmin1 = np.append(Vmin1, res.x[0])
Vmin2 = np.append(Vmin2, res.x[1])
Vmin3 = np.append(Vmin3, res.x[2])
Vmin4 = np.append(Vmin4, res.x[3])
Vmin5 = np.append(Vmin5, res.x[4])
Vmin6 = np.append(Vmin6, res.x[5])
Vclay = np.append(Vclay, res.x[6])
Vker = np.append(Vker, res.x[7])
t1 = datetime.now()
time = t1-t0
print('Run Time: ', time)
目前我在 for
循环级别记录 运行 时间。但是,这并没有告诉我瓶颈可能在哪里。是在mineral_inversion()
函数的层面,还是在minimize()
函数本身,等等
问题:
(1) 我如何巧妙地记录执行时间以确定是否有可能加快速度?
(2) 如果这实际上是 'slow' 或者如果我只是不合理并且有很多样本需要迭代,那么什么是公平的陈述方式?
(3) 是否有明显的不良 practices/speed 陷阱?
trying to figure out how to (a) figure out where the time is being spent
使用标准库中的 pstats 模块进行函数级分析,使用 kernprof 进行行级分析。
在 jupyter 笔记本中,它是 %prun 和 %lprun 魔法。
我正在编写一个 python 脚本,该脚本利用 scipy.optimize
中的 minimize()
函数。该脚本工作正常,但速度相对较慢,我正在尝试弄清楚如何 (a) 弄清楚时间花在了哪里) 所以我可以 (b) 加快速度。
我当前的基准 "slow" 我有一个实体数据集,其中每个实体包含约 5000 个样本(即,我需要 minimize()
5000 times/entity。我有大约 2000 个实体. 我当前的 运行 时间在每个实体 35-45 秒之间变化,所以我正在查看总共 运行 时间 80k 秒(或 22.2 小时)。如果它只是一个就好了-关闭,但这是需要测试多个模型等的东西。所以我需要减少 运行 次。
脚本主要部分如下:
###Initializing Export Arrays
Vmin1 = np.array([])
Vmin2 = np.array([])
Vmin3 = np.array([])
Vmin4 = np.array([])
Vmin5 = np.array([])
Vmin6 = np.array([])
Vclay = np.array([])
Vker = np.array([])
###Initial Estimate
x0 = np.array([0.5, 0.1, 0.1, 0.0, 0.01, 0.07, 0.2, 0.02,])
bounds = ((0,1), (0,1), (0,1), (0,1), (0,1), (0,1), (0,1), (0,1))
C =np.array([[rhob_Vmin1, rhob_Vmin2, rhob_Vmin3, rhob_Vmin4, rhob_Vmin5, rhob_Vmin6, rhob_Vclay, rhob_Vker],
[nphi_Vmin1, nphi_Vmin2, nphi_Vmin3, nphi_Vmin4, nphi_Vmin5, nphi_Vmin6, nphi_Vclay, nphi_Vker],
[pe_Vmin1, pe_Vmin2, pe_Vmin3, pe_Vmin4, pe_Vmin5, pe_Vmin6, pe_Vclay, pe_Vker],
[dt_Vmin1, dt_Vmin2, dt_Vmin3, dt_Vmin4, dt_Vmin5, dt_Vmin6, dt_Vclay, dt_Vker],
[0,0,0,0,0,0,1,0],
[0,0,0,0,0,0,0,1],
[1,1,1,1,1,1,1,1]])
def mineral_inversion(x, L, C):
L_pred = np.matmul(C, x)
if not np.isnan(L[0][0]):
I1 = (np.subtract(L[0][0], L_pred[0])/unc_rhob)**2
else:
I1=0
if not np.isnan(L[0][1]):
I2 = (np.subtract(L[0][1], L_pred[1])/unc_nphi)**2
else:
I2 = 0
if not np.isnan(L[0][2]):
I3 = (np.subtract(L[0][2], L_pred[2])/unc_pe)**2
else:
I3 = 0
if not np.isnan(L[0][3]):
I4 = (np.subtract(L[0][3], L_pred[3])/unc_dt)**2
else:
I4 = 0
if not np.isnan(L[0][4]):
I5 = (np.subtract(L[0][4], L_pred[4])/unc_vwcl)**2
else:
I5 = 0
if not np.isnan(L[0][5]):
I6 = (np.subtract(L[0][5], L_pred[5])/unc_vker)**2
else:
I6 = 0
I7 = ((1-x.sum())/unc_unity)**2
incoherence = I1+I2+I3+I4+I5+I6+I7
return incoherence
from datetime import datetime
t0 = datetime.now()
vpor_init = np.float(0.1)
for dd in range(len(depth)):
###Log values used in mineral inversion + unity value
L = np.array([[rhob[dd], nphi[dd], pe[dd], dt[dd], vwcl[dd], vkero[dd], 1]])
res = minimize(fun = mineral_inversion, x0 = x0, args = (L, C), bounds=bounds, method='SLSQP')
Vmin1 = np.append(Vmin1, res.x[0])
Vmin2 = np.append(Vmin2, res.x[1])
Vmin3 = np.append(Vmin3, res.x[2])
Vmin4 = np.append(Vmin4, res.x[3])
Vmin5 = np.append(Vmin5, res.x[4])
Vmin6 = np.append(Vmin6, res.x[5])
Vclay = np.append(Vclay, res.x[6])
Vker = np.append(Vker, res.x[7])
t1 = datetime.now()
time = t1-t0
print('Run Time: ', time)
目前我在 for
循环级别记录 运行 时间。但是,这并没有告诉我瓶颈可能在哪里。是在mineral_inversion()
函数的层面,还是在minimize()
函数本身,等等
问题: (1) 我如何巧妙地记录执行时间以确定是否有可能加快速度? (2) 如果这实际上是 'slow' 或者如果我只是不合理并且有很多样本需要迭代,那么什么是公平的陈述方式? (3) 是否有明显的不良 practices/speed 陷阱?
trying to figure out how to (a) figure out where the time is being spent
使用标准库中的 pstats 模块进行函数级分析,使用 kernprof 进行行级分析。
在 jupyter 笔记本中,它是 %prun 和 %lprun 魔法。