tensor_scatter_add算子异同点
技术背景在MindSpore的ops下实现了一个tensor_scatter_add算子。这个算子的作用为,例如给定一个shape为(1,2,3,4)的原始tensor,因为这个tensor有4个维度,所以我们每次去提取一个tensor元素的时候,就需要4个索引。那么假如说我们要提取这个tensor中的5个元素,那么需要用到的索引tensor的shape应该为(5,4)。这样一来就可以提取得到5个元素,然后做一个add的操作,给定一个目标的tensor,它的shape为(5,),我们就可以把这个目标tensor按照索引tensor,加到原始的tensor里面去,这就是tensor_scatter_add算子的作用。但是在PyTorch中没有这个算子的实现,只有scatter_add和index_add,但是这三个算子的作用是完全不一样的,接下来用代码示例演示一下。
代码实现
首先看一个mindspore的tensor_scatter_add算子,其官方文档的介绍是这样的:
以下是一个代码实现的示例:
In : import mindspore as ms
In : arr=ms.numpy.zeros((1,2,3,4),dtype=ms.float32)
In : idx=ms.numpy.zeros((5,4),dtype=ms.int64)
In : src=ms.numpy.ones((5,),dtype=ms.float32)
In : res=ms.ops.tensor_scatter_add(arr,idx,src)
In : res.sum()
Out: Tensor(shape=[], dtype=Float32, value= 5)
In : res
Out:
Tensor(shape=, dtype=Float32, value=
[[[[ 5.00000000e+00,0.00000000e+00,0.00000000e+00,0.00000000e+00],
[ 0.00000000e+00,0.00000000e+00,0.00000000e+00,0.00000000e+00],
[ 0.00000000e+00,0.00000000e+00,0.00000000e+00,0.00000000e+00]],
[[ 0.00000000e+00,0.00000000e+00,0.00000000e+00,0.00000000e+00],
[ 0.00000000e+00,0.00000000e+00,0.00000000e+00,0.00000000e+00],
[ 0.00000000e+00,0.00000000e+00,0.00000000e+00,0.00000000e+00]]]])在MindSpore中该算子支持的是挺好的,因为在索引里面其实存在重复索引,并行计算的话可能存在race condition的问题,而MindSpore中还是可以做到正确的加和。在PyTorch中有一个scatter_add算子,但是跟MindSpore里面的tensor_scatter_add完全是两个不一样的算子,以下是一个示例:
In : import torch as tc
In : arr=tc.zeros((1,2,3,4),dtype=tc.float32)
In : idx=tc.zeros((5,4),dtype=tc.int64)
In : src=tc.ones((5,),dtype=tc.float32)
In : res=tc.scatter_add(arr,0,idx,src)
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
Cell In, line 1
----> 1 res=tc.scatter_add(arr,0,idx,src)
RuntimeError: Index tensor must have the same number of dimensions as self tensor他这个scatter_add算子就不是为了这种场景而设计的。
还有另外一个index_add,但是用法也不太相似:
不过如果想要用PyTorch实现这个功能的话,也不是没有办法。还是以这个例子来说,因为原始tensor有4个维度,所以索引到每一个元素需要4个索引编号。在PyTorch中可以直接这样操作(不建议!不建议!不建议!):
In : arr,idx[:,1],idx[:,2],idx[:,3]]+=src
In : arr.sum()
Out: tensor(1.)
In : arr
Out:
tensor([[[,
,
],
[,
,
]]])这个例子就可以看出来,直接使用索引进行加和的话,结果是不对的。存在相同索引的情况下,不同的操作之间有可能相互覆盖。所以,非常的不建议这么操作,除非能够确保索引tensor都是唯一的。
总结概要
本文介绍了MindSpore中的tensor_scatter_add算子的用法,可以对一个多维的tensor在指定的index上面进行加和操作。在PyTorch中虽然也有一个叫scatter_add的算子,但是本质上来说两者是完全不一样的操作。
版权声明
本文首发链接为:https://www.cnblogs.com/dechinphy/p/tensor-scatter-add.html
作者ID:DechinPhy
更多原著文章:https://www.cnblogs.com/dechinphy/
请博主喝咖啡:https://www.cnblogs.com/dechinphy/gallery/image/379634.html
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页:
[1]