Pytorch softmax:使用什么维度?
Pytorch softmax: What dimension to use?
函数torch.nn.functional.softmax
有两个参数:input
和dim
。根据其文档,softmax 操作应用于 input
沿指定 dim
的所有切片,并将重新缩放它们,以便元素位于 (0, 1)
范围内并且总和为 1。
设输入为:
input = torch.randn((3, 4, 5, 6))
假设我想要以下内容,以便该数组中的每个条目都是 1:
sum = torch.sum(input, dim = 3) # sum's size is (3, 4, 5, 1)
我应该如何应用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
我的直觉告诉我那是最后一个,但我不确定。英语不是我的第一语言,因此 along
这个词的使用让我感到困惑。
我不是很清楚 "along" 是什么意思,所以我将使用一个可以澄清事情的例子。假设我们有一个大小为 (s1, s2, s3, s4) 的张量,我希望它发生
让我们考虑二维的例子
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。
请注意,在第二个示例中对列或第零维进行了规范化,因此它沿第零维进行了规范化。
2018-07-10 更新:反映第零维指的是 pytorch 中的列。
我能想到的让您理解的最简单方法是:假设给定了一个形状为 (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 张量视为形状为 (s1*s2*s3, s4)
的 2d 张量或矩阵。现在,如果您希望矩阵在每行 (axis=0) 或列 (axis=1) 中包含总和为 1 的值,那么,您可以简单地在 2d 张量上调用 softmax
函数,如下所示:
softmax(input, dim = 0) # normalizes values along axis 0
softmax(input, dim = 1) # normalizes values along axis 1
你可以看看史蒂文在他的中提到的例子。
不正确。请参阅下面的快照。其实是相反的方式。
图片转录为代码:
>>> x = torch.tensor([[1,2],[3,4]],dtype=torch.float)
>>> F.softmax(x,dim=0)
tensor([[0.1192, 0.1192],
[0.8808, 0.8808]])
>>> F.softmax(x,dim=1)
tensor([[0.2689, 0.7311],
[0.2689, 0.7311]])
我不是 100% 确定你的问题是什么意思,但我认为你的困惑只是因为你不明白 dim
参数的意思。因此,我将对其进行解释并提供示例。
如果我们有:
m0 = nn.Softmax(dim=0)
这意味着 m0
将沿它接收的张量的第零坐标对元素进行归一化。正式地,如果给定一个大小为 (d0,d1)
的张量 b
,则以下内容为真:
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)
符合预期。
请注意,我们确实通过 "summing out the rows" 和 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]
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.])
想一想 softmax 试图实现的目标。它输出一种结果相对于另一种结果的概率。假设您正在尝试预测两个结果:是 A 还是 B。如果 p(A) 大于 p(B),那么下一步是将结果转换为布尔值(即如果 p,则结果将是 A (A) > 50% or B if p(B) > 50% 因为我们处理的是概率,它们应该加起来为 1。
因此,您想要的是每行的总和概率为 1。因此,您指定 dim=1 或 row sum
另一方面,如果您的模型旨在预测两个以上的变量,则输出张量将类似于 [p(a), p(b), p(c)...p(i)]
这里重要的是 p(a) + p(b) + p(c) +...p(i) = 1
那么你会使用 dim = 0
这完全取决于您如何定义输出层。
函数torch.nn.functional.softmax
有两个参数:input
和dim
。根据其文档,softmax 操作应用于 input
沿指定 dim
的所有切片,并将重新缩放它们,以便元素位于 (0, 1)
范围内并且总和为 1。
设输入为:
input = torch.randn((3, 4, 5, 6))
假设我想要以下内容,以便该数组中的每个条目都是 1:
sum = torch.sum(input, dim = 3) # sum's size is (3, 4, 5, 1)
我应该如何应用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
我的直觉告诉我那是最后一个,但我不确定。英语不是我的第一语言,因此 along
这个词的使用让我感到困惑。
我不是很清楚 "along" 是什么意思,所以我将使用一个可以澄清事情的例子。假设我们有一个大小为 (s1, s2, s3, s4) 的张量,我希望它发生
让我们考虑二维的例子
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。
请注意,在第二个示例中对列或第零维进行了规范化,因此它沿第零维进行了规范化。
2018-07-10 更新:反映第零维指的是 pytorch 中的列。
我能想到的让您理解的最简单方法是:假设给定了一个形状为 (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 张量视为形状为 (s1*s2*s3, s4)
的 2d 张量或矩阵。现在,如果您希望矩阵在每行 (axis=0) 或列 (axis=1) 中包含总和为 1 的值,那么,您可以简单地在 2d 张量上调用 softmax
函数,如下所示:
softmax(input, dim = 0) # normalizes values along axis 0
softmax(input, dim = 1) # normalizes values along axis 1
你可以看看史蒂文在他的
图片转录为代码:
>>> x = torch.tensor([[1,2],[3,4]],dtype=torch.float)
>>> F.softmax(x,dim=0)
tensor([[0.1192, 0.1192],
[0.8808, 0.8808]])
>>> F.softmax(x,dim=1)
tensor([[0.2689, 0.7311],
[0.2689, 0.7311]])
我不是 100% 确定你的问题是什么意思,但我认为你的困惑只是因为你不明白 dim
参数的意思。因此,我将对其进行解释并提供示例。
如果我们有:
m0 = nn.Softmax(dim=0)
这意味着 m0
将沿它接收的张量的第零坐标对元素进行归一化。正式地,如果给定一个大小为 (d0,d1)
的张量 b
,则以下内容为真:
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)
符合预期。
请注意,我们确实通过 "summing out the rows" 和 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]
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.])
想一想 softmax 试图实现的目标。它输出一种结果相对于另一种结果的概率。假设您正在尝试预测两个结果:是 A 还是 B。如果 p(A) 大于 p(B),那么下一步是将结果转换为布尔值(即如果 p,则结果将是 A (A) > 50% or B if p(B) > 50% 因为我们处理的是概率,它们应该加起来为 1。 因此,您想要的是每行的总和概率为 1。因此,您指定 dim=1 或 row sum
另一方面,如果您的模型旨在预测两个以上的变量,则输出张量将类似于 [p(a), p(b), p(c)...p(i)] 这里重要的是 p(a) + p(b) + p(c) +...p(i) = 1 那么你会使用 dim = 0
这完全取决于您如何定义输出层。