原问题 主要我刚刚注册那个 还没法回复 所以贴过来解一下
Python 语法问题,实例化了一个对象后直接把这个对象当作一个函数调用,这是什么语法?算是函数式编程吗?
~~~~
最近正在看 PyTorch,在 PyTorch 里看到了一种写法感觉很酷,但有点疑惑,遂来请教,感谢各位大佬答疑
在创建 PyTorch 的模型时会定义一个 class,这里是我抄来的代码:
class Encoder(nn.Module):
def __init__(
self,
n_src_vocab, len_max_seq, d_word_vec,
n_layers, n_head, d_k, d_v,
d_model, d_inner, dropout=0.1):
super().__init__()
# 具体的函数逻辑我就删掉了,应该没有什么关系
def forward(self, src_seq, src_pos, return_attns=False):
# 具体的函数逻辑我就删掉了,应该没有什么关系
return enc_output
然后在另外的函数里初始化了这个类,给对象传入参数,代码如下:
encoder = Encoder(参数)
encoder(input_data)
按照我的理解这里在调用 encoder 时就相当于调用了 forward 函数,但是不需要用encoder.forward()这样的语法,请问这个叫什么?我该在搜什么关键词能找到这个语法?
解答参考
> pyTorch之前向传播函数自动调用forward
主要思路是:
调用forward方法的具体流程
以一个Module为例:
1. 调用module的call方法
2. module的call里面调用module的forward方法
3. forward里面如果碰到Module的子类,回到第1步,如果碰到的是Function的子类,继续往下
4. 调用Function的call方法
5. Function的call方法调用了Function的forward方法。
6. Function的forward返回值
7. module的forward返回值
8. 在module的call进行forward_hook操作,然后返回值 上述中“调用module的call方法”是指nn.Module 的__call__方法。定义__call__方法的类可以当作函数调用,具体参考Python的面向对象编程。也就是说,当把定义的网络模型model当作函数调用的时候就自动调用定义的网络模型的forward方法。
nn.Module 的__call__方法部分源码如下所示:
def __call__(self, *input, **kwargs):
result = self.forward(*input, **kwargs)
for hook in self._forward_hooks.values():
#将注册的hook拿出来用
hook_result = hook(self, input, result)
...
return result
可以看到,当执行model(x)的时候,底层自动调用forward方法计算结果。具体示例如下:
class Function:
def __init__(self):
...
def forward(self, inputs):
...
return outputs
def backward(self, grad_outs):
...
return grad_ins
def _backward(self, grad_outs):
hooked_grad_outs = grad_outs
for hook in hook_in_outputs:
hooked_grad_outs = hook(hooked_grad_outs)
grad_ins = self.backward(hooked_grad_outs)
hooked_grad_ins = grad_ins
for hook in hooks_in_module:
hooked_grad_ins = hook(hooked_grad_ins)
return hooked_grad_ins
model = LeNet()
y = model(x)
如上则调用网络模型定义的forward方法。
我后面看得晕晕乎乎 大概知道内部函数在你调用model的时候调用了forward()
ta给的源码也没看懂。。。更多细节求教!