函数torch.nn.functional.softmax
有两个参数:input
和dim
。根据其文档,softmax操作应用于指定input
的{{1}}的所有切片,并将重新缩放它们,以便元素位于dim
范围内并总和为1。
让输入为:
(0, 1)
假设我想要以下内容,以便该数组中的每个条目都是1:
input = torch.randn((3, 4, 5, 6))
我应该如何应用softmax?
sum = torch.sum(input, dim = 3) # sum's size is (3, 4, 5, 1)
我的直觉告诉我这是最后一个,但我不确定。英语不是我的第一语言,因此使用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
这个词似乎让我感到困惑。
我不清楚“沿着”是什么意思,所以我将使用一个可以澄清事情的例子。假设我们有一个大小的张量(s1,s2,s3,s4),我希望这种情况发生
答案 0 :(得分:10)
答案 1 :(得分:6)
我能想到让你理解的最简单的方法是:假设给你一个形状张量(s1, s2, s3, s4)
并且正如你所提到的那样你希望将最后一个轴上所有条目的总和设为1
sum = torch.sum(input, dim = 3) # input is of shape (s1, s2, s3, s4)
然后你应该将softmax称为:
softmax(input, dim = 3)
为了便于理解,您可以将形状(s1, s2, s3, s4)
的4d张量视为2d张量或形状(s1*s2*s3, s4)
的矩阵。现在,如果您希望矩阵包含总和为1的每一行(轴= 0)或列(轴= 1)中的值,则可以简单地在2d张量上调用softmax
函数,如下所示: / p>
softmax(input, dim = 0) # normalizes values along axis 0
softmax(input, dim = 1) # normalizes values along axis 1
你可以看到史蒂文在answer中提到的例子。
答案 2 :(得分:1)
我不是100%地确定您的问题意味着什么,但是我认为您的困惑仅仅是因为您不了解dim
参数的含义。因此,我将对其进行解释并提供示例。
如果我们有:
m0 = nn.Softmax(dim=0)
这意味着m0
将沿其所接收张量的第零坐标对元素进行规范化。形式上,如果给定张量b
,例如(d0,d1)
,则以下内容将成立:
sum^{d0}_{i0=1} b[i0,i1] = 1, forall i1 \in {0,...,d1}
您可以使用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]])
现在,由于dim=0
意味着如果我们选择任何列i0 \in {0,1}
并对其元素(即行)求和,则要遍历i1
(即遍历行),那么我们应该得到1。检查一下:
>>> b0[:,0].sum()
tensor(1.0000)
>>> b0[:,1].sum()
tensor(1.0000)
符合预期。
请注意,我们确实通过使用torch.sum(b0,dim=0)
“将行汇总”来将所有行的总和设为1,请检查一下:
>>> torch.sum(b0,0)
tensor([1.0000, 1.0000])
我们可以创建一个更复杂的示例,以确保它很清楚。
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)
因此,正如我们预期的那样,如果将沿第一个坐标的所有元素从第一个值到最后一个值求和,我们将得到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]])
也沿维度0表示您沿该维度改变坐标并考虑每个元素。有点像让for循环遍历第一个坐标可以取的值,即
for i0 in range(0,d0):
a[i0,b,c,d]
答案 3 :(得分:0)
让我们考虑二维的例子
x = [[1,2],
[3,4]]
您希望最终结果是
吗?y = [[0.27,0.73],
[0.27,0.73]]
或
y = [[0.12,0.12],
[0.88,0.88]]
如果它是第一个选项,那么你想要dim = 1.如果它是你希望dim = 0的第二个选项。
请注意,第二个示例中的列或第0个维度已标准化,因此它沿着第0个维度进行了规范化。
更新2018-07-10:反映第0个维度是指pytorch中的列。
答案 4 :(得分:0)
import torch
import torch.nn.functional as F
x = torch.tensor([[1, 2], [3, 4]], dtype=torch.float)
s1 = F.softmax(x, dim=0)
tensor([[0.1192, 0.1192],
[0.8808, 0.8808]])
s2 = F.softmax(x, dim=1)
tensor([[0.2689, 0.7311],
[0.2689, 0.7311]])
torch.sum(s1, dim=0)
tensor([1., 1.])
torch.sum(s2, dim=1)
tensor([1., 1.])