Concatenate dimensions in a tensor

username: fyjl
cooked: <pre><code>import torch
x = torch.randn(2, 3, 4, 5)  #  [batch_size, n_chunk, input_size_1, input_size_2]
x_input = x.view(-1, 1, 4, 5)  # [batch_size * n_chunk, 1, input_size_1, input_size_2]  
x_bar = model(x)  # model is an CNN auto-encoder, for example
</code></pre>
<p>As the example shows, I have <code>x</code> with the shape described in comment; there is <code>n_chunk</code> because I split each input to chunks. I use <code>view</code> in order to reshape it as the input to <code>model</code> which is an CNN autoencoder with batch size =  <code>batch_size * n_chunk</code> and 1 channel. So <code>x_bar</code> has the same shape.</p>
<p>My question is, how to reshape <code>x_bar</code> into the shape of <code>[batch_size, input_size_1, input_size_2 * n_chunk]</code> without messing up the data order as it will with <code>view</code>?</p>
<p>To clarify, <code>x</code> is a batch of audio spectrogram which is split into <code>n_chunk</code> chunks, with <code>input_size_1</code> frequency bands and <code>input_size_2</code> time frames; which is why I’d like to concatenate chunks along the time axis.</p>

username: JuanFMontesinos
cooked: <p>You can use permute to order the dimensions as you wany (which is a rotation of the tensor)</p>
<p>the view function reorder picking first elements in the outer dimensions like</p>
<p>if u have a 5d tensor<br>
it will keep this order<br>
[5,4,3,2,1]</p>
<p>applied to you case<br>
you have to do</p>
<pre><code class="lang-auto">x_bar = model(x)  # model is an CNN auto-encoder, for example
x_bar = x_bar.view(batch_size , n_chunk, 1, input_size_1, input_size_2 ).permute(0,2,3,1).view(batch_size , n_chunk, 1, input_size_1,-1)
</code></pre>
<p>Look at permute cos i didnt paid attention to the exact order</p>

username: fyjl
cooked: <p>Thanks, your solution gave me the desired shape but the content is still not in the correct order.<br>
I realised that I should have explained it in a more intuitive way; it is basically doing a <code>hstack</code> for each data in a batch. So I manage to do it through:</p>
<pre><code>x = [torch.cat(i.chunk(n_chunk, dim=1), dim=-1) for i in x.chunk(batch_size, dim=0)]
x = torch.cat(x, dim=0).squeeze(1)</code></pre>

username: JuanFMontesinos
cooked: <p>Could you check this?</p><aside class="quote quote-modified" data-post="4" data-topic="30749">
  <div class="title">
    <div class="quote-controls"></div>
    <img alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/juanfmontesinos/48/76115_2.png" class="avatar">
    <a href="https://discuss.pytorch.org/t/difference-between-2-reshaping-operations-reshape-vs-permute/30749/4">Difference between 2 reshaping operations (reshape vs permute)</a> <a class="badge-category__wrapper " href="/c/nlp/8"><span data-category-id="8" style="--category-badge-color: #AB9364; --category-badge-text-color: #FFFFFF;" data-drop-close="true" class="badge-category " title="Topics related to Natural Language Processing"><span class="badge-category__name">nlp</span></span></a>
  </div>
  <blockquote>
    if u have a cube 
c=torch.rand(3,4,5)

and you use permute 
c=torch.rand(3,4,5)
rx  = c.permute(0,2,1)
ry  = c.permute(2,1,0)
rz = c.permute(1,0,2)
print(rx.size())
print(ry.size())
print(rz.size())

torch.Size([3, 5, 4])
torch.Size([5, 4, 3])
torch.Size([4, 3, 5])

you are just rotating the tensor, but order is preserved 
On the other hand, if you reshape you can see you are modifying the ordering because this is not rotating the cube but mapping in an ordered way from right to left. It takes n…
  </blockquote>
</aside>

<p>It’s a not very good but very graphical explanation about view and permute which may help you to order your data as you expect</p>

username: Arjun100
cooked: <p><div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/d/6/d6293d3e563a9083eb76fe3fb40fbfc652bbaa49.jpeg" data-download-href="https://discuss.pytorch.org/uploads/default/d6293d3e563a9083eb76fe3fb40fbfc652bbaa49" title="image"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/d/6/d6293d3e563a9083eb76fe3fb40fbfc652bbaa49_2_690x249.jpeg" alt="image" data-base62-sha1="uyyx46476lU1a1VnVhhqHnIe409" width="690" height="249" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/d/6/d6293d3e563a9083eb76fe3fb40fbfc652bbaa49_2_690x249.jpeg, https://discuss.pytorch.org/uploads/default/optimized/3X/d/6/d6293d3e563a9083eb76fe3fb40fbfc652bbaa49_2_1035x373.jpeg 1.5x, https://discuss.pytorch.org/uploads/default/original/3X/d/6/d6293d3e563a9083eb76fe3fb40fbfc652bbaa49.jpeg 2x" data-dominant-color="CFC9C8"><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">1140×412 111 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>In this image, we  concat three images on the batch dimension to get the output as shown in the image. I hope this visual representation helps.</p>
<p>First we had three images with each [1, c,h,w]. After concat we got [3,c,h,w]</p>