Lesson 5 Advanced Discussion ✅

Update: I could make it work. My next post will describe how.

=================================================

I am trying to import models from the Cadene Pytorch model libraries.
I am trying for 2 days to make create_cnn working, but seems only learn = Learner(data, model) works. create_cnn is much better, but there is something I am missing. I understand that create_cnn expects a callable function and tried the following examples.

Here are working examples:

# this works
def get_model(pretrained=True, model_name = 'resnet50', **kwargs ): # pretrained key should be the first
    arch = models.resnet50(pretrained, **kwargs )
    return arch

learn = Learner(data, get_model(), metrics=[accuracy])

# this works
def get_model(pretrained=True, model_name = 'resnet50', **kwargs ): # pretrained key should be the first
    arch = pretrainedmodels.__dict__[model_name](num_classes=1000, pretrained='imagenet')
    return arch

learn = Learner(data, get_model(), metrics=[accuracy])

Here are not working examples:

# this does not work
def get_model(pretrained=True, model_name = 'resnet50', **kwargs ): # pretrained key should be the first
    arch = pretrainedmodels.__dict__[model_name](num_classes=1000, pretrained='imagenet')
    return arch

learn = Learner(data, get_model, metrics=[accuracy])
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-45-814e6d5c8795> in <module>
      4     return arch
      5 
----> 6 learn = Learner(data, get_model, metrics=[accuracy])

<string> in __init__(self, data, model, opt_func, loss_func, metrics, true_wd, bn_wd, wd, train_bn, path, model_dir, callback_fns, callbacks, layer_groups)

~/anaconda3/envs/fastai-v1/lib/python3.7/site-packages/fastai/basic_train.py in __post_init__(self)
    145         self.path = Path(ifnone(self.path, self.data.path))
    146         (self.path/self.model_dir).mkdir(parents=True, exist_ok=True)
--> 147         self.model = self.model.to(self.data.device)
    148         self.loss_func = ifnone(self.loss_func, self.data.loss_func)
    149         self.metrics=listify(self.metrics)

AttributeError: 'function' object has no attribute 'to'

# this does not work
def get_model(pretrained=True, model_name = 'resnet50',  **kwargs ): # pretrained key should be the first
    arch = pretrainedmodels.__dict__[model_name](num_classes=1000, pretrained='imagenet')
    return arch

learn = create_cnn(data, get_model(), metrics=[accuracy])
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-43-74cb1e5cde9c> in <module>
      4     return arch
      5 
----> 6 learn = create_cnn(data, get_model(), metrics=[accuracy])

~/anaconda3/envs/fastai-v1/lib/python3.7/site-packages/fastai/vision/learner.py in create_cnn(data, arch, cut, pretrained, lin_ftrs, ps, custom_head, split_on, bn_final, **kwargs)
     53     "Build convnet style learners."
     54     meta = cnn_config(arch)
---> 55     body = create_body(arch, pretrained, cut)
     56     nf = num_features_model(body) * 2
     57     head = custom_head or create_head(nf, data.c, lin_ftrs, ps=ps, bn_final=bn_final)

~/anaconda3/envs/fastai-v1/lib/python3.7/site-packages/fastai/vision/learner.py in create_body(arch, pretrained, cut, body_fn)
     30 def create_body(arch:Callable, pretrained:bool=True, cut:Optional[int]=None, body_fn:Callable[[nn.Module],nn.Module]=None):
     31     "Cut off the body of a typically pretrained `model` at `cut` or as specified by `body_fn`."
