Как отметил Пол, einsum - это простой способ выполнить задачу, но если скорость вызывает беспокойство, то, как правило, лучше придерживаться типичных функций numpy.
Это может быть достигнуто путем выписывания уравнения и перевода шагов в матричные операции.
Пусть X
будет m x d
матрицей данных, для которой вы хотите выполнить пакетную обработку, а Z
будет m x d
желаемым результатом. Мы придем к Z.T
(транспонировать), потому что это проще.
Обратите внимание, что для получения уравнения для вклада R
мы можем написать

Тогда мы можем это умножить на числовую матрицу R.dot(X.T)
.
Аналогично, обратите внимание, что вклад T
равен

Внутри скобок находится матрица пакетов, умноженная между T
и X.T
. Таким образом, если мы определим количество в скобках как

Мы можем прийти к нему с помощью W = np.matmul(T,X.T)
. Продолжая наше упрощение, мы видим, что T
вклад составляет

Что эквивалентно np.sum(W*X.T[np.newaxis,:,:], axis=1)
. Собирая все вместе, мы получаем
W = np.matmul(T,X.T)
ZT = R.dot(X.T) + np.sum(W*X.T[np.newaxis,:,:], axis=1)
Z = ZT.T
Для больших размеров партии это примерно в 3-4 раза быстрее, чем функция einsum при d=2
. Если бы нам не пришлось использовать как можно больше транспозов, это могло бы быть даже немного быстрее.