numpy.einsum 'ij,kl->ik' как это сделать с помощью numpy.tensordot
У меня две матрицы, 5х4 и 3х2. Я хочу получить матрицу 5х3 от них.
>>>theta_ic = np.random.randint(5,size=(5,4))
>>>psi_tr = np.random.randint(5,size=(3,2))
Я могу сделать это
>>>np.einsum('ij,kl->ik',theta_ic,psi_tr).shape
(5,3)
Но я не знаю, как это сделать с помощью numpy.tensordot, я попробовал это
>>>np.tensordot(theta_ic,psi_tr,((1),(1)))
Я получаю ошибку
ValueError: shape-mismatch for sum
Математика позади
z_ij = \sum_{c=1}^4{x_{ic}}\sum_{d=1}^{2}{y_{jd}}
where i=[1,...,5], j=[1...3]
Почему мне нужно мигрировать einsum
в tensordot
?
Потому что я делаю свое исследование, используя pymc3
пакет, который используют theano
в качестве бэкэнда для ускорения вычислений.
Тем не мение, theano.tensor
не поддерживает einsum
и это только поддержка tensordot
та же грамматика, что и np.tensordot
,
1 ответ
Тот факт, что ваша формула эйнсума
'ij,kl->ik'
использует индексы
j
а также
l
один раз означает, что вы можете суммировать их перед операцией.
theta_ic2 = np.sum(theta_ic, axis=1)
psi_tr2 = np.sum(psi_tr, axis=1)
и в итоге ты получаешь
'i,k->ik'
это просто внешний продукт
theta_ic2[:, None] * psi_tr2
или в одну строку
np.sum(theta_ic, axis=1)[:, None] * np.sum(psi_tr, axis=1)
И в
np.tensordot
, параметр
axes=0
изготовим внешний продукт:
np.tensordot(np.sum(theta_ic, axis=1), np.sum(psi_tr, axis=1), axes=0)