Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 用numpy快速计算批次和时间维度上的空间变换_Python_Numpy - Fatal编程技术网

Python 用numpy快速计算批次和时间维度上的空间变换

Python 用numpy快速计算批次和时间维度上的空间变换,python,numpy,Python,Numpy,对于机器学习任务,我必须计算时间序列中每个帧的3D坐标(沿z轴旋转)的空间变换。此外,我还有一批时间序列。我希望尽可能减少for循环的使用 假设我有一个形状的旋转矩阵(batch_size,3,3)和一个形状张量(batch_size,seq_length,n_坐标,3)。我目前正在做的是一个随时间和批次维度的双for循环,并计算每个3D坐标的点积 代码如下: #计算转换 对于范围内的t(序号长度): 对于范围内的b(批次尺寸): X[b,t,:,:]=np.dot(旋转z_矩阵[b],X[b,

对于机器学习任务,我必须计算时间序列中每个帧的3D坐标(沿z轴旋转)的空间变换。此外,我还有一批时间序列。我希望尽可能减少for循环的使用

假设我有一个形状的旋转矩阵(batch_size,3,3)和一个形状张量(batch_size,seq_length,n_坐标,3)。我目前正在做的是一个随时间和批次维度的双for循环,并计算每个3D坐标的点积

代码如下:

#计算转换
对于范围内的t(序号长度):
对于范围内的b(批次尺寸):
X[b,t,:,:]=np.dot(旋转z_矩阵[b],X[b,t,:,:].t)
我已经研究了tensordot和einsum函数,但最后,我不想在一个维度上求点积和,我想在两个维度(批次和时间)上叠加点积

是否有有效的等待来编写等效代码

提前谢谢

您可以使用-


另外,在
np.einsum
中将
optimize
标志设置为
True
以使用BLAS。可以使用广播来完成:

X@rotation_z_matrix.transpose(0,2,1)[:, None, ...]
这(在模拟数据集上)给出了与@Divakar相同的答案

batch_size = 10
seq_length = 8
n_coordinates = 12

X = np.random.randint(0,10,(batch_size, seq_length, n_coordinates, 3))
rotation_z_matrix = np.random.randint(0,10,(batch_size,3,3))

(X@rotation_z_matrix.transpose(0,2,1)[:, None, ...] == np.einsum('ijk,ilmk->ilmj',rotation_z_matrix,X)).all()
# True
但至少在这个例子中,速度要快得多

timeit(lambda: np.einsum('ijk,ilmk->ilmj',rotation_z_matrix,X, optimize=True), number=1000)
# 0.1285447319969535

timeit(lambda: np.einsum('ijk,ilmk->ilmj',rotation_z_matrix,X, optimize=False), number=1000)
# 0.07962286799738649

timeit(lambda: X@rotation_z_matrix.transpose(0,2,1)[:, None, ...], number=1000)
# 0.019039910010178573
请务必注意,设置
optimize
标志实际上会降低
einsum
的速度。(这种情况在我身上经常发生。)

更新:同一示例,但数据转换为float数据类型

timeit(lambda: np.einsum('ijk,ilmk->ilmj',rotation_z_matrix,X, optimize=True), number=1000)
# 0.12346570500812959
timeit(lambda: np.einsum('ijk,ilmk->ilmj',rotation_z_matrix,X, optimize=False), number=1000)
# 0.07575376800377853
timeit(lambda: X@rotation_z_matrix.transpose(0,2,1)[:, None, ...], number=1000)
# 0.027829282989841886

美好的所以,跳到einsum似乎对性能没有意义,嗯。@Divakar这很难预测,不是吗?顺便问一下,您对
优化
有何经验?是的,
optimize
一个我认为适用于经历总和缩减的大型轴的方法。但情况似乎并非如此,至少在较新的NumPy版本中是如此。如果我没记错的话,性能数据可以与matmul进行比较。
timeit(lambda: np.einsum('ijk,ilmk->ilmj',rotation_z_matrix,X, optimize=True), number=1000)
# 0.12346570500812959
timeit(lambda: np.einsum('ijk,ilmk->ilmj',rotation_z_matrix,X, optimize=False), number=1000)
# 0.07575376800377853
timeit(lambda: X@rotation_z_matrix.transpose(0,2,1)[:, None, ...], number=1000)
# 0.027829282989841886