【问题标题】:TypeError: hook() takes 3 positional arguments but 4 were givenTypeError: hook() 接受 3 个位置参数,但给出了 4 个
【发布时间】:2021-04-14 01:27:18
【问题描述】:

我正在尝试使用前向挂钩从 PyTorch 中的 ResNet18 中间体中提取特征

class CCLModel(nn.Module):
    def __init__(self,output_layer,*args):
        self.output_layer = output_layer
        super().__init__(*args)

        self.output_layer = output_layer
        #PRETRAINED MODEL
        self.pretrained = models.resnet18(pretrained=True)
    
        #TAKING OUTPUT FROM AN INTERMEDIATE LAYER

        #self._layers = []
        for l in list(self.pretrained._modules.keys()):
            #self._layers.append(l)
            if l == self.output_layer:
                handle = getattr(self.pretrained,l).register_forward_hook(self.hook)
   
    def hook(self,input,output):
        return output

    def _forward_impl(self, x):
        x = self.pretrained(x)
        return x

    def forward(self, x):
        return self._forward_impl(x)

我还想要第 4 层的特征输出旁边的预测

但我收到了TypeError: hook() takes 3 positional arguments but 4 were given

完整的错误信息是这样的

TypeError                                 Traceback (most recent call last)
<ipython-input-66-18c4a0f917f2> in <module>()
----> 1 out = model(x.to('cuda:0').float())

6 frames
/usr/local/lib/python3.6/dist-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
    725             result = self._slow_forward(*input, **kwargs)
    726         else:
--> 727             result = self.forward(*input, **kwargs)
    728         for hook in itertools.chain(
    729                 _global_forward_hooks.values(),

<ipython-input-61-71fe0d1420a6> in forward(self, x)
     78 
     79     def forward(self, x):
---> 80         return self._forward_impl(x)
     81 
     82     '''def forward(self,x):

<ipython-input-61-71fe0d1420a6> in _forward_impl(self, x)
     73         #x = torch.flatten(x, 1)
     74         #x = self.fc(x)
---> 75         x = self.pretrained(x)
     76 
     77         return x

/usr/local/lib/python3.6/dist-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
    725             result = self._slow_forward(*input, **kwargs)
    726         else:
--> 727             result = self.forward(*input, **kwargs)
    728         for hook in itertools.chain(
    729                 _global_forward_hooks.values(),

/usr/local/lib/python3.6/dist-packages/torchvision/models/resnet.py in forward(self, x)
    218 
    219     def forward(self, x):
--> 220         return self._forward_impl(x)
    221 
    222 

/usr/local/lib/python3.6/dist-packages/torchvision/models/resnet.py in _forward_impl(self, x)
    209         x = self.layer2(x)
    210         x = self.layer3(x)
--> 211         x = self.layer4(x)
    212 
    213         x = self.avgpool(x)

/usr/local/lib/python3.6/dist-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
    729                 _global_forward_hooks.values(),
    730                 self._forward_hooks.values()):
--> 731             hook_result = hook(self, input, result)
    732             if hook_result is not None:
    733                 result = hook_result

TypeError: hook() takes 3 positional arguments but 4 were given

为什么钩子不起作用,尽管我在各种论坛中看到这是这样做的方法?

【问题讨论】:

    标签: python pytorch


    【解决方案1】:

    这里是一个前向钩子的简单例子,它必须有modelinputoutput三个参数:

    m = models.resnet18(pretrained=False)
    
    def hook(module, input, output):
        print(output.detach().shape)
    
    m.fc.register_forward_hook(hook)
    

    用虚拟数据试试:

    >>> m(torch.rand(1, 3, 224, 224))
    torch.Size([1, 1000])
    <<< tensor(...)
    

    要将它与您的nn.Module 结合使用,您需要使用额外的参数self 实现挂钩:

    class CCLModel(nn.Module):
        def __init__(self, output_layer, *args):
            super(CCLModel, self).__init__()
    
            self.pretrained = models.resnet18(pretrained=True)
            self.output_layer = output_layer
    
            self.output_layer.register_forward_hook(self.hook)
       
        def hook(self, module, input, output):
            return print(output.shape)
    
        def forward(self, x):
            x = self.pretrained(x)
            x = self.output_layer(x)
            return x
    

    注意 - self 对应于 CCLModel 实例,而 model 是我们所连接的层,即 nn.Linear

    这是一个例子:

    >>> m = CCLModel(nn.Linear(1000, 100))    
    >>> m(torch.rand(1, 3, 224, 224))
    torch.Size([1, 100])
    <<< tensor(...)
    

    【讨论】:

      猜你喜欢
      • 2020-01-06
      • 2021-10-05
      • 2018-03-07
      • 1970-01-01
      • 1970-01-01
      • 2022-01-17
      • 2021-02-02
      • 2020-11-02
      • 1970-01-01
      相关资源
      最近更新 更多