Fill 0 values in a tensor with nearest neighbors

username: danishnazir
cooked: <p>Hi I have a tensor of size (1,320,1216), which has values = 0 at most of the places.  I want to replace those values with their nearest neighbors. What is the most efficient and fast way of achieving this considering this would happen in online training?</p>

username: JuanFMontesinos
cooked: <p>I don’t find that really straight forward.<br>
First of all you would need to calculate which is the nearest neightbor.<br>
You can get non-zero elements by doing tensor[tensor&gt;0].<br>
This is already bit expensive.<br>
But this way you are losing the position in the grid.<br>
Getting that is hard.</p>
<p>In fact you could try to use sparse tensors.<br>
<a href="https://pytorch.org/docs/stable/sparse.html" class="onebox" target="_blank" rel="noopener nofollow ugc">https://pytorch.org/docs/stable/sparse.html</a><br>
as they save the position of the non-zero elements.</p>
<p>However as u can see here:</p><aside class="quote" data-post="1" data-topic="7404">
  <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/chenjus/48/724_2.png" class="avatar">
    <a href="https://discuss.pytorch.org/t/dense-to-sparse-tensors/7404">Dense to Sparse Tensors</a> 
  </div>
  <blockquote>
    Is there a way to convert dense tensors to sparse tensors without having to extract every value and coordinate and recreating the dense tensor as a sparse one?
  </blockquote>
</aside>
<p>
The developer point out that there is no easy way to obtain a sparse tensor from a dense one. Which is basically the problem you are trying to solve.</p>
<p>If you can construct the sparse tensor you can achieve good performance.<br>
Otherwise I would recomment to find another way to fill the non-zero elements or to relax your criteria bout what’s the nearest.</p>
<p>For example something very silly that would be fast is to run a convolution (as the operation takes the max of the kernel). If you matrix is really sparse and ur kernel is big enough you would me taking some sort of nearest neighbor.</p>
<p>hope it helps</p>

username: danishnazir
cooked: <p>I agree with most of the points that you have made, however, my problem is to create dense tensors from sparse tensors, not the other way around. I have a tensor that contains values at only 25% of the total indices e.g if total values are 100 then only 25 values would be present and 75 would be 0. I want to interpolate that 0 values with their nearest values in the index. I thought there would be a clean way to simply fill a tensor with 0 values.</p>

username: JuanFMontesinos
cooked: <p>Oh btw I remembered that there is a function which return those indices:</p>
<pre><code class="lang-auto">import torch

with torch.no_grad():
    tensor = torch.rand(4, 4)
    # generate zero elements
    tensor[tensor &lt; 0.5] = 0
    print(tensor)
    # Obtain position of non-zero elements
    print(tensor.nonzero())
</code></pre>
<pre><code class="lang-auto">tensor([[0.0000, 0.7300, 0.7180, 0.0000],
        [0.0000, 0.7008, 0.5255, 0.0000],
        [0.6798, 0.0000, 0.0000, 0.6164],
        [0.9133, 0.0000, 0.7820, 0.0000]])
tensor([[0, 1],
        [0, 2],
        [1, 1],
        [1, 2],
        [2, 0],
        [2, 3],
        [3, 0],
        [3, 2]])
</code></pre>
<p>Soo given this you can easily apply the interpolation</p>

username: danishnazir
cooked: <p>thanks, this is much cleaner than the initial solution I thought.</p>