import numpy as np
N=10
K=3
D=4
M_ikl = np.zeros((N,K,D))
one_minu_theta = np.random.randint(5, size=(N,D))+0.5
F = np.random.randint(2, size=(K,D))+0.5
sigma = np.random.randint(2, size=(K,D))+0.5
dat = np.random.randint(2, size=(N,D))+0.5
tau = np.random.randint(2, size=(K,D))+0.5
exp_gamma = np.random.randint(2, size=(K))+0.5
exp_gamma_minus = np.random.randint(2, size=(K))+0.5
M_ikl = np.zeros((N,K,D))
for i in range(N):
for k in range(K):
for l in range(D):
M_ikl[i][k][l] = np.exp(one_minu_theta[i][l]*(F[k][l]+(sigma[k][l]-1)*np.log(dat[i][l])-(sigma[k][l]+tau[k][l])*np.log(1+dat[i][l])) + exp_gamma[k]+ np.sum(exp_gamma_minus[:-1]))
答案 0 :(得分:0)
您可能正在执行大量重新计算。
M_ikl[i][k][l] = np.exp(
one_minu_theta[i][l] * (
F[k][l] +
(sigma[k][l]-1) * np.log(dat[i][l]) -
(sigma[k][l]+tau[k][l]) * np.log(1+dat[i][l])
) +
exp_gamma[k] +
np.sum(exp_gamma_minus[:-1])
)
您要避免在算法的核心中执行日志和求和
log_dat = np.log(dat)
log_dat_p1 = np.log(1+dat)
sum_gamma = np.sum(exp_gamma_minus[:-1])
for ... :
M_ikl[i][k][l] = np.exp(
one_minu_theta[i][l] * (
F[k][l] +
(sigma[k][l]-1) * log_dat[i][l] -
(sigma[k][l]+tau[k][l]) * logdat_p1[i][l]
) +
exp_gamma[k] +
sum_gamma
)
接下来,我将考虑在循环之外最后进行指数运算。
for ... :
lnM_ikl[i][k][l] =
one_minus_theta[i][l] * (
F[k][l] +
(sigma[k][l]-1) * log_dat[i][l] -
(sigma[k][l]+tau[k][l]) * logdat_p1[i][l]
) +
exp_gamma[k] +
sum_gamma
M = np.exp(lnM_ikl)
(我认为您的sum_gamma项是错误的,因为它取决于方程式中的k,但不取决于您的实现中的k-我将继续假设它没问题)
现在您可以尝试将其拆分以使用numpys分布和张量积等。 但是我认为创建一个小的numba函数已经很简单了,应该可以很快得到结果。
@numba
def calc_log_M(one_minus_theta, F, sigma, log_dat, logdat_p1, exp_gamma, sum_gamma):
lnM = np.zeros(...)
for ... :
lnM[i][k][l] =
one_minus_theta[i][l] * (
F[k][l] +
(sigma[k][l]-1) * log_dat[i][l] -
(sigma[k][l]+tau[k][l]) * logdat_p1[i][l]
) +
exp_gamma[k] +
sum_gamma
return lnM
log_dat = np.log(dat)
log_dat_p1 = np.log(1+dat)
sum_gamma = np.sum(exp_gamma_minus[:-1])
M = np.exp(calc_log_M(one_minus_theta, F, sigma, log_dat, logdat_p1, exp_gamma, sum_gamma))
您可能需要调整numba参数以获得最佳性能。