Resize tensor without converting to PIL image?

Giulia_Savorgnan: <p>I have 6-channel images (512x512x6) that I would like to resize while preserving the 6-channels (say to 128x128x6). <code>torchvision.transforms.Resize</code> expects a PIL image in input but I cannot (&amp; do not want to) convert my images to PIL. Any idea how to do this within torchvision transforms (i.e. without resizing using numpy/scipy/cv2 or similar libs)?</p>

Nikronic: <p>Hi,</p>
<p>You can do it using <a href="https://pytorch.org/docs/stable/nn.html#torch.nn.functional.interpolate" rel="nofollow noopener">interpolate</a> function and it supports different methods.<br>
Here is an example:</p>
<pre><code class="lang-python">
import PIL.Image as Image
from torchvision.transforms import ToTensor, ToPILImage
import torch.nn.functional as F

img = Image.open('data/Places365_val_00000001.jpg')
img = ToTensor()(img)
out = F.interpolate(img, size=128)  #The resize operation on tensor.
ToPILImage()(out).save('test.png', mode='png')
</code></pre>
<p>Bests<br>
Nik</p>

Giulia_Savorgnan: <aside class="quote no-group" data-username="Nikronic" data-post="2" data-topic="52401">
<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/nikronic/48/71873_2.png" class="avatar"> Nikronic:</div>
<blockquote>
<p>torch.nn.functional</p>
</blockquote>
</aside>
<p>From the docs of <code>torch.nn.functional.interpolate</code>:<br>
<code>Currently temporal, spatial and volumetric sampling are supported, i.e. expected inputs are 3-D, 4-D or 5-D in shape.</code><br>
<code>raise NotImplementedError("Input Error: Only 3D, 4D and 5D input Tensors supported"                                   " (got {}D) for the modes: nearest | linear | bilinear | bicubic | trilinear"                                   " (got {})".format(input.dim(), mode))</code></p>

Giulia_Savorgnan: <p>I solved by using the <a href="https://github.com/albu/albumentations" rel="nofollow noopener">albumentations</a> library (which uses at least <code>numpy</code> and <code>cv2</code>). Not exactly what I wanted, but super easy to use <img src="https://discuss.pytorch.org/images/emoji/apple/slight_smile.png?v=9" title=":slight_smile:" class="emoji" alt=":slight_smile:"></p>

Nikronic: <p>Ok, great. But the <code>interpolate</code> function in PyTorch is very easy to use and actually needs only one line of code.</p>
<pre><code class="lang-auto">F.interpolate(tensor, size)
</code></pre>
<p>By the way, you should no get any error, because your tensor is 3D already so it works precisely as I shared my code.</p>
<p>As I can see, you provided <code>none</code> or something like that to <code>interpolate</code> because the error says your tensor has <code>{}D</code> dimension!</p>
<p>Finally, I have read a little about <a href="https://github.com/albu/albumentations" rel="nofollow noopener">albumentations</a> library and it seems it does not support GPU, so you can achieve higher benchmark by using GPU and Torch core.</p>
<p>Good luck</p>

Giulia_Savorgnan: <p>Sorry, I completely misunderstood the input.dim(), I thought it was referring to the number of channels, my bad! I did not produce the error above, I just had a look at the source. Thank you very much then. I didn’t know albumentations was not supporting GPU as well. Cheers mate <img src="https://discuss.pytorch.org/images/emoji/apple/slight_smile.png?v=9" title=":slight_smile:" class="emoji" alt=":slight_smile:"></p>

wjm: <p>hi ,I have a 4d data and like this: torch.Size([100, 1, 2, 2]),I want to know how resize it become ([100, 1, 32, 32])?</p>

Nikronic: <p>Hi,</p>
<p><code>F.interpolate</code> works for 3D, 4D, and 5D tensors in shape.</p>
<pre><code class="lang-auto">x = torch.randn(100, 1, 2, 2)
F.interpolate(x, (32, 32))
</code></pre>

WeberJulian: <p>Hi,<br>
I think I’m not getting what the dim means…<br>
I don’t know why I’m getting this error because clearly my input has the same dim as the scale_factor tuple.<br>
please help<br>
<div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/e/7/e76406554881b8702e8a51939c68c600b0f6f4ec.png" data-download-href="https://discuss.pytorch.org/uploads/default/e76406554881b8702e8a51939c68c600b0f6f4ec" title="image"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/e/7/e76406554881b8702e8a51939c68c600b0f6f4ec_2_690x287.png" alt="image" data-base62-sha1="x0YB3vR98nZZZGOik7XitwK34o4" width="690" height="287" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/e/7/e76406554881b8702e8a51939c68c600b0f6f4ec_2_690x287.png, https://discuss.pytorch.org/uploads/default/optimized/3X/e/7/e76406554881b8702e8a51939c68c600b0f6f4ec_2_1035x430.png 1.5x, https://discuss.pytorch.org/uploads/default/optimized/3X/e/7/e76406554881b8702e8a51939c68c600b0f6f4ec_2_1380x574.png 2x" data-dominant-color="252627"><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">2324×968 249 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>

