Is there a convenient way of reshaping only last n dimensions?

username: Parskatt
cooked: <p>Consider:</p>
<pre><code class="lang-python">T = torch.randn(u,v,w,x,y,z)
</code></pre>
<p>where u,v,w,x,y,z are some dimensions. If I want to reshape this as: u,v,w,x,y*z I can write:</p>
<pre><code class="lang-python">T = torch.randn(u,v,w,x,y,z).view(-1,v,w,x,y*z)
</code></pre>
<p>But I cannot write:</p>
<pre><code class="lang-python">T = torch.randn(u,v,w,x,y,z).view(-1,y*z)
</code></pre>
<p>Since this will flatten all previous dimensions.<br>
Is there some convenient notation like:</p>
<pre><code class="lang-python">T = torch.randn(u,v,w,x,y,z).view_last(y*z)
U = T.view_last(y,z)
</code></pre>
<p>Currently in PyTorch, that just reshapes the final dimensions?<br>
The reason I am interested in this is the case where u,v,w,x are not known ahead of time, and I would rather avoid doing a T.shape.</p>

username: G.M
cooked: <p>U can try <code>torch.flatten</code>, which will flatten the given dimension.</p>

username: Parskatt
cooked: <p>Thanks for the suggestion, this does solve my issue in the case where I want to restrict dimensions, but not when I want to extend them. (i added an additional example to clarify my post)</p>
<p>Perhaps it is not a good idea to freely reshape the last dimensions since it might be ambiguous? Haven’t really thought about it.</p>

username: G.M
cooked: <p>what do u mean by extending the dimension? I didn’t find ur example <img src="https://discuss.pytorch.org/images/emoji/apple/frowning.png?v=9" title=":frowning:" class="emoji" alt=":frowning:"></p>

username: dhpollack
cooked: <pre><code class="lang-auto">T = torch.randn(3,4,5,6,7,8)
all_but_last_two_dims = T.size()[:-2]
U = T.view(*all_but_last_two_dims, -1)
</code></pre>
<p>I don’t think this is the most ideal solution especially if you want to flatten dimensions in the middle of a tensor but for your use case this should work.</p>

username: Parskatt
cooked: <pre><code class="lang-python">T = torch.randn(u,v,w,x,y,z).view_last(y*z)
U = T.view_last(y,z)
</code></pre>
<p>Basically I want to first flatten, and then “re-inflate”</p>

username: dhpollack
cooked: <p>Well, in my example you could just save the last two dims and then expand those.  I’m not totally sure what you find wrong with my answer?  It’s a bit confusing because you are using a function that doesn’t actually exist and you never save the original tensor <code>T</code>.  I think your example should look like this:</p>
<pre><code class="lang-auto">original_tensor = torch.randn(u,v,w,x,y,z)
T = original_tensor.view_last(y*z)
U = original_tensor.view_last(y,z)
# my suggestion
rem_dims, last_2_dims = original_tensor.size()[:-2], original_tensor.size()[-2:]
T = original_tensor.view(*rem_dims, -1)
U = T.view(*rem_dims, *last_2_dims)
</code></pre>
<h2>Alternative Answer</h2>
<p>Named Tensors and specifically <a href="https://pytorch.org/tutorials/intermediate/named_tensor_tutorial.html#new-behavior-flattening-and-unflattening-dimensions-by-names" rel="nofollow noopener">this</a></p>

username: JuanFMontesinos
cooked: <p>do:</p>
<pre><code class="lang-auto">torch.randn(u,v,w,x,y,z).view(u,v,w,x,-1)
</code></pre>
<p>undo:</p>
<pre><code class="lang-auto">T.view(u,v,w,x,y,z)
</code></pre>

username: JuanFMontesinos
cooked: <p>This seems incorrect to me, you cannot view something which is</p>
<pre><code class="lang-auto">(u,v,w,x,y,z)--&gt;(y,z)
</code></pre>
<p>unlesss u,v,w,x=1</p>

username: Parskatt
cooked: <p>Sorry, didn’t mean to suggest that your answer was wrong, however the notation you are using is slightly clunky.</p>

username: Parskatt
cooked: <p>I think my original question is perhaps a bit unclear, but what I want to avoid is having to explicitly mention the other dimensionalities, i.e. if there is an input which Im only certain of the last two dimensions I dont want to have to do a T.shape to get the others. But thanks for the suggestion.</p>

username: JuanFMontesinos
cooked: <p>I’m afraid it’s not implemented. Tensors doesn’t save previous shapes, as soon as you reshape it, the info about previous dimensionality is lost.<br>
The most you can do is something like <a class="mention" href="/u/dhpollack">@dhpollack</a> suggested, which would be manually saving the dimensionality.<br>
Given a tensor T</p>
<pre><code class="lang-auto">T_flatten = T.view(*T.shape[:-2],-1)
T_unflatten = T_flatten.view(*T_flatten.shape[:-1],y,z)
</code></pre>
<p>As I mentioned as soon as you compute T_flatten values of y and z are lost unless you save them.</p>
<pre><code class="lang-auto">T_flatten = T.view(*T.shape[:-2],-1)
T_unflatten = T_flatten.view(*T_flatten.shape[:-1],*T.shape[-2:])
</code></pre>
<p>So in short if you don’t overwrite T, you can do it that way.<br>
If you overwrite T you would need to save y and z</p>