No real ideas, just some comments:
(1) I would never use reshape() or view() to adjust the tensor shape. I’ve seen to many cases where this was used incorrectly and broke the tensor. Just because the shape is correct in the network doesn’t throw an error doesn’t mean the tensor is correct. If possible, I always use transpose() or permute() since in almost all cases I only need to swap dimensions. For exanole, instead of
seq = seq.reshape(seq_length,batch_size,1).to(DEVICE)

I would do
seq = seq.tranpose(1,0).to(DEVICE)

or
seq = seq.permute(1,0,2).to(DEVICE)

This ensures that dimensions are only swapped but never “torn apart” which can happen with reshape() or view(). The latter are mostly needed to maybe (un-)flatten tensors, but that’s not needed here.
(2) I’m also not quite sure about
predictions = self.linear1(lstm_out)

since the shape of lstm_out is (batch_size, seq_len, features). I know that nn.Linear takes as input (N,∗,H_in) but I’m not sure if you really want go that way. Usually the last hidden state is used for prediction. So I would try:
lstm_out, (h, c) = self.lstm(input_seq)
predictions = self.linear1(h[-1])

h[-1] is the last layer of the last hidden state.