Optimizer.load_state_dict() worsens training process when I continue it

Pratyush: <p>I am training my Segformer model using AdamW optimizer, I trained the model for 100 epochs and then I saved the model and the optimizer state dict. At the time of saving the validation loss was 1.2</p>
<p>Now when I restart the training the validation loss begins with 30.2</p>
<pre><code class="lang-auto">device=torch.device("cuda" if torch.cuda.is_available() else "cpu")
optimizer=torch.optim.AdamW(model.parameters(),lr=5e-3,weight_decay=0.01)
criterion=nn.BCEWithLogitsLoss()
model.to(device)
model.load_state_dict(torch.load('segformer_full/epoch-100.pt',map_location='cuda'))
optimizer.load_state_dict(torch.load('segformer_optimizer/epoch-100.pt',map_location='cuda'))
</code></pre>
<p>Here are the training loop sections-</p>
<pre><code class="lang-auto">for epoch in range(num_epochs):
    model.train()
    train_loss=0
    for i in tqdm(range(len(datagen))):
     training loop....

    model.eval()
    valid_loss=0
    with torch.no_grad():
        for i in tqdm(range(len(datagen)-73)):
            validation loop....

     if valid_loss&lt;best_loss:
        best_loss=valid_loss
        torch.save(model.state_dict(), os.path.join(r'segformer_full', 'epoch-{}.pt'.format(epoch)))
        torch.save(optimizer.state_dict(), os.path.join(r'segformer_optimizer', 'epoch-{}.pt'.format(epoch)))
</code></pre>
<p>Can anyone tell where I am going wrong?</p>

ptrblck: <p>Are you seeing the worse loss value only if you load the model’s <code>state_dict</code> and run the validation loop or do you need to perform a training step with the restored optimizer?</p>

Pratyush: <p>I would like to continue training my model</p>

ptrblck: <p>My suggestion wasn’t to change your workflow, but to use it as a debugging step to check if loading the <code>state_dict</code> of the model already causes the issue while the optimizer might be fine.</p>

Pratyush: <p>If I use optimizer.load_state_dict() alone, validation loss for the first 5 epochs is like this-<br>
45.09<br>
34.47<br>
30.77<br>
37.57<br>
23.28</p>
<p>if I use both model.load_state_dict() and optimizer.load_state_dict() for the first 5 epochs validation loss are as follows-<br>
28.53<br>
39.14<br>
28.32<br>
26.47<br>
21.64</p>

ptrblck: <p>Could you check loading the model’s <code>state_dict</code> alone and executing the validation phase as mentioned before?</p>

Pratyush: <p>using model.load_state_dict() alone it begins at 32.47 and then it was<br>
14.4<br>
15.94<br>
7.11<br>
10.34</p>

ptrblck: <p>So loading the model’s <code>state_dict</code> alone fails already as the last validation loss was:</p>
<blockquote>
<p>At the time of saving the validation loss was 1.2</p>
</blockquote>
<p>In that case I would recommend checking the output of the model before saving with a constant input (e.g. <code>torch.ones</code>) and after restoring it to make sure the parameters are properly loaded. If this fails already you would need to check if some layers are not properly restored by comparing their values.<br>
However, if a static input yields the same results (up to floating point precision errors) you should check the data processing.</p>

Pratyush: <p>Yea, it works now.  Not sure if the issue was with varying validation set or the state_dict was not saved properly.</p>
<p>Maybe the issue was that my validation set was  varying (i.e, every epoch it generated a new set).<br>
I fixed my validation set to a fixed number of samples and I tried again and it worked properly.</p>
<p>Thank You</p>