外观
为什么我们在 PyTorch 中不直接调用 model.forward()?
Why Don't We Invoke model.forward() in PyTorch?
在 PyTorch 中,前向传播是在 forward() 方法中实现的,如下所示:

这里你有没有想过,当我们想要运行前向传播时,却很少直接去调用这个 forward() 方法:

相反,我们总是像调用函数一样去调用 model(一个类对象),如下所示:

我们也可以验证 model 确实是一个类对象:

一个类对象怎么能像函数一样被调用呢?我们到底漏掉了什么?让我们来弄明白!
假设我们想求下面这个二次式的值:f(x) = ax² + bx + c
一种做法是定义一个方法,接收输入并返回该二次式的值,如下所示:

当然,这种做法没有任何问题。
但在 Python 中还有一种更聪明、更优雅的做法。我们不必显式地调用某个方法,而是定义 call 这个魔术方法(magic method)。
这个魔术方法允许你定义类对象在被当作函数调用时(比如像这样:obj())的行为。我们把 value 方法重命名为 call。

这样一来,我们就可以直接调用类对象,而不必显式调用某个方法了。这会带来很多好处。例如:
- 它让我们能够以灵活且直观的方式去实现并使用对象。
- 它允许我们在期望可调用对象的场景中使用一个类对象——比如把类对象当作装饰器来用。

在 Python 中,可调用对象(callable)是指任何可以使用括号来调用、并可能返回值的对象。例如,函数就是一个可调用对象(可以被调用/执行的对象)。
我们用 PyTorch 构建深度学习模型时,发生的就是这件事。例如,再来看一下这个 PyTorch 类:

你可能已经猜到了,model 对象之所以可以被调用,是因为所有 PyTorch 的类都隐式地自行声明了 call 方法。而在那个 call 方法内部,它们会调用用户自定义的前向传播。
下面是它的一个简化版本:

- PyTorch 自身添加了 call 方法。
- call 方法会去调用用户自定义的 forward() 方法。
这样一来,Python 就知道这个 model 对象可以像函数一样被调用——model()。
事实上,我们可以验证:无论用哪种方式运行前向传播,得到的输出都是相同的:

这三种方式返回的输出完全相同。