为什么 model.forward(input) 和 model(input) 之间有不同的输出

Why there are different output between model.forward(input) and model(input)

我正在使用 pytorch 构建一个像 VGG16 这样的简单模型,并且我在我的模型中重载了函数 forward

我发现每个人都倾向于使用 model(input) 而不是 model.forward(input) 来获取输出,我对它们之间的区别很感兴趣。我尝试输入相同的数据,但结果不同。我很困惑。

我在输入数据之前已经输出了layer_weight,权重没有改变,我知道当我们使用model(input)时它使用__call__函数,这个函数将调用model.forward.

   vgg = VGG()
   vgg.double()
   for layer in vgg.modules():
      if isinstance(layer,torch.nn.Linear):
         print(layer.weight)
   print("   use model.forward(input)     ")
   result = vgg.forward(array)

   for layer in vgg.modules():
     if isinstance(layer,torch.nn.Linear):
       print(layer.weight) 
   print("   use model(input)     ")
   result_2 = vgg(array)
   print(result)
   print(result_2)

输出:

    Variable containing:1.00000e-02 *
    -0.2931  0.6716 -0.3497 -2.0217 -0.0764  1.2162  1.4983 -1.2881
    [torch.DoubleTensor of size 1x8]

    Variable containing:
    1.00000e-02 *
    0.5302  0.4494 -0.6866 -2.1657 -0.9504  1.0211  0.8308 -1.1665
    [torch.DoubleTensor of size 1x8]

model.forward 只是调用前向操作,但 __call__ 做了一些额外的操作。

如果你深入研究 nn.Module class 的 code 你会看到 __call__ 最终调用 forward 但在内部处理 forward 或 backward hooks 并管理一些状态pytorch 允许。当调用像 MLP 这样的简单模型时,它可能不是真正需要的,但更复杂的模型如光谱归一化层有钩子,因此你应该尽可能使用 model(.) 签名,除非你明确地只想调用 model.forward

另见 Calling forward function without .forward()

然而,在这种情况下,差异可能是由于某些丢失层造成的,您应该调用 vgg.eval() 以确保在比较输出之前关闭网络中的所有随机性。