【发布时间】:2020-03-22 22:03:24
【问题描述】:
这是一个简单的例子,它对两个高斯 pdf 的乘积进行数值积分。其中一个高斯是固定的,均值始终为 0。另一个高斯的均值变化:
import time
import jax.numpy as np
from jax import jit
from jax.scipy.stats.norm import pdf
# set up evaluation points for numerical integration
integr_resolution = 6400
lower_bound = -100
upper_bound = 100
integr_grid = np.linspace(lower_bound, upper_bound, integr_resolution)
proba = pdf(integr_grid)
integration_weight = (upper_bound - lower_bound) / integr_resolution
# integrate with new mean
def integrate(mu_new):
x_new = integr_grid - mu_new
proba_new = pdf(x_new)
total_proba = sum(proba * proba_new * integration_weight)
return total_proba
print('starting jit')
start = time.perf_counter()
integrate = jit(integrate)
integrate(1)
stop = time.perf_counter()
print('took: ', stop - start)
这个函数看起来很简单,但它根本无法扩展。以下列表包含成对的(integr_resolution 的值,运行代码所用的时间):
- 100 | 0.107s
- 200 | 0.23s
- 400 | 0.537s
- 800 | 1.52s
- 1600 | 5.2秒
- 3200 | 19 岁
- 6400 | 134秒
作为参考,应用于integr_resolution=6400 的unjitted 函数耗时0.02s。
我认为这可能与函数正在访问全局变量有关。但是移动代码以在函数内部设置积分点对时序没有显着影响。以下代码需要 5.36 秒才能运行。它对应于之前耗时 5.2s 的 1600 表项:
# integrate with new mean
def integrate(mu_new):
# set up evaluation points for numerical integration
integr_resolution = 1600
lower_bound = -100
upper_bound = 100
integr_grid = np.linspace(lower_bound, upper_bound, integr_resolution)
proba = pdf(integr_grid)
integration_weight = (upper_bound - lower_bound) / integr_resolution
x_new = integr_grid - mu_new
proba_new = pdf(x_new)
total_proba = sum(proba * proba_new * integration_weight)
return total_proba
这里发生了什么?
【问题讨论】: