Python PyTorch torch.max在多个维度上

Python PyTorch torch.max在多个维度上,python,multidimensional-array,max,pytorch,tensor,Python,Multidimensional Array,Max,Pytorch,Tensor,像张量:x.shape=[3,2,2] 导入火炬 x=张量([ [[-0.3000, -0.2926],[-0.2705, -0.2632]], [[-0.1821, -0.1747],[-0.1526, -0.1453]], [[-0.0642, -0.0568],[-0.0347, -0.0274]] ]) 我需要在2维和3维上取.max()。我希望像这样的[-0.2632,-0.1453,-0.0274]作为输出。我尝试使用:x.max(dim=(1,2)),但这会导致错误。现在,您可以

像张量:
x.shape=[3,2,2]

导入火炬
x=张量([
[[-0.3000, -0.2926],[-0.2705, -0.2632]],
[[-0.1821, -0.1747],[-0.1526, -0.1453]],
[[-0.0642, -0.0568],[-0.0347, -0.0274]]
])
我需要在2维和3维上取
.max()
。我希望像这样的
[-0.2632,-0.1453,-0.0274]
作为输出。我尝试使用:
x.max(dim=(1,2))
,但这会导致错误。

现在,您可以这样做了。8月28日发布,现在可在夜间发布

只需使用:

导入火炬
x=张量([
[[-0.3000, -0.2926],[-0.2705, -0.2632]],
[[-0.1821, -0.1747],[-0.1526, -0.1453]],
[[-0.0642, -0.0568],[-0.0347, -0.0274]]
])
打印(torch.amax(x,dim=(1,2)))
#输出:
#>>>张量([-0.2632,-0.1453,-0.0274])

原始答案

截至今天(2020年4月11日),在PyTorch中无法对多个维度执行
.min()
.max()
。有一个关于它的问题,你可以遵循,看看它是否得到了实施。在您的情况下,解决方法是:

导入火炬
x=张量([
[[-0.3000, -0.2926],[-0.2705, -0.2632]],
[[-0.1821, -0.1747],[-0.1526, -0.1453]],
[[-0.0642, -0.0568],[-0.0347, -0.0274]]
])
打印(x.view(x.size(0),-1).max(dim=-1))
#输出:
#>>>值=张量([-0.2632,-0.1453,-0.0274]),
#>>>指数=张量([3,3,3]))
因此,如果您只需要以下值:
x.view(x.size(0),-1).max(dim=-1).values

如果
x
不是连续张量,则
.view()
将失败。在这种情况下,您应该使用
.reformate()


2020年8月26日更新

此功能正在中实现,这些函数将被称为
amin
amax
。它们将只返回值。这可能很快就要合并了,所以当您阅读本文时,您可能可以在夜间构建中访问这些函数:)祝您玩得开心。

虽然解决了这个具体问题,但我认为添加一些解释可能会帮助大家了解这里使用的技巧,以便它可以适用于(m)任何其他尺寸

让我们首先检查输入张量的形状
x

In [58]: x.shape   
Out[58]: torch.Size([3, 2, 2])
因此,我们有一个形状为
(3,2,2)
的三维张量。现在,根据OP的问题,我们需要计算第一维和第二维张量值的最大值。在撰写本文时,
torch.max()
dim
参数仅支持
int
。所以,我们不能使用元组。因此,我们将使用以下技巧,我称之为

展平和最大技巧:由于我们希望在第一维度和第二维度上计算
Max
,我们将把这两个维度展平为一个维度,并保持第0维度不变。这正是我们所做的:

In [61]: x.flatten().reshape(x.shape[0], -1).shape   
Out[61]: torch.Size([3, 4])   # 2*2 = 4
现在我们把三维张量压缩成二维张量(即矩阵)

现在,我们只需在第一个维度上应用
max
(即,在本例中,第一个维度也是最后一个维度),因为展平的维度位于该维度中

In [65]: x.flatten().reshape(x.shape[0], -1).max(dim=1)    # or: `dim = -1`
Out[65]: 
torch.return_types.max(
values=tensor([-0.2632, -0.1453, -0.0274]),
indices=tensor([3, 3, 3]))
我们在合成张量中得到了3个值,因为矩阵中有3行


