How to get separate conv feature map from pretrained ResNet?

panovr: <p>PyTorch supplied pretrained ResNet with different depths. The ResNet has the “BasicBlock” or “Bottleneck” structure. I want to ask that how to get separate conv feature maps from these pretrained ResNet (for example, restnet18 or resnet50)?</p>

smth: <p>your question is not clear at all. What do you mean by “get separate conv feature maps”.<br>
Also, there are a few posts explaining how to extract intermediate outputs of resnet, please read those.</p>

panovr: <p>What I mean is “Extracting image features” from different layers in ResNet, and I read <a href="https://discuss.pytorch.org/t/how-to-extract-features-of-an-image-from-a-trained-model/119/3">this post</a>.<br>
I just wonder how this can be done in ResNet. One possible way is to construct a partial model which only use the front layers for forwarding. Are there other ways?<br>
By the way, the Torch version of ResNet has a <a href="https://github.com/facebook/fb.resnet.torch/blob/master/pretrained/extract-features.lua" rel="nofollow noopener">nice script</a><br>
to extract features from ResNet. If PyTorch also has a corresponding one will be better.</p>

fmassa: <p>In your case, attaching a hook to the layer you want seems easier.</p>
<pre><code class="lang-python">model = models.resnet18()

outputs = []
def hook(module, input, output):
    outputs.append(output)

model.layer2.conv1.register_forward_hook (hook)
</code></pre>
<p>(Typing from the phone, the code is an approximation and might contain errors)</p>

isalirezag: <p>Why do we have output as one of the inputs in the hook?</p>

alic: <p>Here is what i do:</p>
<pre><code class="lang-auto">class Resnet50Extractor(nn.Module):
    def __init__(self, submodule, extracted_layer):
        super(Resnet50Extractor, self).__init__()
        self.submodule = submodule
        self.extracted_layer = extracted_layer

    def forward(self, x):
        if self.extracted_layer == 'maxpool':                       
            modules = list(self.submodule.children())[:4]
        elif self.extracted_layer == 'inner-layer-3':                     
            modules = list(self.submodule.children())[:6]
            third_module = list(self.submodule.children())[6]
            third_module_modules = list(third_module.children())[:3]    # take the first three inner modules
            third_module = nn.Sequential(*third_module_modules)
            modules.append(third_module)
        elif self.extracted_layer == 'layer-3':                     
            modules = list(self.submodule.children())[:7]
        else:                                               # after avg-pool
            modules = list(self.submodule.children())[:9]

        self.submodule = nn.Sequential(*modules)
        x = self.submodule(x)
        return x
</code></pre>
<p>then call like below:</p>
<pre><code class="lang-auto">model_ft = models.resnet50(pretrained=True)
extractor = Resnet50Extractor(model_ft, extracted_layer)
features = extractor(input_tensor)
</code></pre>

seyeeet: <aside class="quote no-group" data-username="alic" data-post="6" data-topic="3479">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/alic/48/16974_2.png" class="avatar"> alic:</div>
<blockquote>
<p><code>Resnet50Extractor</code></p>
</blockquote>
</aside>
<p>is there any pros or cons between using your method comparing to <code>register_forward_hook</code></p>