图解PyTorch中的torch.gather函数和 scatter 函数

前言

torch.gather在目前基于 transformer or query based 的目标检测中,在最后获取目标结果时,经常用到。

这里记录下用法,防止之后又忘了。

介绍

torch.gather

官方文档对torch.gather()的定义非常简洁

定义:从原tensor中获取指定dim和指定index的数据

看到这个核心定义,我们很容易想到gather()的基本想法其实就类似从完整数据中按索引取值般简单,比如下面从列表中按索引取值

python 复制代码
lst = [1, 2, 3, 4, 5]
value = lst[2]  # value = 3
value = lst[2:4]  # value = [3, 4]

上面的取值例子是取单个值或具有逻辑顺序序列的例子,而对于深度学习常用的批量tensor数据来说,我们的需求可能是选取其中多个且乱序的值,此时gather()就是一个很好的tool,它可以帮助我们从批量tensor中取出指定乱序索引下的数据,因此其用途如下

用途:方便从批量tensor中获取指定索引下的数据,该索引是高度自定义化的,可乱序的

示例

我们找个3x3的二维矩阵做个实验

python 复制代码
import torch

tensor_0 = torch.arange(3, 12).view(3, 3)
print(tensor_0)

输出结果

python 复制代码
tensor([[ 3,  4,  5],
        [ 6,  7,  8],
        [ 9, 10, 11]])

2.1 输入行向量index,并替换行索引(dim=0)

python 复制代码
index = torch.tensor([[2, 1, 0]])
tensor_1 = tensor_0.gather(0, index)
print(tensor_1)

输出结果

python 复制代码
tensor([[9, 7, 5]])

过程如图所示

2.2 输入行向量index,并替换列索引(dim=1)

python 复制代码
index = torch.tensor([[2, 1, 0]])
tensor_1 = tensor_0.gather(1, index)
print(tensor_1)

输出结果

python 复制代码
tensor([[5, 4, 3]])

过程如图所示

2.3 输入列向量index,并替换列索引(dim=1)

python 复制代码
index = torch.tensor([[2, 1, 0]]).t()
tensor_1 = tensor_0.gather(1, index)
print(tensor_1)

输出结果

python 复制代码
tensor([[5],
        [7],
        [9]])

过程如图所示

scatter

基本是 gather 的反过程,是将数据添加进去,

doc:https://pytorch.org/docs/stable/generated/torch.Tensor.scatter_.html#torch.Tensor.scatter_

python 复制代码
self[index[i][j][k]][j][k] = src[i][j][k]  # if dim == 0
self[i][index[i][j][k]][k] = src[i][j][k]  # if dim == 1
self[i][j][index[i][j][k]] = src[i][j][k]  # if dim == 2

example:

python 复制代码
>>> src = torch.arange(1, 11).reshape((2, 5))
>>> src
tensor([[ 1,  2,  3,  4,  5],
        [ 6,  7,  8,  9, 10]])
>>> index = torch.tensor([[0, 1, 2, 0]])
>>> torch.zeros(3, 5, dtype=src.dtype).scatter_(0, index, src)
tensor([[1, 0, 0, 4, 0],
        [0, 2, 0, 0, 0],
        [0, 0, 3, 0, 0]])
>>> index = torch.tensor([[0, 1, 2], [0, 1, 4]])
>>> torch.zeros(3, 5, dtype=src.dtype).scatter_(1, index, src)
tensor([[1, 2, 3, 0, 0],
        [6, 7, 0, 0, 8],
        [0, 0, 0, 0, 0]])

>>> torch.full((2, 4), 2.).scatter_(1, torch.tensor([[2], [3]]),
...            1.23, reduce='multiply')
tensor([[2.0000, 2.0000, 2.4600, 2.0000],
        [2.0000, 2.0000, 2.0000, 2.4600]])
>>> torch.full((2, 4), 2.).scatter_(1, torch.tensor([[2], [3]]),
...            1.23, reduce='add')
tensor([[2.0000, 2.0000, 3.2300, 2.0000],
        [2.0000, 2.0000, 2.0000, 3.2300]])

具体过程见 gather 的就好~一摸一样,一个获取,一个填入。

相关推荐
Null箘4 分钟前
从零创建一个 Django 项目
后端·python·django
云空8 分钟前
《解锁 Python 数据挖掘的奥秘》
开发语言·python·数据挖掘
玖年40 分钟前
Python re模块 用法详解 学习py正则表达式看这一篇就够了 超详细
python
岑梓铭44 分钟前
(CentOs系统虚拟机)Standalone模式下安装部署“基于Python编写”的Spark框架
linux·python·spark·centos
边缘计算社区1 小时前
首个!艾灵参编的工业边缘计算国家标准正式发布
大数据·人工智能·边缘计算
游客5201 小时前
opencv中的各种滤波器简介
图像处理·人工智能·python·opencv·计算机视觉
一位小说男主1 小时前
编码器与解码器:从‘乱码’到‘通话’
人工智能·深度学习
Eric.Lee20211 小时前
moviepy将图片序列制作成视频并加载字幕 - python 实现
开发语言·python·音视频·moviepy·字幕视频合成·图像制作为视频
Dontla1 小时前
vscode怎么设置anaconda python解释器(anaconda解释器、vscode解释器)
ide·vscode·python
深圳南柯电子1 小时前
深圳南柯电子|电子设备EMC测试整改:常见问题与解决方案
人工智能