Unexpected key(s) in state_dict: "model", "opt"
I'm currently using fast.ai to train an image classifier model.

data = ImageDataBunch.single_from_classes(path, classes, ds_tfms=get_transforms(), size=224).normalize(imagenet_stats)
learner = cnn_learner(data, models.resnet34)

learner.model.load_state_dict(
    torch.load('stage-2.pth', map_location="cpu")
)


which results in :


  torch.load('stage-2.pth', map_location="cpu")   File
  "/usr/local/lib/python3.6/site-packages/torch/nn/modules/module.py",
  line 769, in load_state_dict
      self.class.name, "\n\t".join(error_msgs))) RuntimeError: Error(s) in loading state_dict for Sequential:
  
  ...
  
  Unexpected key(s) in state_dict: "model", "opt". 


I have looked around in SO and tried to use the following solution:

# original saved file with DataParallel
state_dict = torch.load('stage-2.pth', map_location="cpu")
# create new OrderedDict that does not contain `module.`
from collections import OrderedDict
new_state_dict = OrderedDict()
for k, v in state_dict.items():
    name = k[7:] # remove `module.`
    new_state_dict[name] = v
# load params
learner.model.load_state_dict(new_state_dict)


which results in :


  RuntimeError: Error(s) in loading state_dict for Sequential:
  
  Unexpected key(s) in state_dict: "".


I'm using Google Colab to train my model and then port the trained model into docker and try to host in in a local server.

What could be the issue? Could it be the different version of pytorch which results in model mismatch?

In my docker config:

# Install pytorch and fastai
RUN pip install torch_nightly -f https://download.pytorch.org/whl/nightly/cpu/torch_nightly.html
RUN pip install fastai


While my Colab is using the following:

 !curl -s https://course.fast.ai/setup/colab | bash


My strong guess is that stage-2.pth contains two top-level items: the model itself (its weights) and the final state of the optimizer which was used to train it. To load just the model, you need only the former. Assuming things were done in the idiomatic PyTorch way, I would try

learner.model.load_state_dict(
    torch.load('stage-2.pth', map_location="cpu")['model']
)


Update: after applying my first round of advice it becomes clear that you're loading a savepoint create with a different (perhaps differently configured?) model than the one you're loading it into. As you can see in the pastebin, the savepoint contains weights for some extra layers, not present in your model, such as bn3, downsample, etc. 


  "0.4.0.bn3.running_var", "0.4.0.bn3.num_batches_tracked", "0.4.0.downsample.0.weight"


at the same time some other key names match, but the tensors are of different shapes.


  size mismatch for 0.5.0.downsample.0.weight: copying a param with shape torch.Size([512, 256, 1, 1]) from checkpoint, the shape in current model is torch.Size([128, 64, 1, 1]).


I see a pattern that you consistently try to load a parameter of shape [2^(x+1), 2^x, 1, 1] in place of [2^(x), 2^(x-1), 1, 1]. Perhaps you're trying to load a model of different depth (ex. loading vgg-16 weights for vgg-11?). Either way, you need to figure out the exact architecture used to create your savepoint and then recreate it before loading the savepoint.

PS. In case you weren't sure - savepoints contain model weights, along with their shapes and (autogenerated) names. They do not contain the full specification of the architecture itself - you need to assure yourself, that you're calling model.load_state_dict with model being of exactly the same architecture as was used to create the savepoint. Otherwise you will likely have weight names mismatching.
