Python 为什么通过pytorch张量的循环如此缓慢(与Numpy相比)?
我最近一直在处理图像变换,遇到了这样一种情况:我有一个大数组(形状为100000 x 3),其中每一行代表3D空间中的一个点,如:Python 为什么通过pytorch张量的循环如此缓慢(与Numpy相比)?,python,numpy,pytorch,tensor,Python,Numpy,Pytorch,Tensor,我最近一直在处理图像变换,遇到了这样一种情况:我有一个大数组(形状为100000 x 3),其中每一行代表3D空间中的一个点,如: pnt=[x y z] 我所要做的就是迭代每个点,然后用一个称为T(shape=3x3)的矩阵乘以每个点 使用Numpy进行测试: def变换(pnt_云,T): i=0 对于pnt_云中的pnt: xyz_pnt=np.dot(T,pnt) 如果xyz_pnt[0]>0: arr[i]=xyz_pnt[0] i+=1 返回arr 调用以下代码并计算运行时(使用
pnt=[x y z]
我所要做的就是迭代每个点,然后用一个称为T(shape=3x3)的矩阵乘以每个点
使用Numpy进行测试:
def变换(pnt_云,T):
i=0
对于pnt_云中的pnt:
xyz_pnt=np.dot(T,pnt)
如果xyz_pnt[0]>0:
arr[i]=xyz_pnt[0]
i+=1
返回arr
调用以下代码并计算运行时(使用%时间)将给出输出:
Out[190]: CPU times: user 670 ms, sys: 7.91 ms, total: 678 ms
Wall time: 674 ms
Out[199]: CPU times: user 6.15 s, sys: 28.1 ms, total: 6.18 s
Wall time: 6.09 s
用Pytork张量测试:
导入火炬
张量cld=火炬张量(pnt_云)
张量T=火炬。张量(T)
def变换(pnt_云,T):
深度数组=火炬张量(np.0(pnt_云形状[0]))
i=0
对于pnt_云中的pnt:
xyz_pnt=焊炬.马特穆尔(T,pnt)
如果xyz_pnt[0]>0:
深度数组[i]=xyz\u pnt[0]
i+=1
返回深度数组
调用以下代码并计算运行时(使用%时间)将给出输出:
Out[190]: CPU times: user 670 ms, sys: 7.91 ms, total: 678 ms
Wall time: 674 ms
Out[199]: CPU times: user 6.15 s, sys: 28.1 ms, total: 6.18 s
Wall time: 6.09 s
注意:对torch.jit执行相同操作只会减少2秒
我原以为Pytork张量计算会快得多,因为Pytork在编译阶段分解代码的方式。我错过了什么
除了使用Numba,还有其他更快的方法吗?为什么要使用for循环??
为什么计算3x3点积时只使用结果的第一个元素 您可以在一个
matmul
中完成所有数学运算:
带火炬的。无梯度()
深度数组=torch.matmul(pnt_云,T[:1,:].T)#nx3点3x1->nx1
#因为你只想要非负面的结果
深度数组=火炬。最大值(深度数组,0)
因为您想将runtime与numpy进行比较,所以应该禁用。关于速度,我从PyTorch论坛得到了以下回复:
你是如何将一个形状点(3,)与形状矩阵(4,4)相乘的?尺寸是否不兼容?Pytork是否可能正在为该操作积累梯度?哦,是的,我删除了第四个术语,以使问题更易于理解和概括,但忘记了减小另一个矩阵的大小。我已经编辑了这个问题,感谢您指出Natchiket在上面的问题中,我声明pnt_cld是一个100000 x 3矩阵,即每行为1 x 3。我将每个1 x 3向量乘以T(3x3)。[nx3点3x1->nx3不等于上述过程]我发现的另一件事是张量运算本身不会累积梯度。只有当操作涉及nn.model对象时,才会累积渐变。@dankpenny I更新了代码中有关矩阵大小的注释。因为你只使用结果的一个元素-你可以乘以矩阵的3x1行,而不是整个矩阵。哦,是的,我的坏哈哈!