It’s a wild guess, but based on your loading function it looks like you are dealing with Kaggle’s facial keypoint detection dataset.
I’m not sure if there are multiple images of the same individuals in the training data, but I’m quite sure there are. Let’s assume your splitting gives two datasets which have nearly the same distribution (same individuals, gender ratio etc.).
Your training loss is currently saved before each optimizer step, while your validation loss is saved after the optimization is done. If both datasets are nearly identical, your validation loss might thus be a little lower if you don’t overfit your data.
Besides that I can’t find any other mistakes.
Are you following some kind of tutorial which assumes another validation loss curve?