Отображаемое сообщение об ошибке довольно легко устранить.np.zeros
создает массив dtype=np.float64
по умолчанию, который равен nb.float64
в numba.Вы должны указать dtype
в np.zeros
, чтобы получить массив 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
с выводом / приведением типа.Все типы 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 преобразуется в int64 в numba в любом случае.Используя Обходной путь 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)
Поскольку я предполагаю, что приведение к поведению является ошибкой, я рекомендую сообщить об этом со ссылкой на этот поток.