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)
Другие вопросы по тегам