---> 32     model = arch(pretrained)
     33     if not cut and not body_fn: cut = cnn_config(arch)['cut']
     34     return (nn.Sequential(*list(model.children())[:cut]) if cut

~/anaconda3/envs/fastai-v1/lib/python3.7/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
    487             result = self._slow_forward(*input, **kwargs)
    488         else:
--> 489             result = self.forward(*input, **kwargs)
    490         for hook in self._forward_hooks.values():
    491             hook_result = hook(self, input, result)

~/anaconda3/envs/fastai-v1/lib/python3.7/site-packages/pretrainedmodels/models/torchvision_models.py in forward(self, input)
    338 
    339     def forward(self, input):
--> 340         x = self.features(input)
    341         x = self.logits(x)
    342         return x

~/anaconda3/envs/fastai-v1/lib/python3.7/site-packages/pretrainedmodels/models/torchvision_models.py in features(self, input)
    320 
    321     def features(self, input):
--> 322         x = self.conv1(input)
    323         x = self.bn1(x)
    324         x = self.relu(x)

~/anaconda3/envs/fastai-v1/lib/python3.7/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
    487             result = self._slow_forward(*input, **kwargs)
    488         else:
--> 489             result = self.forward(*input, **kwargs)
    490         for hook in self._forward_hooks.values():
    491             hook_result = hook(self, input, result)

~/anaconda3/envs/fastai-v1/lib/python3.7/site-packages/torch/nn/modules/conv.py in forward(self, input)
    318     def forward(self, input):
    319         return F.conv2d(input, self.weight, self.bias, self.stride,
--> 320                         self.padding, self.dilation, self.groups)
    321 
    322 

TypeError: conv2d(): argument 'input' (position 1) must be Tensor, not bool

# this does not work
def get_model(pretrained=True, model_name = 'resnet50',  **kwargs ): # pretrained key should be the first
    arch = pretrainedmodels.__dict__[model_name](num_classes=1000, pretrained='imagenet')
    return arch

learn = create_cnn(data, get_model, metrics=[accuracy])
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-44-86a48fcf2401> in <module>
      4     return arch
      5 
----> 6 learn = create_cnn(data, get_model, metrics=[accuracy])

~/anaconda3/envs/fastai-v1/lib/python3.7/site-packages/fastai/vision/learner.py in create_cnn(data, arch, cut, pretrained, lin_ftrs, ps, custom_head, split_on, bn_final, **kwargs)
     54     meta = cnn_config(arch)
     55     body = create_body(arch, pretrained, cut)
---> 56     nf = num_features_model(body) * 2
     57     head = custom_head or create_head(nf, data.c, lin_ftrs, ps=ps, bn_final=bn_final)
     58     model = nn.Sequential(body, head)

~/anaconda3/envs/fastai-v1/lib/python3.7/site-packages/fastai/callbacks/hooks.py in num_features_model(m)
    115 def num_features_model(m:nn.Module)->int:
    116     "Return the number of output features for `model`."
--> 117     return model_sizes(m)[-1][1]
    118 
    119 def total_params(m:nn.Module)->int:

~/anaconda3/envs/fastai-v1/lib/python3.7/site-packages/fastai/callbacks/hooks.py in model_sizes(m, size)
    110     "Pass a dummy input through the model `m` to get the various sizes of activations."
    111     with hook_outputs(m) as hooks:
--> 112         x = dummy_eval(m, size)
    113         return [o.stored.shape for o in hooks]
    114 

~/anaconda3/envs/fastai-v1/lib/python3.7/site-packages/fastai/callbacks/hooks.py in dummy_eval(m, size)
    105 def dummy_eval(m:nn.Module, size:tuple=(64,64)):
    106     "Pass a `dummy_batch` in evaluation mode in `m` with `size`."
--> 107     return m.eval()(dummy_batch(m, size))
    108 
    109 def model_sizes(m:nn.Module, size:tuple=(64,64))->Tuple[Sizes,Tensor,Hooks]:

~/anaconda3/envs/fastai-v1/lib/python3.7/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
    487             result = self._slow_forward(*input, **kwargs)
    488         else:
--> 489             result = self.forward(*input, **kwargs)
    490         for hook in self._forward_hooks.values():
    491             hook_result = hook(self, input, result)

~/anaconda3/envs/fastai-v1/lib/python3.7/site-packages/torch/nn/modules/container.py in forward(self, input)
     90     def forward(self, input):
     91         for module in self._modules.values():
---> 92             input = module(input)
     93         return input
     94 

~/anaconda3/envs/fastai-v1/lib/python3.7/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
    487             result = self._slow_forward(*input, **kwargs)
    488         else:
--> 489             result = self.forward(*input, **kwargs)
    490         for hook in self._forward_hooks.values():
    491             hook_result = hook(self, input, result)

~/anaconda3/envs/fastai-v1/lib/python3.7/site-packages/torch/nn/modules/pooling.py in forward(self, input)
    563     def forward(self, input):
    564         return F.avg_pool2d(input, self.kernel_size, self.stride,
--> 565                             self.padding, self.ceil_mode, self.count_include_pad)
    566 
    567 

RuntimeError: Given input size: (2048x2x2). Calculated output size: (2048x-4x-4). Output size is too small at /opt/conda/conda-bld/pytorch_1544202130060/work/aten/src/THNN/generic/SpatialAveragePooling.c:48

A working example shared here to import any Cadene model is very helpful. It will expand the usable models in fastai for everybody. I heard in Kaggle competitions that there are people could make it work with fastai v1, but could not do it myself. Here is an 8th Kaggle winner in Human Protein Atlas comp. that just did that!

2 Likes