Thanks for reaching out.
Indeed it was just a silly mistake leaving different weighted losses between training and validation. I’ve just put both losses as 0.5*loss1 + 0.5* loss2 and this is how my training looks like now:
Epoch: 0, train_loss: 6.007 , val_loss: 5.639
Epoch: 1, train_loss: 4.894 , val_loss: 3.604
Epoch: 2, train_loss: 2.423 , val_loss: 1.695
Epoch: 3, train_loss: 1.642 , val_loss: 1.520
Epoch: 4, train_loss: 1.511 , val_loss: 1.408
Epoch: 5, train_loss: 1.397 , val_loss: 1.297
Epoch: 6, train_loss: 1.286 , val_loss: 1.196
Epoch: 7, train_loss: 1.193 , val_loss: 1.116
Epoch: 8, train_loss: 1.119 , val_loss: 1.053
Epoch: 9, train_loss: 1.055 , val_loss: 0.992
Epoch: 10, train_loss: 0.993 , val_loss: 0.936
Epoch: 11, train_loss: 0.941 , val_loss: 0.895
Epoch: 12, train_loss: 0.905 , val_loss: 0.870
Epoch: 13, train_loss: 0.883 , val_loss: 0.856
Epoch: 14, train_loss: 0.870 , val_loss: 0.847
Epoch: 15, train_loss: 0.860 , val_loss: 0.840
Epoch: 16, train_loss: 0.853 , val_loss: 0.834
Epoch: 17, train_loss: 0.846 , val_loss: 0.830
Epoch: 18, train_loss: 0.841 , val_loss: 0.826
Epoch: 19, train_loss: 0.837 , val_loss: 0.822
Epoch: 20, train_loss: 0.833 , val_loss: 0.819
Epoch: 21, train_loss: 0.829 , val_loss: 0.817
Epoch: 22, train_loss: 0.826 , val_loss: 0.814
Epoch: 23, train_loss: 0.823 , val_loss: 0.812
Epoch: 24, train_loss: 0.820 , val_loss: 0.810
Epoch: 25, train_loss: 0.817 , val_loss: 0.808
Epoch: 26, train_loss: 0.815 , val_loss: 0.806
Epoch: 27, train_loss: 0.812 , val_loss: 0.805
Epoch: 28, train_loss: 0.810 , val_loss: 0.803
Epoch: 29, train_loss: 0.808 , val_loss: 0.802
Epoch: 30, train_loss: 0.806 , val_loss: 0.801
Epoch: 31, train_loss: 0.804 , val_loss: 0.799
Epoch: 32, train_loss: 0.802 , val_loss: 0.798
Epoch: 33, train_loss: 0.800 , val_loss: 0.797
Epoch: 34, train_loss: 0.798 , val_loss: 0.796
Epoch: 35, train_loss: 0.796 , val_loss: 0.794
Epoch: 36, train_loss: 0.795 , val_loss: 0.793
Epoch: 37, train_loss: 0.793 , val_loss: 0.792
Epoch: 38, train_loss: 0.791 , val_loss: 0.791
Epoch: 39, train_loss: 0.789 , val_loss: 0.790
Epoch: 40, train_loss: 0.788 , val_loss: 0.789
Epoch: 41, train_loss: 0.786 , val_loss: 0.788
Epoch: 42, train_loss: 0.784 , val_loss: 0.787
Epoch: 43, train_loss: 0.783 , val_loss: 0.786
Epoch: 44, train_loss: 0.781 , val_loss: 0.785
Epoch: 45, train_loss: 0.780 , val_loss: 0.784
Epoch: 46, train_loss: 0.778 , val_loss: 0.783
Epoch: 47, train_loss: 0.776 , val_loss: 0.782
Epoch: 48, train_loss: 0.775 , val_loss: 0.781
Epoch: 49, train_loss: 0.773 , val_loss: 0.780

I’m also attaching a plot to visualize the behaviour:

I also have the feeling that I may mess things up when I build train_loader and val_loader in a separate class. Basically I split the original data into training and test, and then I use the original train dataset to split again into training and validation. I’m attaching some additional code to let you better frame the situation:
df = pd.read_csv(data_path)
df_train, df_test = train_test_split(df, test_size=0.25)
df_tr, df_val = train_test_split(df_train, test_size=0.25)

train_dataset = MyCompositionalDataset(df_tr, fea_path)
val_dataset = MyCompositionalDataset(df_val, fea_path)
test_dataset = MyCompositionalDataset(df_test, fea_path)

train_list = [Data(x=train, edge_index=make_fully_connected(train.shape[0]), y=target) for train,target in train_dataset]
val_list = [Data(x=train, edge_index=make_fully_connected(train.shape[0]), y=target) for train,target in val_dataset]
test_list = [Data(x=train, edge_index=make_fully_connected(train.shape[0]), y=target) for train,target in test_dataset]
train_loader = DataLoader(train_list, batch_size=batch_size)
val_loader = DataLoader(val_list, batch_size=batch_size)
test_loader= DataLoader(test_list, batch_size=len(test_list))

this is part of my data processing method returning then train_loader, val_loader, test_loader. Maybe you can spot something from this… Do you think that the initial separation through train_test_split() has been done correctly?
Many thanks,
Fede