Nikronic: <p>Hi,<br>
The issue is that <code>tensor.dim</code> does not have same meaning as <code>dim</code> in interpolation.<br>
In case of interpolate, you need to provide a batched tensor if you are using <code>scale_factor</code>.<br>
Your input <code>[1, 4, 4]</code> is actually a batch of 1 instance where it has 4 channels and only 1 dimension for samples but your <code>scale_factor</code> has 3 dimensions. That is why you see it says your input is 1D.<br>
If you want to define an 4x4 grayscale image, you need to define your input in this way:</p>
<pre><code class="lang-auto">x = torch.rand((1, 1, 4, 4))  # (batch_size, channel, height, width)
res = F.interpolate(x, scale_factor=(2, 2), mode='nearest')
res.shape  # [1, 1, 8. 8]
</code></pre>
<p>And if you want to work on a 3D image (your scale_factor is 3D at least):</p>
<pre><code class="lang-auto">x = torch.rand((1, 1, 1, 4, 4))  # (batch_size, channel, height, width, depth)
res = F.interpolate(x, scale_factor=(1, 2, 2), mode='nearest')
res.shape  # torch.Size([1, 1, 1, 8, 8])
</code></pre>
<p>An easy solution is to always look for the source code:</p>
<pre><code class="lang-auto">def _interp_output_size(closed_over_args):  # noqa: F811
    input, size, scale_factor, recompute_scale_factor = closed_over_args
    ###############
    dim = input.dim() - 2  ############# removes batch size and channel size
    ###############
    if size is None and scale_factor is None:
        raise ValueError('either size or scale_factor should be defined')
    if size is not None and scale_factor is not None:
        raise ValueError('only one of size or scale_factor should be defined')
    if scale_factor is not None:
        if isinstance(scale_factor, (list, tuple)):
            if len(scale_factor) != dim:
                raise ValueError('scale_factor shape must match input shape. '
                                 'Input is {}D, scale_factor size is {}'.format(dim, len(scale_factor)))

</code></pre>
<p>Bests</p>

Nikronic: <p>It seems documentation has been changed so the link to the <code>interpolate</code> is broken.<br>
Use the following link<br>
<a href="https://pytorch.org/docs/stable/nn.functional.html" class="onebox" target="_blank" rel="nofollow noopener">https://pytorch.org/docs/stable/nn.functional.html</a></p>

WeberJulian: <p>Thank you so much for your quick answer ! It works !<br>
I just spent 15 minutes coding a solution with scipy.interpolate.interp2d and it’s painfully slow compared to this.<br>
Thanks again</p>

AmaliaAzizi: <p>Hi, I am trying to use this method, however i am getting the error of<br>
RuntimeError: It is expected output_size equals to 1, but got size 2</p>
<p>I am trying to standardize my torch images so that all are [5,189,197,233]<br>
I ran it as: image = F.interpolate(image, (197,233))</p>

eqy: <p>What is the input image shape to interpolate in this situation?</p>

eqy: <p>Hmm, I cannot seem to reproduce this issue with:</p>
<pre><code class="lang-auto">&gt;&gt;&gt; import torch
&gt;&gt;&gt; import torch.nn.functional as F
&gt;&gt;&gt; a= torch.randn([5,189,196,233])
&gt;&gt;&gt; b = F.interpolate(a, (197, 233))
&gt;&gt;&gt; b.shape
torch.Size([5, 189, 197, 233])
</code></pre>

AmaliaAzizi: <p>Ahh, I believe my input is without the batch size. So instead of [5,189,197,233], its actually just [189,197,233]. But the issue still persists</p>

Nikronic: <p>As per docs of <a href="https://pytorch.org/docs/master/generated/torch.nn.functional.interpolate.html" rel="noopener nofollow ugc">interpolate</a>, inputs expected to be batched, so with your input, torch interprets it as <code>[batch, channel, length]</code>. Just add a new a batch dimension by <code>tensor.unsqueeze(0)</code>.</p>

NomanMK007: <aside class="quote no-group" data-username="Nikronic" data-post="18" data-topic="52401">
<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/nikronic/48/71873_2.png" class="avatar"> Nikronic:</div>
<blockquote>
<p>channe</p>
</blockquote>
</aside>
<p>Hi,<br>
I am getting “torch.Size([1, 3, 250, 100])”, so how can I update the channel from 3 to 6, any idea ??</p>