The code looks generally alright.
You might need to play around with some hyperparameters (e.g. learning rate, hidden size, etc.).
It might also be a good idea to scale down your use case a bit and try to overfit your model on a small data sample (e.g. use just 10 samples from the train dataset).
If your model is not able to overfit these samples perfectly, there might be e.g. some code bugs we missed.