Как использовать трансляцию с моими массивами (3000,3) и (3,2,3000) - PullRequest
0 голосов
/ 18 февраля 2019

У меня есть 2 массива в настоящее время с формами v1 = (3000,3) и v2 = (3,2,3000).3000 - это измерение времени, поэтому v1 имеет 3000 (1,3) выборок, а v2 имеет 3000 (3,2) выборок.Я хочу сделать матричное умножение и передать по измерению 3000, чтобы я получил взамен 3000 (1,2) векторов.

Я попытался изменить форму так, чтобы v1 = (1,3,3000) и v2 =(3200), которая выдает ошибку о том, что фигуры не выровнены.

код:

v1 = np.ones((1,3,3000)) +1
v2 = np.ones((3,2,3000)) - 0.5
np.dot(v1,v2)

Ответы [ 2 ]

0 голосов
/ 19 февраля 2019

Я бы посоветовал вам не использовать optimize=True флаг, потому что он неэффективен по какой-то странной причине.Кроме того, я бы порекомендовал вам явно перевести 2D-массив в 3D, выполнить пакетное матричное умножение и затем сжать одноэлементное измерение результирующего массива, если вам в конце понадобится2D массив в качестве конечного результата.Пожалуйста, найдите код ниже:

# sample arrays
In [25]: v1 = np.random.random_sample((3000, 3))
In [26]: v2 = np.random.random_sample((3, 2, 3000))

# Divakar's approach
In [27]: %timeit np.einsum('ij,jki->ik',v1,v2, optimize=True)
80.7 µs ± 792 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

# needed for future use
In [28]: res_optimized = np.einsum('ij,jki->ik',v1,v2, optimize=True)

# promoting to 3D array and swapping axes
In [29]: v1 = v1[:, np.newaxis, :]
In [30]: v2 = np.moveaxis(v2, 2, 0)

# perform batch matrix multiplication
In [31]: %timeit np.einsum("bij, bjk -> bik", v1, v2)
47.9 µs ± 496 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

# for sanity checking
In [32]: res = np.einsum("bij, bjk -> bik", v1, v2)

In [33]: res.shape, res_optimized.shape
Out[33]: ((3000, 1, 2), (3000, 2))

# squeeze the singleton dimension and perform sanity check with Divakar's approach
In [34]: np.allclose(res.squeeze(), res_optimized)
Out[34]: True

Итак, как мы можем видеть из приведенного выше времени, мы получаем прибл.2-кратное ускорение без использования флага optimize=True.Кроме того, явное формирование массивов в 3D дает немного больше понимания того, что происходит, когда мы используем numpy.einsum().

Примечание: время было выполнено с использованием последней версии NumPy '1.16.1'


PS Узнайте больше о Понимание NumPy einsum ()

0 голосов
/ 18 февраля 2019

С v1 формы (3000,3) и v2 как (3,2,3000), мы можем использовать np.einsum -

np.einsum('ij,jki->ik',v1,v2)

Это дает нам вывод формы(3000,2).

Мы могли бы поиграть с optimize arg в np.einsumoptimize = True он использует BLAS внутри, а с optimize = False обращается к простым C-циклам.Этот способ BLAS тоже требует настройки.Таким образом, при приличных длинах осей, которые подвергаются уменьшению суммы, мы могли бы хотеть установить этот флаг как True и False в противном случае.В этом случае кажется, что эти оси действительно короткие, поэтому нам лучше использовать стандартное значение: optimize = False input.

...