How do you determine the layer type?

lgoncalves: <p>I want to iterate through the children() of a module,<br>
and identify all the convolutional layers (for instance), or maybe all the maxpool layers, to do something with them.</p>
<p>How can I determine the type of layer?</p>
<p>My code would be something like this:</p>
<pre><code class="lang-auto">for layer in net.children():
    if layer is a conv layer:  # ??? how do I do this ???
        do something with the layer
</code></pre>
<p>Thanks!</p>

reachtarunhere: <p>Do you plan to treat Conv1d, Conv2d and so far as different? If you were only looking for Conv2d layers you can do something like:</p>
<pre><code class="lang-auto">for layer in net.children():
    if isinstance(layer, nn.Conv2d):
        do something with the layer
</code></pre>
<p>isinstance is a Python built-in <a href="https://docs.python.org/3/library/functions.html#isinstance" rel="nofollow noopener">https://docs.python.org/3/library/functions.html#isinstance</a></p>

lgoncalves: <p>Great! Thanks!</p>
<p>That’s good enough for me, for now.  I just need to distinguish between Conv2d and MaxPool2d.</p>
<p>Thank you!!</p>

reachtarunhere: <p>Happy to help <img src="https://discuss.pytorch.org/images/emoji/apple/slight_smile.png?v=5" title=":slight_smile:" class="emoji" alt=":slight_smile:"></p>

ksouvik52: <p>How can I check whether a layer is Conv2d or not for this kind of ResNet structure?<br>
Please help.</p>
<p>ResNet(<br>
(conv1): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)<br>
(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)<br>
(layer1): Sequential(<br>
(0): BasicBlock(<br>
(conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)<br>
(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)<br>
(conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)<br>
(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)<br>
(shortcut): Sequential()<br>
)<br>
(1): BasicBlock(<br>
(conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)<br>
(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)<br>
(conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)<br>
(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)<br>
(shortcut): Sequential()<br>
)<br>
)</p>

ptrblck: <p>The code of <a class="mention" href="/u/reachtarunhere">@reachtarunhere</a> should work, since <code>net.children()</code> will be called recursively on all submodules.</p>

ksouvik52: <p>But it is not working, it can find only if the 1st layer is conv or not. I guess its mostly because for the BasicBlocks the nns are not directly having Conv2d as its children directly. So, the code is failing. Any suggestion?</p>

ptrblck: <p>Right, I was mistaken.<br>
In that case, <code>model.modules()</code> or <code>model.named_modules()</code> should work. <img src="https://discuss.pytorch.org/images/emoji/apple/wink.png?v=9" title=":wink:" class="emoji" alt=":wink:"></p>

ksouvik52: <p>Thanks, it worked fine! Is there any way I can specifically choose the shortcut layer conv2ds only?</p>

sanchit2843: <p>I was searching for batchnorm layer and</p>
<pre><code class="lang-auto">
model = models.densenet161()
for child in model.children():
  for layer in child.modules():
    if(isinstance(layer,torch.nn.modules.batchnorm.BatchNorm2d)):
      print(layer)
</code></pre>
<p>This code worked for me.</p>

remya: <p>Thank you for the answer. How can I select the first conv layer of the ResNet model?</p>

ptrblck: <p>This should work:</p>
<pre><code class="lang-python">model = models.resnet18()
print(model.conv1)
</code></pre>

remya: <p>Thank you. it works:)</p>

remya: <p>I want to decompose each Conv layer  other than the first one in the ResNet.How can I re-assign the decomposed layers to its position?What is the equivalent of model.features._modules[module] of vgg in ResNet?</p>

ptrblck: <p>The architectures are a bit different for these models.<br>
You can print out the layout using:</p>
<pre><code class="lang-python">model = models.resnet18()
print(model)
print(model.layer1)
</code></pre>
<p>and check all submodules.</p>

remya: <p>I got it in the following way. But do we have a better way to do it ? here net impies the model.</p>
<p>for n, m in net.named_children():<br>
num_children = sum(1 for i in m.children())<br>
if num_children != 0:<br>
# in a layer of resnet<br>
layer = getattr(net, n)<br>
# decomp every bottleneck<br>
for i in range(num_children):<br>
BasicBlock = layer[i]<br>
conv2 = getattr(BasicBlock, ‘conv2’)<br>
<span class="hashtag">#print</span>(conv2)<br>
decompose = function_call<br>
# s += count_params(conv2)<br>
setattr(BasicBlock, ‘conv2’,decompose)<br>
<span class="hashtag">#print</span>(decompose)<br>
conv1 = getattr(BasicBlock, ‘conv1’)<br>
<span class="hashtag">#print</span>(conv1)<br>
decompose = function_call<br>
# s += count_params(conv2)<br>
setattr(BasicBlock, ‘conv1’,decompose)<br>
conv = getattr(BasicBlock, ‘downsample’)<br>
if(conv) :<br>
c = getattr(conv, ‘0’)<br>
decompose = function_call<br>
setattr(conv, ‘0’,decompose)</p>

mhamdan: <p>How to determine layer type from a model saved with  torch.jit.<br>
When I attempt to access modules, it returns RecursiveScriptModule(original_name=Linear) instead of Linear.</p>

augustus-thomas: <p>I have the same problem when saving to torchscript! It is also not possible to use the built-in Python isinstance method.</p>