So with that, i have adjusted my code as follows
batch_size = 8
layer_size = 64
learning_rate = 5e-4
class_weights = torch.tensor([0.7, 0.3], dtype=torch.float64)
loss_fn  = nn.BCEWithLogitsLoss(reduction='none', pos_weight=class_weights)

class MY_FIRST_GRU(nn.Module):
    def __init__(self):
        super(MY_FIRST_GRU, self).__init__()
        self.gru = nn.GRU(input_size=32, 
                          hidden_size=20, 
                          num_layers=4,
                          batch_first=True)  # Note that "batch_first" is set to "True"
        self.l_out = nn.Linear(in_features=20*1,
                               out_features=2)
 
    def forward(self, batch):
        x, x_length, _ = batch
        x_pack = pack_padded_sequence(x, x_length, batch_first=True).float()
        packed_x, hidden = self.gru(x_pack)
        output_padded ,input_sizes = pad_packed_sequence(packed_x, batch_first=True)
        output = self.l_out(output_padded)
        return output

def train(train_loader):
    dl_model.train()
    total_loss = 0
    correct = 0
    for data_list in train_loader:
        # datalist:
        # 0 = data
        # 1 = data shape
        # 2 = label
        optimizer.zero_grad()
        output = dl_model(data_list) # shape = [8, 4, 2]
        y = data_list[2]
        lossmask = create_seq_mask(data_list[1], device)
        loss = (loss_fn(output, y.float()) * lossmask).sum() / lossmask.sum()
        loss.backward()
        total_loss += loss.item()
        with torch.no_grad():
            pred = output[0] 
        correct += pred.eq(y.long()).sum().item()
        optimizer.step()
    return total_loss / len(train_loader), correct / len(train_loader.dataset)


def test(loader):
    dl_model.eval()
    actuals = []
    probabilities = []
    correct = 0
    for data_list in test_loader:
        with torch.no_grad():
            output = dl_model(data_list)
            y = data_list[2]
            pred = output[0]
            actuals.extend(y.cpu().detach().numpy())
        correct += pred.eq(y.long()).sum().item()
    return correct / len(loader.dataset), actuals 

And as far as i can tell, the loss looks like it’s minimising in a way that seams reasonable.
But i should still adjust my accuracy calculations.
But from your perspective, does this look ok (except for the acc calculation)?