out[i][j][k] = input[index[i][j][k]][j][k] # if dim == 0
out[i][j][k] = input[i][index[i][j][k]][k] # if dim == 1
out[i][j][k] = input[i][j][index[i][j][k]] # if dim == 2
As we "skip" the first dimension (the dimension we want to collect along is 1), the first dimension of the result is implicitly given as the first dimension of the index. That means that the indices hold the second dimension, or the column indices, but not the row indices. Those are given by the indices of the index tensor itself.
例如,这意味着输出将在其第一行中包含 input张量第一行的元素的选择,就像 index张量第一行的第一行所给出的那样。由于列索引是由 [0, 0]给出的,因此我们两次选择输入第一行的第一个元素,结果是 [1, 1]。类似地,结果的第二行的元素是 input张量的第二行的元素对 index张量的第二行进行索引的结果,结果是 [4, 3]。
为了进一步说明这一点,让我们交换示例中的维度:
t = torch.tensor([[1,2],[3,4]])
r = torch.gather(t, 0, torch.tensor([[0,0],[1,0]]))
# r now holds:
# tensor([[ 1, 2],
# [ 3, 2]])
So, each list within index gives us the columns from which to pull the values. The 1st list of the index ([0,0]) is telling us to take to look at the 1st row of the source and take the 1st column of that row (it's zero-indexed) twice, which is [1,1]. The 2nd list of the index ([1,1]) is telling us to take to look at the 2nd row of source and take the 2nd column of that row twice, which is [5,5]. Jumping to the 4th list of the index (index0), which is asking us to look at the 4th and final row of the source, is asking us to take the 1st column (index2) and then the 2nd column (index3) which gives us index4.
这里有一个巧妙的事情: 你的 index的每个列表必须是相同的长度,但他们可能是你喜欢的长度!例如,对于 index = torch.tensor([[0,1,2,1,0],[2,1,0,1,2],[1,2,0,2,1],[1,0,2,0,1]]),source.gather(dim=1, index=index)会给我们
With dim=1 the output always has the same number of rows as the source, although the number of columns will equal the length of the lists in index. The number of lists in index has to equal the number of rows in source. Each value in index, however, needs to be less than the number of columns in source.