I cannot reproduce this issue using these scripts:
# script1.py
import torch
import torch.nn as nn

class Network(nn.Module):
    def __init__(self):
        super(Network, self).__init__()
        self.fc1 = nn.Linear(in_features = 41, out_features = 12) 
        self.fc2 = nn.Linear(in_features = 12, out_features = 18)
        self.out = nn.Linear(in_features = 18, out_features = 23) 
    def forward(self, t):
        t = F.relu(self.fc1(t))
        t = F.relu(self.fc2(t))
        t = self.out(t)
        return t

# Setup
device = 'cuda'
model = Network().to(device)
data = torch.randn(32, 41).to(device)
target = torch.randint(0, 23, (32,)).to(device)
optimizer = torch.optim.SGD(model.parameters(), lr=1e-3)
criterion = nn.CrossEntropyLoss()

# Train on random data
nb_epochs = 100
for epoch in range(nb_epochs):
    optimizer.zero_grad()
    output = model(data)
    loss = criterion(output, target)
    loss.backward()
    optimizer.step()
    print('epocj {}, loss {}'.format(epoch, loss.item()))

# Save
model.eval() # not necessary for your model
output = model(data)
checkpoint = {
    'model': model.state_dict(),
    'data': data,
    'target': target,
    'loss': loss,
    'output': output}
torch.save(checkpoint, 'tmp.pth')

# script2.py
checkpoint = torch.load('tmp.pth')
model = Network()
model.load_state_dict(checkpoint['model'])

data = checkpoint['data']
target = checkpoint['target']
output_reference = checkpoint['output']
loss_reference = checkpoint['loss']

criterion = nn.CrossEntropyLoss()
output_restored = model(data)
loss_restored = criterion(output_restored, target)

print('abs err output ', (output_restored - output_reference).abs().max())
> abs err output  tensor(0., device='cuda:0', grad_fn=<MaxBackward1>)
print('err loss ', (loss_restored - loss_reference).abs().max())
> err loss  tensor(0.0001, device='cuda:0', grad_fn=<MaxBackward1>)

Could you compare your code to mine and check for differences?