Modify a MaxPool2d layer parameter in pretrained VGG16

username: emross3371
cooked: <p>I wanted to change the parameter in a Maxpool2d layer of a VGG16 network from ceil_mode=False to ceil_mode=True to achieve a certain strict output shape requirement to reproduce a piece of code. Can this be done if I am using a pretrained vgg16 model from torchvision.models?</p>

username: KFrank
cooked: <p>Hi Em!</p>
<aside class="quote no-group" data-username="emross3371" data-post="1" data-topic="143476" data-full="true">
<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/emross3371/48/50783_2.png" class="avatar"> emross3371:</div>
<blockquote>
<p>Can this be done if I am using a pretrained vgg16 model from torchvision.models?</p>
</blockquote>
</aside>
<p>Yes, this should work okay.</p>
<p>The question you should ask yourself when modifying the architecture<br>
of a pretrained model is whether the parameters (weights, etc.) of the<br>
modified model still mean more or less the same thing as they did in the<br>
unmodified model.</p>
<p>In the case of your proposed VGG16 modification, the following points<br>
are relevant:</p>
<ol>
<li>
<p><code>MaxPool2d</code> does not contain any trainable parameters, so no<br>
issue there.</p>
</li>
<li>
<p>As for the <code>Conv2d</code> layers, changing <code>cell_mode</code> from <code>False</code> to<br>
<code>True</code> will sometimes change slightly the size of the “images”<br>
output by the <code>MaxPool2d</code> layers.  But the <code>Conv2d</code> layers are<br>
pretty much agnostic about the spatial sizes of their inputs, so<br>
their weights retain essentially their original meaning.</p>
</li>
<li>
<p>At the end, you have some fully-connected <code>Linear</code> layers.  These<br>
expect inputs of a fixed size.  But the fully-connected “classifier”<br>
section of VGG16 is preceded by an <code>AdaptiveAvgPool2d</code> layer<br>
that outputs an “image” of spatial size 7 x 7, regardless of whether<br>
your <code>cell_mode = True</code> modifications have changed the size of<br>
the input to the <code>AdaptiveAvgPool2d</code> layer.</p>
</li>
</ol>
<p>All in all, the modified architecture will still work, and the weights of the<br>
layers will retain their original meanings so that their original pretrained<br>
values will still makes sense and work together properly with one another.<br>
This remains true even though the sizes of various intermediate “images”<br>
(sometimes called “feature maps”) will be modestly different as a result<br>
of your <code>cell_mode = True</code> modifications.</p>
<p>See this illustration in which layer 23 (chosen more or less at random) of<br>
VGG16’s <code>features</code> module has your <code>cell_mode = True</code> modification<br>
applied to it:</p>
<pre><code class="lang-plaintext">&gt;&gt;&gt; import torch
&gt;&gt;&gt; torch.__version__
'1.10.2'
&gt;&gt;&gt; import torchvision
&gt;&gt;&gt; torchvision.__version__
'0.11.3'
&gt;&gt;&gt;
&gt;&gt;&gt; _ = torch.manual_seed (2022)
&gt;&gt;&gt;
&gt;&gt;&gt; vgg = torchvision.models.vgg16 (pretrained = True)
Downloading: "https://download.pytorch.org/models/vgg16-397923af.pth" to C:\&lt;path_to_.cache&gt;\torch\hub\checkpoints\vgg16-397923af.pth
100%|███████████████████████████████████████████████████████████████████████████████| 528M/528M [00:39&lt;00:00, 13.8MB/s]
&gt;&gt;&gt;
&gt;&gt;&gt; t = torch.randn (1, 3, 244, 244)
&gt;&gt;&gt;
&gt;&gt;&gt; vgg.features[23]
MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
&gt;&gt;&gt; predA = vgg (t)
&gt;&gt;&gt;
&gt;&gt;&gt; vgg.features[23] = torch.nn.MaxPool2d (2, 2, ceil_mode = True)
&gt;&gt;&gt;
&gt;&gt;&gt; vgg.features[23]
MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
&gt;&gt;&gt; predB = vgg (t)
&gt;&gt;&gt;
&gt;&gt;&gt; predA[0, 0:10]
tensor([-1.1322,  2.0340, -1.0934, -1.5980, -0.4693,  0.9064,  0.4962,  0.7050,
         0.4435,  0.7932], grad_fn=&lt;SliceBackward0&gt;)
&gt;&gt;&gt; predB[0, 0:10]
tensor([-0.2408,  2.8836, -1.5900, -1.4564, -0.6028,  2.5356,  0.9514,  0.7236,
         1.3219,  0.4366], grad_fn=&lt;SliceBackward0&gt;)
&gt;&gt;&gt;
&gt;&gt;&gt; vgg.avgpool
AdaptiveAvgPool2d(output_size=(7, 7))
</code></pre>
<p>Notice that the resulting prediction (for a random input) does change<br>
when the network is modified, but that it still retains much of the structure<br>
of the prediction made by the original network.</p>
<p>Best.</p>
<p>K. Frank</p>