使用 Numba 时将多个输入传递给 Class 时出错
Error Passing Multiple Inputs to a Class while using Numba
我正在尝试将 Numba Decorator 与我的 class 一起使用。但是,我收到以下错误。我检查了输入维度,它看起来是正确的,但仍然出现相同的错误。知道如何解决这个问题吗?
spec = [('w_x', nb.int32), ('w_a', nb.int32),('mu_a', nb.int64[:]),
('sig_a',nb.int64[:]),('mu_x', nb.int64[:]),('sig_x', nb.int32[:]),
('mu_a_a',nb.float64[:,:]),('sig_a_a', nb.float64[:,:]), ('mu_x_a',
nb.int32[:]),('sig_x_a', nb.float32[:,:]),('mu_0', nb.boolean),
('sig_0', nb.boolean),('beta', nb.int32),('policy', nb.uint8)]
@nb.jitclass(spec)
class learner(object):
def __init__ (self, w_x, w_a, beta, policy):
'''
initialize:
w_x: the dim of customer features
w_a: the dim of ad features
mu_a: the prior of mean of weights on ad
sig_a: the prior of var of weights on ad
mu_x: the prior of mean of weights on customer
sig_x: the prior of var of weights on customer
mu_a_a: the prior of interactions between ad segments
sig_a_a: the prior of var of interactions between ad segments
mu_x_a: the prior of mean of interactions between customers and ad
segments
sig_x_a: the prior of var of interactions between customers and ad
segments
'''
self.w_x = w_x
self.w_a = w_a
self.mu_a = np.zeros(self.w_a)
self.sig_a = np.ones(self.w_a)
self.mu_x = np.zeros(self.w_x)
self.sig_x = np.ones(self.w_x)
self.mu_a_a = np.zeros((self.w_a, self.w_a))
#self.mu_a_a = np.triu(self.mu_a_a, k=1)
self.sig_a_a = np.ones((self.w_a, self.w_a))
#self.sig_a_a = np.triu(self.sig_a_a, k=1)
self.mu_x_a = np.zeros((self.w_x, self.w_a))
self.sig_x_a = np.ones((self.w_x, self.w_a))
#the intercept term w_0
self.mu_0 = 0
self.sig_0 = 1
self.beta = beta
self.policy = policy
错误信息如下:
File "C:\Users\MSHAHAB2\AppData\Local\Continuum\anaconda3\lib\site-
packages\numba\six.py", line 659, in reraise
raise value numba.errors.LoweringError: Failed at nopython (nopython mode
backend)
Can only insert i64* at [4] in {i8*, i8*, i64, i64, i64*, [1 x i64], [1 x
i64]}: got double*
File "batch_mode_function.py", line 147:
def __init__ (self, w_x, w_a, beta, policy):
<source elided>
self.w_a = w_a
self.mu_a = np.zeros(self.w_a)
^
[1] During: lowering "(self).mu_a = [=12=].9" at
W:\GRMOS\MShahabi\MNV\HillClimbSim\batch_mode_function.py (147)
[2] During: resolving callee type:
jitclass.learner#1e390f65798<w_x:int32,w_a:int32,mu_a:array(int64, 1d,
A),sig_a:array(int64, 1d, A),mu_x:array(int64, 1d, A),sig_x:array(int32, 1d,
A),mu_a_a:array(float64, 2d, A),sig_a_a:array(float64, 2d,
A),mu_x_a:array(int32, 1d, A),sig_x_a:array(float32, 2d,
A),mu_0:bool,sig_0:bool,beta:int32,policy:uint8>
[3] During: typing of call at <string> (3)
显示的错误消息很容易解决。 np.zeros
默认创建一个 dtype=np.float64
的数组,在 numba 中是 nb.float64
。您必须在 np.zeros
中指定 dtype
以获得 np.int64
或 np.int32
:
的数组
self.mu_a = np.zeros(self.w_a, dtype=np.int64)
self.sig_a = np.ones(self.w_a, dtype=np.int64)
self.mu_x = np.zeros(self.w_x, dtype=np.int64)
self.sig_x = np.ones(self.w_x, dtype=np.int32)
数组 self.mu_x_a
和 self.sig_x_a
相同
self.mu_x_a = np.zeros((self.w_x, self.w_a), dtype=np.int32)
self.sig_x_a = np.ones((self.w_x, self.w_a), dtype=np.float32)
对于 self.mu_x_a
,您还错过了 spec
中的第二个维度。它必须是:
spec = [('mu_x_a', nb.int32[:, :])]
然后创建数组时出现后续错误self.mu_a_a
。 Numba 引发错误,形状元组 (self.w_a, self.w_a)
的类型为 (i64, i32)
。这显然是 numba
中类型为 inference/casting 的一些错误。所有 nb.int32
类型似乎都自动转换为 nb.int64
。
有两种解决方法:
解决方法 1:
将 self.w_a
的类型签名替换为 nb.int64
(以及 self.w_x
,因为 self.mu_x_a
和 self.sig_x_a
需要):
spec = [('w_x', nb.int64), ('w_a', nb.int64)]
或
解决方法 2:
不要使用以某种方式不一致的强制转换实例变量。而是使用给定的输入:
self.mu_a_a = np.zeros((w_a, w_a))
self.sig_a_a = np.ones((w_a, w_a))
self.mu_x_a = np.zeros((w_x, w_a), dtype=np.int32)
self.sig_x_a = np.ones((w_x, w_a), dtype=np.float32)
我建议使用解决方法 1,因为目前 int32 无论如何都会在 numba 中转换为 int64。使用 解决方法 1 它应该如下所示:
spec = [('w_x', nb.int64), ('w_a', nb.int64),('mu_a', nb.int64[:]),
('sig_a',nb.int64[:]),('mu_x', nb.int64[:]),('sig_x', nb.int32[:]),
('mu_a_a',nb.float64[:,:]),('sig_a_a', nb.float64[:,:]), ('mu_x_a',
nb.int32[:, :]),('sig_x_a', nb.float32[:,:]),('mu_0', nb.boolean),
('sig_0', nb.boolean),('beta', nb.int32),('policy', nb.uint8)]
@nb.jitclass(spec)
class learner(object):
def __init__ (self, w_x, w_a, beta, policy):
'''
initialize:
w_x: the dim of customer features
w_a: the dim of ad features
mu_a: the prior of mean of weights on ad
sig_a: the prior of var of weights on ad
mu_x: the prior of mean of weights on customer
sig_x: the prior of var of weights on customer
mu_a_a: the prior of interactions between ad segments
sig_a_a: the prior of var of interactions between ad segments
mu_x_a: the prior of mean of interactions between customers and ad
segments
sig_x_a: the prior of var of interactions between customers and ad
segments
'''
self.w_x = w_x
self.w_a = w_a
self.mu_a = np.zeros(self.w_a, dtype=np.int64)
self.sig_a = np.ones(self.w_a, dtype=np.int64)
self.mu_x = np.zeros(self.w_x, dtype=np.int64)
self.sig_x = np.ones(self.w_x, dtype=np.int32)
self.mu_a_a = np.zeros((self.w_a, self.w_a))
#self.mu_a_a = np.triu(self.mu_a_a, k=1)
self.sig_a_a = np.ones((self.w_a, self.w_a))
#self.sig_a_a = np.triu(self.sig_a_a, k=1)
self.mu_x_a = np.zeros((self.w_x, self.w_a), dtype=np.int32)
self.sig_x_a = np.ones((self.w_x, self.w_a), dtype=np.float32)
#the intercept term w_0
self.mu_0 = 0
self.sig_0 = 1
self.beta = beta
self.policy = policy
对于 解决方法 2 您可以将 w_x
和 w_a
的规范保留为 nb.int32
并仅替换以下数组创建4 个数组:
self.mu_a_a = np.zeros((w_a, w_a))
self.sig_a_a = np.ones((w_a, w_a))
self.mu_x_a = np.zeros((w_x, w_a), dtype=np.int32)
self.sig_x_a = np.ones((w_x, w_a), dtype=np.float32)
因为我猜转换行为是一个错误,我建议你用 link 向这个线程报告它。
我正在尝试将 Numba Decorator 与我的 class 一起使用。但是,我收到以下错误。我检查了输入维度,它看起来是正确的,但仍然出现相同的错误。知道如何解决这个问题吗?
spec = [('w_x', nb.int32), ('w_a', nb.int32),('mu_a', nb.int64[:]),
('sig_a',nb.int64[:]),('mu_x', nb.int64[:]),('sig_x', nb.int32[:]),
('mu_a_a',nb.float64[:,:]),('sig_a_a', nb.float64[:,:]), ('mu_x_a',
nb.int32[:]),('sig_x_a', nb.float32[:,:]),('mu_0', nb.boolean),
('sig_0', nb.boolean),('beta', nb.int32),('policy', nb.uint8)]
@nb.jitclass(spec)
class learner(object):
def __init__ (self, w_x, w_a, beta, policy):
'''
initialize:
w_x: the dim of customer features
w_a: the dim of ad features
mu_a: the prior of mean of weights on ad
sig_a: the prior of var of weights on ad
mu_x: the prior of mean of weights on customer
sig_x: the prior of var of weights on customer
mu_a_a: the prior of interactions between ad segments
sig_a_a: the prior of var of interactions between ad segments
mu_x_a: the prior of mean of interactions between customers and ad
segments
sig_x_a: the prior of var of interactions between customers and ad
segments
'''
self.w_x = w_x
self.w_a = w_a
self.mu_a = np.zeros(self.w_a)
self.sig_a = np.ones(self.w_a)
self.mu_x = np.zeros(self.w_x)
self.sig_x = np.ones(self.w_x)
self.mu_a_a = np.zeros((self.w_a, self.w_a))
#self.mu_a_a = np.triu(self.mu_a_a, k=1)
self.sig_a_a = np.ones((self.w_a, self.w_a))
#self.sig_a_a = np.triu(self.sig_a_a, k=1)
self.mu_x_a = np.zeros((self.w_x, self.w_a))
self.sig_x_a = np.ones((self.w_x, self.w_a))
#the intercept term w_0
self.mu_0 = 0
self.sig_0 = 1
self.beta = beta
self.policy = policy
错误信息如下:
File "C:\Users\MSHAHAB2\AppData\Local\Continuum\anaconda3\lib\site-
packages\numba\six.py", line 659, in reraise
raise value numba.errors.LoweringError: Failed at nopython (nopython mode
backend)
Can only insert i64* at [4] in {i8*, i8*, i64, i64, i64*, [1 x i64], [1 x
i64]}: got double*
File "batch_mode_function.py", line 147:
def __init__ (self, w_x, w_a, beta, policy):
<source elided>
self.w_a = w_a
self.mu_a = np.zeros(self.w_a)
^
[1] During: lowering "(self).mu_a = [=12=].9" at
W:\GRMOS\MShahabi\MNV\HillClimbSim\batch_mode_function.py (147)
[2] During: resolving callee type:
jitclass.learner#1e390f65798<w_x:int32,w_a:int32,mu_a:array(int64, 1d,
A),sig_a:array(int64, 1d, A),mu_x:array(int64, 1d, A),sig_x:array(int32, 1d,
A),mu_a_a:array(float64, 2d, A),sig_a_a:array(float64, 2d,
A),mu_x_a:array(int32, 1d, A),sig_x_a:array(float32, 2d,
A),mu_0:bool,sig_0:bool,beta:int32,policy:uint8>
[3] During: typing of call at <string> (3)
显示的错误消息很容易解决。 np.zeros
默认创建一个 dtype=np.float64
的数组,在 numba 中是 nb.float64
。您必须在 np.zeros
中指定 dtype
以获得 np.int64
或 np.int32
:
self.mu_a = np.zeros(self.w_a, dtype=np.int64)
self.sig_a = np.ones(self.w_a, dtype=np.int64)
self.mu_x = np.zeros(self.w_x, dtype=np.int64)
self.sig_x = np.ones(self.w_x, dtype=np.int32)
数组 self.mu_x_a
和 self.sig_x_a
self.mu_x_a = np.zeros((self.w_x, self.w_a), dtype=np.int32)
self.sig_x_a = np.ones((self.w_x, self.w_a), dtype=np.float32)
对于 self.mu_x_a
,您还错过了 spec
中的第二个维度。它必须是:
spec = [('mu_x_a', nb.int32[:, :])]
然后创建数组时出现后续错误self.mu_a_a
。 Numba 引发错误,形状元组 (self.w_a, self.w_a)
的类型为 (i64, i32)
。这显然是 numba
中类型为 inference/casting 的一些错误。所有 nb.int32
类型似乎都自动转换为 nb.int64
。
有两种解决方法:
解决方法 1:
将 self.w_a
的类型签名替换为 nb.int64
(以及 self.w_x
,因为 self.mu_x_a
和 self.sig_x_a
需要):
spec = [('w_x', nb.int64), ('w_a', nb.int64)]
或 解决方法 2: 不要使用以某种方式不一致的强制转换实例变量。而是使用给定的输入:
self.mu_a_a = np.zeros((w_a, w_a))
self.sig_a_a = np.ones((w_a, w_a))
self.mu_x_a = np.zeros((w_x, w_a), dtype=np.int32)
self.sig_x_a = np.ones((w_x, w_a), dtype=np.float32)
我建议使用解决方法 1,因为目前 int32 无论如何都会在 numba 中转换为 int64。使用 解决方法 1 它应该如下所示:
spec = [('w_x', nb.int64), ('w_a', nb.int64),('mu_a', nb.int64[:]),
('sig_a',nb.int64[:]),('mu_x', nb.int64[:]),('sig_x', nb.int32[:]),
('mu_a_a',nb.float64[:,:]),('sig_a_a', nb.float64[:,:]), ('mu_x_a',
nb.int32[:, :]),('sig_x_a', nb.float32[:,:]),('mu_0', nb.boolean),
('sig_0', nb.boolean),('beta', nb.int32),('policy', nb.uint8)]
@nb.jitclass(spec)
class learner(object):
def __init__ (self, w_x, w_a, beta, policy):
'''
initialize:
w_x: the dim of customer features
w_a: the dim of ad features
mu_a: the prior of mean of weights on ad
sig_a: the prior of var of weights on ad
mu_x: the prior of mean of weights on customer
sig_x: the prior of var of weights on customer
mu_a_a: the prior of interactions between ad segments
sig_a_a: the prior of var of interactions between ad segments
mu_x_a: the prior of mean of interactions between customers and ad
segments
sig_x_a: the prior of var of interactions between customers and ad
segments
'''
self.w_x = w_x
self.w_a = w_a
self.mu_a = np.zeros(self.w_a, dtype=np.int64)
self.sig_a = np.ones(self.w_a, dtype=np.int64)
self.mu_x = np.zeros(self.w_x, dtype=np.int64)
self.sig_x = np.ones(self.w_x, dtype=np.int32)
self.mu_a_a = np.zeros((self.w_a, self.w_a))
#self.mu_a_a = np.triu(self.mu_a_a, k=1)
self.sig_a_a = np.ones((self.w_a, self.w_a))
#self.sig_a_a = np.triu(self.sig_a_a, k=1)
self.mu_x_a = np.zeros((self.w_x, self.w_a), dtype=np.int32)
self.sig_x_a = np.ones((self.w_x, self.w_a), dtype=np.float32)
#the intercept term w_0
self.mu_0 = 0
self.sig_0 = 1
self.beta = beta
self.policy = policy
对于 解决方法 2 您可以将 w_x
和 w_a
的规范保留为 nb.int32
并仅替换以下数组创建4 个数组:
self.mu_a_a = np.zeros((w_a, w_a))
self.sig_a_a = np.ones((w_a, w_a))
self.mu_x_a = np.zeros((w_x, w_a), dtype=np.int32)
self.sig_x_a = np.ones((w_x, w_a), dtype=np.float32)
因为我猜转换行为是一个错误,我建议你用 link 向这个线程报告它。