PyTorch 中的参数约定

Argument convention in PyTorch

我是 PyTorch 的新手,在浏览示例时,我注意到有时函数在接受参数时有不同的约定。例如 transforms.Compose 接收一个列表作为其参数:

transform=transforms.Compose([  # Here we pass a list of elements
   transforms.ToTensor(), 
   transforms.Normalize(
      (0.4915, 0.4823, 0.4468), 
      (0.2470, 0.2435, 0.2616)
   )
]))

同时,其他函数单独接收参数(即不在列表中)。例如 torch.nn.Sequential:

torch.nn.Sequential(  # Here we pass individual elements
    torch.nn.Linear(1, 4),
    torch.nn.Tanh(),
    torch.nn.Linear(4, 1)
)

这是我在学习过程中经常犯的打字错误。

我想知道我们是否在暗示什么:

还是只是投稿人的喜好,应该原封不动的记住?

更新 1: 请注意,我并不是说哪种格式更好。我只是抱怨缺乏一致性。当然(正如 Ivan 在他的回答中所说)如果有充分的理由(例如 transforms.Normalize),遵循一种格式是完全合理的。但如果没有,那么我会投票支持一致性。

这不是约定,而是设计决定。

是,torch.nn.Sequential (source) receives individual items, whereas torchvision.transforms.Compose (source) 收到单个 list 项目。这些是任意的设计选择。我相信 PyTorch 和 Torchvision 由不同的人群维护,这或许可以解释差异。有人可能会争辩说,将输入作为列表传递更连贯,因为它的长度是可变的,这是更传统的编程语言(如 C++ 和 Java 中使用的方法。另一方面,您可能会争辩说,将它们作为一系列单独的参数传递会更具可读性,例如 Python.

这样的语言

在这种特殊情况下,我们会

>>> fn1([element_a, element_b, element_c]) # single list

>>> fn2(element_a, element_b, element_c) # separate args

它的实现类似于:

def fn1(elements):
    pass

与使用 star argument:

def fn2(*elements):
    pass

然而,这并不总是由设计决定,有时实施很明确。例如,当函数有其他参数(无论它们是位置参数还是关键字参数)时,最好使用 list 方法。在这种情况下,将其实现为 fn1 而不是 fn2 更有意义。在这里,我给出了第二个带有关键字参数的示例。查看两种情况下第一组参数的接口差异:

>>> fn1([elemen_a, element_b], option_1=True, option_2=True) # list

>>> fn2(element_a, element_b, option_1=True, option_2=True) # separate

它的函数头看起来像这样:

def fn1(elements, option_1=False, option_2=False)
   pass

而另一个将在后台使用 star argument

def fn2(*elements, option_1=False, option_2=False)
   pass

如果参数位于星形参数之后,它实际上会强制用户将其用作关键字参数...

提到这一点,您可以查看 ComposeSequential 的源代码,您会注意到两者都只需要一个元素列表,之后没有其他参数。所以在这种情况下,可能更倾向于使用 Sequential 的方法,使用 star 参数......但这只是个人偏好!