另一方面,如果要计算第0维和第1维上的
max
,则需要执行以下操作:

In [80]: x.flatten().reshape(-1, x.shape[-1]).shape 
Out[80]: torch.Size([6, 2])    # 3*2 = 6

In [79]: x.flatten().reshape(-1, x.shape[-1]) 
Out[79]: 
tensor([[-0.3000, -0.2926],
        [-0.2705, -0.2632],
        [-0.1821, -0.1747],
        [-0.1526, -0.1453],
        [-0.0642, -0.0568],
        [-0.0347, -0.0274]])
现在,我们可以简单地在第0维上应用
max
,因为这是我们展平的结果。((同样,从我们的原始形状(
3,2,2
)来看,在对前两个维度进行max之后,我们应该得到两个值作为结果。)

同样,您可以将此方法应用于多维和其他缩减功能,如
min



注意:我遵循基于0的维度(
0,1,2,3,
)的术语,只是为了与PyTorch的用法和代码保持一致。

如果您只想使用
torch.max()
函数来获取2D张量中最大项的索引,您可以执行以下操作:

max_i_vals, max_i_indices = torch.max(x, 0)
print('max_i_vals, max_i_indices: ', max_i_vals, max_i_indices)
max_j_index = torch.max(max_i_vals, 0)[1]
print('max_j_index: ', max_j_index)
max_index = [max_i_indices[max_j_index], max_j_index]
print('max_index: ', max_index)
在测试过程中,为我打印了上述内容:

max_i_vals: tensor([0.7930, 0.7144, 0.6985, 0.7349, 0.9162, 0.5584, 1.4777, 0.8047, 0.9008, 1.0169, 0.6705, 0.9034, 1.1159, 0.8852, 1.0353], grad_fn=\<MaxBackward0>)   
max_i_indices: tensor([ 5,  8, 10,  6, 13, 14,  5,  6,  6,  6, 13,  4, 13, 13, 11])  
max_j_index:  tensor(6)  
max_index:  [tensor(5), tensor(6)]

这种一行程序不仅可以在不需要对代码进行调整的情况下使用N维张量,而且比我上面写的方法(至少2:1的比率)快得多,比公认的答案(大约3:2的比率)快得多根据我的基准测试。

谢谢。它可以工作,但需要使用“重塑安装视图”,以避免我的测试中出现错误case@iGero好的,我会在答案上加上这个注释以防万一:)很高兴它能帮上忙我在pytorch版本1.5.0和1.6.0上试过这个,但是没有方法
torch.amax
。你能证实这一点吗?还是我做错了什么?@zwep正如我在回答中所说的,这个功能目前在夜间版本中可用。因此,如果您想访问amax,或者等到下一个稳定版本,即1.7.0,您必须升级到它。@Berriel啊,对不起,我不知道哪个版本与夜间版本相关。虽然我不知道你是否能在这种情况下谈论一个版本哦,说清楚一点。请您具体说明什么是“展平结果”?我将不胜感激,谢谢!展平总是返回一个1D大小的张量,该张量是原始形状中各个尺寸的乘积(即,这里的3*2*2与张量
x
)我更新了我的答案,因为我提到的PR现在已合并,并且该功能在夜间版本中可用。请参阅下面我的更新答案。
max_i_vals, max_i_indices = torch.max(x, 0)
print('max_i_vals, max_i_indices: ', max_i_vals, max_i_indices)
max_j_index = torch.max(max_i_vals, 0)[1]
print('max_j_index: ', max_j_index)
max_index = [max_i_indices[max_j_index], max_j_index]
print('max_index: ', max_index)
max_i_vals: tensor([0.7930, 0.7144, 0.6985, 0.7349, 0.9162, 0.5584, 1.4777, 0.8047, 0.9008, 1.0169, 0.6705, 0.9034, 1.1159, 0.8852, 1.0353], grad_fn=\<MaxBackward0>)   
max_i_indices: tensor([ 5,  8, 10,  6, 13, 14,  5,  6,  6,  6, 13,  4, 13, 13, 11])  
max_j_index:  tensor(6)  
max_index:  [tensor(5), tensor(6)]
x = (x==torch.max(x)).nonzero()