Rewrite LSTM in Pytorch

username: Hoang_Tran
cooked: <p><div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/3/1/31122d7b32568aa99fa4d0366ed31e796e04e9ac.png" data-download-href="https://discuss.pytorch.org/uploads/default/31122d7b32568aa99fa4d0366ed31e796e04e9ac" title="image"><img src="https://discuss.pytorch.org/uploads/default/original/3X/3/1/31122d7b32568aa99fa4d0366ed31e796e04e9ac.png" alt="image" data-base62-sha1="706laLH49voEq6FGSncVYbGGY9u" width="647" height="500" data-dominant-color="F5F5F5"><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">750×579 14.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>May I ask how do you go from (None, 20, 256) from layer dropout_4 to (None, 256) in lstm layer? I’m trying to rewrite this network in Pytorch but keep getting size mismatch errors. The input that I used for the keras model has shape (128, 20, 108) and the output has shape (128, 108). Input[i,:,:] is a collection of 20 one-hot-encoded vectors indicate the positions of musical notes. Output[i,:] is also one-hot-encoded vector that indicates the notes at the 21st position.</p>

username: SANKALP_SHUBHAM
cooked: <p>Hi! I am not some expert here but I will try to answer. The picture you have attached is for a keras model right?<br>
Refer this stackoverflow <a href="https://stackoverflow.com/questions/53663407/keras-lstm-different-input-output-shape" rel="noopener nofollow ugc">link</a>.<br>
I don’t use Keras (but from reading <a href="https://keras.io/api/layers/recurrent_layers/lstm/" rel="noopener nofollow ugc">docs</a>), it seems that using <code>return sequences = True</code> will <strong>return the hidden state output for each input time step</strong>.<br>
For this, you may use a LSTMCell maybe with a for loop to collect all the timesteps(slow I guess, somebody correct me) or you can just use  the output provided by the LSTM.  (See the docs for nn.LSTM)</p>
<pre><code class="lang-auto">Outputs: output, (h_n, c_n)
output of shape (seq_len, batch, num_directions * hidden_size): tensor containing the output features (h_t) from the last layer of the LSTM, for each t. 
If a torch.nn.utils.rnn.PackedSequence has been given as the input, 
the output will also be a packed sequence.

h_n of shape (num_layers * num_directions, batch, hidden_size): tensor containing the hidden state for t = seq_len.

c_n of shape (num_layers * num_directions, batch, hidden_size): tensor containing the cell state for t = seq_len.

</code></pre>
<p>So before lstm_5, it seems the keras network uses all the hidden time steps.<br>
After that, it is only passing the latest hidden state through the network. So, you can just take the hidden state using <a href="https://pytorch.org/docs/stable/generated/torch.nn.LSTM.html#lstm" rel="noopener nofollow ugc">nn.LSTM</a>.</p>

username: SANKALP_SHUBHAM
cooked: <p>Also, typically people use LSTMCell in seq2seq models when they have to do some manipulation on the individual hidden states, cell states etc. Then, one feeds these to obtain the hidden,cell states for the next time step.</p>

username: nicofish
cooked: <p>I have not used Keras. Is it possible that LSTM_5 is doing something beyond a simply LSTM?</p>
<p>As <a class="mention" href="/u/sankalp_shubham">@SANKALP_SHUBHAM</a> suggest it may simply be taking the output at the last time step.</p>
<p>Indeed, when looking at Keras documentation this seems to be the case</p>
<blockquote>
<p>Blockquote<br>
return_sequences: Boolean. Whether to return the last output. in the output sequence, or the full sequence. Default: <code>False</code>.</p>
</blockquote>
<p>above from keras LSTM documentation.</p>
<p>if you wanted to replicate the above exactly in pytorch you could do the following either of the following:</p>
<p>output, hidden = yourLSTM()</p>
<p>1)take output[19] (your last output)<br>
2)take hidden</p>
<p>The last hidden state should correspond to the last output as output simply stores the hidden states at each time step.</p>
<p>I am not sure that this is what you should be doing. You would be getting rid of the hidden states of all your previous timesteps. Which in this case would correspond to the previous 19 vectors.</p>
<p>Instead I would suggest taking the output of your LSTM of shape [1, 20,256] = [seq_len, batch_size, input_size] and reshaping it so it is of shape [20, 1, 256]  = [batch_size, seq_length, input_size]. You can use torch.transpose() to do this.</p>
<p>Pass the reshaped data to an nn.Linear() layer with 256 neurons using your activation function of choice (2 things are same as Dense).</p>