Forward() got an unexpected keyword argument 'pretrained'

Hi,

I want to train a UNet for some image reconstruction. I wrote the following dataloader:

train_ds = data_gen(X_train)
test_ds = data_gen(X_test)
batch_size = 8
dls = DataLoaders.from_dsets(train_ds, test_ds, bs=batch_size, device='cuda:0')

And the following model:

encoder = fastai.vision.models.resnet34(pretrained=False).cuda()
encoder = nn.Sequential(*list(encoder.children())[:-2])

encoder.add_module('encode_1',nn.Conv2d(512, 32, kernel_size=2, stride=2).cuda())
encoder.add_module('RelU_1', nn.ReLU().cuda())
encoder.add_module('batchnorm_1', nn.BatchNorm2d(32).cuda())

encoder.add_module('encode_2',nn.Conv2d(32, 8, kernel_size=2, stride=2).cuda())
encoder.add_module('RelU_2', nn.ReLU().cuda())
encoder.add_module('batchnorm_2', nn.BatchNorm2d(8).cuda())

encoder.add_module('encode_3',nn.Conv2d(8,2, kernel_size=4).cuda())
encoder.add_module('RelU_3', nn.ReLU().cuda())
encoder.add_module('batchnorm_3', nn.BatchNorm2d(2).cuda())

When I run tst = unet_learner(dls,arch=encoder,loss_func = nn.MSELoss), I get the following:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-14-1a4291b9715f> in <module>
----> 1 tst = unet_learner(dls,arch=encoder,loss_func = nn.MSELoss)

~/anaconda3/envs/fastai/lib/python3.8/site-packages/fastcore/utils.py in _f(*args, **kwargs)
    467         log_dict = {**func_args.arguments, **{f'{k} (not in signature)':v for k,v in xtra_kwargs.items()}}
    468         log = {f'{f.__qualname__}.{k}':v for k,v in log_dict.items() if k not in but}
--> 469         inst = f(*args, **kwargs) if to_return else args[0]
    470         init_args = getattr(inst, 'init_args', {})
    471         init_args.update(log)

~/anaconda3/envs/fastai/lib/python3.8/site-packages/fastai/vision/learner.py in unet_learner(dls, arch, loss_func, pretrained, cut, splitter, config, n_in, n_out, normalize, **kwargs)
    192     if config is None: config = unet_config()
    193     meta = model_meta.get(arch, _default_meta)
--> 194     body = create_body(arch, n_in, pretrained, ifnone(cut, meta['cut']))
    195     size = dls.one_batch()[0].shape[-2:]
    196     if n_out is None: n_out = get_c(dls)

~/anaconda3/envs/fastai/lib/python3.8/site-packages/fastai/vision/learner.py in create_body(arch, n_in, pretrained, cut)
     63 def create_body(arch, n_in=3, pretrained=True, cut=None):
     64     "Cut off the body of a typically pretrained `arch` as determined by `cut`"
---> 65     model = arch(pretrained=pretrained)
     66     _update_first_layer(model, n_in, pretrained)
     67     #cut = ifnone(cut, cnn_config(arch)['cut'])

~/anaconda3/envs/fastai/lib/python3.8/site-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
    720             result = self._slow_forward(*input, **kwargs)
    721         else:
--> 722             result = self.forward(*input, **kwargs)
    723         for hook in itertools.chain(
    724                 _global_forward_hooks.values(),

TypeError: forward() got an unexpected keyword argument 'pretrained'

I don’t know why I am getting this. I even tried to use fastai.vision.models.resnet34() and I still get the error.

1 Like

Please try
model = fastai.vision.models.resnet34
and pass it to the learner.
Check type(resnet34) and type(resnet34()) to see the difference.

Regards
Evo

1 Like

So I tried resnet34 and it seems to get rid of the error. But what if I have a custom network, let’s say I added some layers to the network. Then what should I do?

I think that cnn_learner expects a function to construct a model and not a model architecture. If you want to change the model you need to build a function, to construct that changed model. This approach worked for me:

def get_model(model, pretrained=False, progress=True, **kwargs):
    """model: function to load the model, e.g. resnet18
        pretrained, progress: to be passed to the model function
    """
    m = model(pretrained=pretrained, progress=progress, **kwargs) # loads standard model
    m.avgpool = nn.AdaptiveAvgPool2d(output_size=(100,100)) # changes one layer
    return m

You can then pass this to the learner.

learn = cnn_learner(dls, partial(get_model, model=resnet18))

3 Likes