Pytorch softmax:使用什么尺寸?

Jad*_*mas 13 python pytorch

该函数torch.nn.functional.softmax有两个参数:inputdim.根据其文档,softmax操作应用于input指定的所有切片,dim并将重新缩放它们,使元素位于范围内(0, 1)并总和为1.

让输入为:

input = torch.randn((3, 4, 5, 6))
Run Code Online (Sandbox Code Playgroud)

假设我想要以下内容,以便该数组中的每个条目都是1:

sum = torch.sum(input, dim = 3) # sum's size is (3, 4, 5, 1)
Run Code Online (Sandbox Code Playgroud)

我应该如何应用softmax?

softmax(input, dim = 0) # Way Number 0
softmax(input, dim = 1) # Way Number 1
softmax(input, dim = 2) # Way Number 2
softmax(input, dim = 3) # Way Number 3
Run Code Online (Sandbox Code Playgroud)

我的直觉告诉我这是最后一个,但我不确定.英语不是我的第一语言,由于这个原因,使用这个词along对我来说似乎很困惑.

我不太清楚"沿"的意思,所以我将使用一个可以澄清事物的例子.假设我们有一个大小的张量(s1,s2,s3,s4),我希望这发生

sww*_*sww 17

在此输入图像描述

史蒂文上面的回答是不正确的.请参阅下面的快照.这实际上是相反的方式.

  • 我认为最好将此图像添加为可以搜索和复制粘贴的实际代码。 (4认同)

Was*_*mad 8

我能想到的让你理解的最简单的方法是:假设你有一个形状的张量,(s1, s2, s3, s4)正如你所提到的,你希望将最后一个轴上所有条目的总和设为1.

sum = torch.sum(input, dim = 3) # input is of shape (s1, s2, s3, s4)
Run Code Online (Sandbox Code Playgroud)

然后你应该将softmax称为:

softmax(input, dim = 3)
Run Code Online (Sandbox Code Playgroud)

为了便于理解,您可以将4d张量的形状(s1, s2, s3, s4)视为2d张量或形状矩阵(s1*s2*s3, s4).现在,如果您希望矩阵在每行(轴= 0)或列(轴= 1)中包含总和为1的值,则可以简单地softmax在2d张量上调用该函数,如下所示:

softmax(input, dim = 0) # normalizes values along axis 0
softmax(input, dim = 1) # normalizes values along axis 1
Run Code Online (Sandbox Code Playgroud)

你可以看到史蒂文在他的回答中提到的例子.

  • @CharlieParker 这意味着采用最后一个维度 (3认同)

Ste*_*ven 6

让我们考虑二维的例子

x = [[1,2],
    [3,4]]
Run Code Online (Sandbox Code Playgroud)

你希望你的最终结果是

y = [[0.27,0.73],
    [0.27,0.73]]
Run Code Online (Sandbox Code Playgroud)

或者

y = [[0.12,0.12],
    [0.88,0.88]]
Run Code Online (Sandbox Code Playgroud)

如果是第一个选项,则需要 dim = 1。如果是第二个选项,则需要 dim = 0。

请注意,在第二个示例中,列或第零维度已标准化,因此它是沿第零维度标准化的。

2018-07-10 更新:反映第 0 维是指 pytorch 中的列。

  • 请参阅下面的正确答案。以上是不正确的@Steven (4认同)

Cha*_*ker 6

我不是 100% 确定你的问题是什么意思,但我认为你的困惑只是因为你不明白dim参数的含义。所以我将解释它并提供示例。

如果我们有:

m0 = nn.Softmax(dim=0)
Run Code Online (Sandbox Code Playgroud)

这意味着它将m0沿着它接收到的张量的第零坐标对元素进行标准化。形式上,如果给定一个b大小的张量(d0,d1),则以下内容将为真:

sum^{d0}_{i0=1} b[i0,i1] = 1, forall i1 \in {0,...,d1}
Run Code Online (Sandbox Code Playgroud)

您可以使用 Pytorch 示例轻松检查这一点:

>>> b = torch.arange(0,4,1.0).view(-1,2)
>>> b 
tensor([[0., 1.],
        [2., 3.]])
>>> m0 = nn.Softmax(dim=0) 
>>> b0 = m0(b)
>>> b0 
tensor([[0.1192, 0.1192],
        [0.8808, 0.8808]])
Run Code Online (Sandbox Code Playgroud)

现在,既然dim=0意味着遍历i0 \in {0,1}(即遍历行),如果我们选择任何列i1并将其元素(即行)相加,那么我们应该得到 1。检查一下:

>>> b0[:,0].sum()
tensor(1.0000)
>>> b0[:,1].sum()
tensor(1.0000)
Run Code Online (Sandbox Code Playgroud)

正如预期的那样。

请注意,我们确实通过使用“对行求和”来使所有行总和为 1 torch.sum(b0,dim=0),请检查一下:

>>> torch.sum(b0,0)
tensor([1.0000, 1.0000])
Run Code Online (Sandbox Code Playgroud)

我们可以创建一个更复杂的示例以确保它确实清晰。

a = torch.arange(0,24,1.0).view(-1,3,4)
>>> a
tensor([[[ 0.,  1.,  2.,  3.],
         [ 4.,  5.,  6.,  7.],
         [ 8.,  9., 10., 11.]],

        [[12., 13., 14., 15.],
         [16., 17., 18., 19.],
         [20., 21., 22., 23.]]])
>>> a0 = m0(a)
>>> a0[:,0,0].sum()
tensor(1.0000)
>>> a0[:,1,0].sum()
tensor(1.0000)
>>> a0[:,2,0].sum()
tensor(1.0000)
>>> a0[:,1,0].sum()
tensor(1.0000)
>>> a0[:,1,1].sum()
tensor(1.0000)
>>> a0[:,2,3].sum()
tensor(1.0000)
Run Code Online (Sandbox Code Playgroud)

因此,正如我们所期望的,如果我们将第一个坐标上从第一个值到最后一个值的所有元素相加,我们会得到 1。因此,所有内容都沿着第一个维度(或第一个坐标i0)进行标准化。

>>> torch.sum(a0,0)
tensor([[1.0000, 1.0000, 1.0000, 1.0000],
        [1.0000, 1.0000, 1.0000, 1.0000],
        [1.0000, 1.0000, 1.0000, 1.0000]])
Run Code Online (Sandbox Code Playgroud)

此外,沿维度 0 表示您沿该维度改变坐标并考虑每个元素。有点像有一个 for 循环遍历第一个坐标可以采用的值,即

for i0 in range(0,d0):
    a[i0,b,c,d]
Run Code Online (Sandbox Code Playgroud)