问题描述
torch.flatten()
和 torch.nn.Flatten()
之间有什么区别?
解决方法
PyTorch 提供三种形式的扁平化
-
作为张量方法(oop style)
torch.Tensor.flatten
直接应用于张量:produto = gets.chomp.upcase.to_sym
。 -
作为函数(函数形式)
torch.flatten
应用为:x.flatten()
。 -
作为一个模块(层
torch.flatten(x)
)nn.Flatten()
。通常用于模型定义。
所有三个都是相同的并共享相同的实现,唯一的区别是 nn.Module
默认将 nn.Flatten
设置为 start_dim
以避免展平第一个轴(通常是批处理轴)。而其他两个从 1
展平到 axis=0
- 即整个张量 - 如果没有给出参数。
您可以将 torch.flatten()
的工作视为简单地对张量进行展平操作,不附加任何字符串。你给一个张量,它变平,然后返回它。就是这样。
相反,nn.Flatten()
要复杂得多(即,它是一个神经网络层)。作为面向对象,它继承自 nn.Module
,尽管它 internally uses the plain tensor.flatten() OP in the forward()
method 用于展平张量。您可以将其更像是 torch.flatten()
上的语法糖。
重要区别:一个显着的区别是 torch.flatten()
总是 返回一个 1D 张量作为结果,前提是输入至少为 1D 或更大,而nn.Flatten()
总是 返回一个 2D 张量,前提是输入至少是 2D 或更大(以 1D 张量作为输入,它会抛出一个 IndexError)。
比较:
-
torch.flatten()
是一个 API,而nn.Flatten()
是一个神经网络层。 -
torch.flatten()
是一个 python 函数,而nn.Flatten()
是一个 python 类。 -
因为以上几点,
nn.Flatten()
comes with lot of methods and attributes -
torch.flatten()
可以在野外使用(例如,用于简单的张量 OP),而nn.Flatten()
预计将在nn.Sequential()
块中用作层之一。 -
torch.flatten()
没有关于计算图的信息,除非它被卡在其他图形感知块中(tensor.requires_grad
标志设置为True
)而nn.Flatten()
始终由 autograd 跟踪。 -
torch.flatten()
不能接受和处理(例如,线性/conv1D)层作为输入,而nn.Flatten()
主要用于处理这些神经网络层。 -
torch.flatten()
和nn.Flatten()
都返回 views 以输入张量。因此,对结果的任何修改也会影响输入张量。 (见下方代码)
代码演示:
# input tensors to work with
In [109]: t1 = torch.arange(12).reshape(3,-1)
In [110]: t2 = torch.arange(12,24).reshape(3,-1)
In [111]: t3 = torch.arange(12,36).reshape(3,2,-1) # 3D tensor
用 torch.flatten()
展平:
In [113]: t1flat = torch.flatten(t1)
In [114]: t1flat
Out[114]: tensor([ 0,1,3,4,5,6,7,8,9,10,11])
# modification to the flattened tensor
In [115]: t1flat[-1] = -1
# input tensor is also modified; thus flattening is a view.
In [116]: t1
Out[116]:
tensor([[ 0,3],[ 4,7],[ 8,-1]])
用 nn.Flatten()
展平:
In [123]: nnfl = nn.Flatten()
In [124]: t3flat = nnfl(t3)
# note that the result is 2D,as opposed to 1D with torch.flatten
In [125]: t3flat
Out[125]:
tensor([[12,13,14,15,16,17,18,19],[20,21,22,23,24,25,26,27],[28,29,30,31,32,33,34,35]])
# modification to the result
In [126]: t3flat[-1,-1] = -1
# input tensor also modified. Thus,flattened result is a view.
In [127]: t3
Out[127]:
tensor([[[12,15],[16,19]],[[20,23],[24,27]],[[28,31],[32,-1]]])
花絮:torch.flatten()
是nn.Flatten()
及其brethren nn.Unflatten()
的前身,因为它从一开始就存在。然后,有一个合法的 use-case for nn.Flatten()
,因为这是几乎所有 ConvNet 的共同要求(就在 softmax 之前或其他地方)。所以它后来被添加到 PR #22245 中。
最近还有 proposals to use nn.Flatten()
in ResNets 用于模型手术。