Cast Operation in ONNX

Diego: <p>Hi, I am trying to export the segmentation some segementation of the segmentation model, newly added to torchvision. They export sucessfully after applying this <a href="https://github.com/pytorch/pytorch/issues/22906" rel="noopener nofollow ugc">workaround</a>. However the ONNX graph generates several cast operations as seen in the picture.</p>
<p><div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/2X/0/0839f78f7786e500886bb22cb0a6bdac45070b0b.png" data-download-href="https://discuss.pytorch.org/uploads/default/0839f78f7786e500886bb22cb0a6bdac45070b0b" title="image"><img src="https://discuss.pytorch.org/uploads/default/optimized/2X/0/0839f78f7786e500886bb22cb0a6bdac45070b0b_2_690x108.png" alt="image" data-base62-sha1="1aM0Q7qRxZEe45PcU9fCZ5iiTVN" width="690" height="108" srcset="https://discuss.pytorch.org/uploads/default/optimized/2X/0/0839f78f7786e500886bb22cb0a6bdac45070b0b_2_690x108.png, https://discuss.pytorch.org/uploads/default/optimized/2X/0/0839f78f7786e500886bb22cb0a6bdac45070b0b_2_1035x162.png 1.5x, https://discuss.pytorch.org/uploads/default/optimized/2X/0/0839f78f7786e500886bb22cb0a6bdac45070b0b_2_1380x216.png 2x" data-dominant-color="2E2F30"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">1919×303 92.9 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div></p>
<p>It says its coming from the ASPPPooling layer but that layer is defined as:</p>
<p><div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/2X/c/cc90e2bb17625969715d401433a413f8ec80767b.png" data-download-href="https://discuss.pytorch.org/uploads/default/cc90e2bb17625969715d401433a413f8ec80767b" title="image"><img src="https://discuss.pytorch.org/uploads/default/original/2X/c/cc90e2bb17625969715d401433a413f8ec80767b.png" alt="image" data-base62-sha1="tbFOQoxl5ewTW9vJ3D4m9cpE8X1" width="690" height="161" data-dominant-color="323131"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">719×168 23.6 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div></p>
<p>And I dont think any of these layers do any casting. Any ideas where this <code>Cast[to=1]</code> comes from or how to avoid it? Any help will be greatly appreciated!! <img src="https://discuss.pytorch.org/images/emoji/apple/slight_smile.png?v=12" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>
<p>P.S I am using pytorch and torchvision both compiled from source</p>

ptrblck: <p>I guess the cast is related to <a href="https://github.com/pytorch/pytorch/blob/9228dd766af09017364bfaa7f88feacb7e89a154/torch/nn/functional.py#L2463" rel="nofollow noopener">this line of code</a> in <code>interpolate</code>, which was added in <a href="https://github.com/pytorch/pytorch/pull/18875" rel="nofollow noopener">this PR</a> to fix tracing.</p>
<p>PS: I could run the code without modifying anything or building from source:</p>
<pre><code class="lang-python">class AsppPooling(nn.Module):
    def __init__(self, in_channels, out_channels, norm_layer):
        super(AsppPooling, self).__init__()
        self.gap = nn.Sequential(nn.AdaptiveAvgPool2d(1),
                                 nn.Conv2d(in_channels, out_channels, 1, bias=False),
                                 norm_layer(out_channels),
                                 nn.ReLU(True))

    def forward(self, x):
        _, _, h, w = x.size()
        pool = self.gap(x)
        return F.interpolate(pool, (h,w))


model = AsppPooling(3, 3, nn.BatchNorm2d)
torch.onnx.export(model, torch.randn(2, 3, 2, 2), 'tmp.onnx', verbose=True)
</code></pre>

Diego: <p>Thank you so much! <a class="mention" href="/u/ptrblck">@ptrblck</a>. What should I expect if I were to remove the <code>.floor</code> operation?. Would the results be the same if I wanted to use that model for segmentation?</p>

ptrblck: <p>I’m not sure, but I would assume you would get wrong results.<br>
Also, I don’t think you should be too worried about casting a single value, as this should not change the time a lot.<br>
That being said, these are just guesses, as I’m not very familiar with ONNX, so <a class="mention" href="/u/eellison">@eellison</a> might have more insight as the author of the PR.</p>

Diego: <p>I am not worried because of speed. I am trying to export some ONNX models to OpenCV as part of my <a href="https://github.com/dvd42/opencv/wiki" rel="nofollow noopener">GSoC project</a> and the OpenCV ONNX importer does not support the <code>Cast</code> operation from ONNX yet. I am trying to see if I can get away with not implementing it <img src="https://discuss.pytorch.org/images/emoji/apple/sweat_smile.png?v=9" title=":sweat_smile:" class="emoji" alt=":sweat_smile:"></p>