Load model from pth file

Hello,

I have saved a model with learn.save() function, and copied the resulting pth file to an offline computer. I wish to use it in a new cnn model, just as we use resnet34 in the first lesson. However, I cannot find a way to load the model. The function learn.load() needs the learn object to already be a model.

How do I load this model from pth file into a functional ‘callable’, which can be used by the create_cnn function?

Thanks in advance.

3 Likes

Hi Kristin, I had the same problem. You need to first create the network, e.g. by
learn=create_cnn(data, models.resnet34, metrics=error_rate)

then you can load the trained weights, e.g.
learn.load(path/‘models/stage3’)

(note, you don’t need to include .pth).
Hope this helps!

5 Likes

Hi luca, thanks for your answer.

My offline computer is down for the time being, so I don’t get to test this just now. However, I am not sure how to move the trained model from my online computer to the offline one without the pth file. There needs to be some kind of file transfer, and then some way to create or load the model with offline resources.

On my offline computer I have cloned the anaconda environment with fastai, so I can access the libraries. However, online resources are beyond reach. I wish to move my trained models (trained on an online computer) to the offline computer and then train some more on a specific dataset.

I will come back when my offline computer is up and running again.

This way of loading is bit tedious , since you have to copy the train/test data and the .pth to production systems or other computer . Is there a better way like only copy the .pth without the train/test data ? @StatisticDean / @muellerzr.
OR
one have to always export learn.export and create a .pkl file then share it with someone to
do the below

def load_model():
    path = 'models'
    learn = load_learner(path, 'model.pkl')
    return learn
3 Likes

@jbo the second way is how I’d recommend as the export loads a blank train and validation and then you can load your test or load in any databunch you want to use.

With this approach I faced a problem , my old model was trained on a dataset which was imbalanced and the accuracy I obtained with that model was 87% however after loading that old model and creating a data bunch which distributed the train and valid again , the accuracy jumped to 95% [which I think is cheating]

does this apply to a .pth file? Im trying to create a learner from a pth file to make a single image prediction test. How do I do that @jbo

1 Like

In case your Learn object is destroyed, you have to create the learn object from start. Similar to what Zachary has mentioned.

@jbo have you solved the accuracy issue where the reloaded model suddenly has a higher accuracy?

Hi.

I used this learn = load_learner('model_max.pth', cpu=False) to load my model and all it loads is a dictionary that contains the weights and biases. How should I proceed? This is what the dictionary contains:
dict_keys(['model', 'opt'])

2 Likes

it looks like below breaks for all dual_path_networks. I tried implementation from cadene and rwightman

load_learner(f’weights/models/{dpn_arch_weight}.pkl’)

Above yield below error on fastai v2.5.2

File “…lib/python3.8/site-packages/fastai/learner.py”, line 384, in load_learner
res = torch.load(fname, map_location=‘cpu’ if cpu else None, pickle_module=pickle_module)
File “…lib/python3.8/site-packages/torch/serialization.py”, line 592, in load
return _load(opened_zipfile, map_location, pickle_module, **pickle_load_args)
File “…lib/python3.8/site-packages/torch/serialization.py”, line 851, in _load
result = unpickler.load()
AttributeError: Can’t get attribute ‘dpn98’ on <module ‘main’ from ‘…lib/python3.8/site-packages/ray/workers/default_worker.py’>

@muellerzr any ideas here

So, got a fix for this
I had to ensure the exact function used for he model during training was also available

e.g., for dpn98, I used weights from https://github.com/Cadene/pretrained-models.pytorch … so, I needed to have the function below in the main module from which I started the inference execution

During training, I used below

import pretrainedmodels
from fastai import *
from fastai.vision.all import *

def dpn131(pretrained=False):
pretrained = ‘imagenet’ if pretrained else None
model = pretrainedmodels.dpn131(pretrained=pretrained)
return nn.Sequential(*list(model.children()))

For inference, I just needed to ensure the function is defined/accessible from same main module

def dpn131(pretrained=False):
pass

PS: I have switched to using https://github.com/rwightman/pytorch-image-models/ now though as it is much friendlier with fastai library, and equally contains much more model architectures

I load the .pth model in this way:

# The path of the model without '.pth'.
model_path = 'model_0.871_VGG16_30epochs'
# The dataset path that you have used for training the (.pth) model.
dataset_path_ = '/content/drive/MyDrive/Datasets/brain_mri/brain_mri'
# Set the inputs that you have used for training the (.pth) model.
input_images_size = 224
pretrained_model = vgg16_bn
metrics = accuracy
transformers = [Flip(p=0.25),
                Rotate(max_deg=10, p=0.25),
                Warp(magnitude=0.2, p=0.25),
                Contrast(max_lighting=0.2, p=0.25),
                Brightness(max_lighting=0.1,p=0.25),
                Zoom(min_zoom=1.0,max_zoom=1.2,p=0.25)]
dls = ImageDataLoaders.from_folder(dataset_path_, 
                                           item_tfms=Resize(input_images_size),
                                           batch_tfms=transformers)
# Make a learner like you've created before.
learn = cnn_learner(dls, pretrained_model, metrics=metrics)
# Give .pth path to load() and load your model.
learn = learn.load(model_path)