Change Conv2D layer on pretrained network for Image Segmentation

Looking at the source code, here it seems that when you are using the function get_model it preloads the set of classes because I am getting this error:

In [23]: model = gluoncv.model_zoo.get_model('deeplab_resnet101_ade', nclass=2)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-23-8a1eb9de3344> in <module>()
----> 1 model = gluoncv.model_zoo.get_model('deeplab_resnet101_ade', nclass=2)

/usr/local/lib/python3.5/dist-packages/gluoncv/model_zoo/model_zoo.py in get_model(name, **kwargs)
    184         err_str += '%s' % ('\n\t'.join(sorted(_models.keys())))
    185         raise ValueError(err_str)
--> 186     net = _models[name](**kwargs)
    187     return net
    188 

/usr/local/lib/python3.5/dist-packages/gluoncv/model_zoo/deeplabv3.py in get_deeplab_resnet101_ade(**kwargs)
    294     >>> print(model)
    295     """
--> 296     return get_deeplab('ade20k', 'resnet101', **kwargs)

/usr/local/lib/python3.5/dist-packages/gluoncv/model_zoo/deeplabv3.py in get_deeplab(dataset, backbone, pretrained, root, ctx, **kwargs)
    175     from ..data import datasets
    176     # infer number of classes
--> 177     model = DeepLabV3(datasets[dataset].NUM_CLASS, backbone=backbone, ctx=ctx, **kwargs)
    178     if pretrained:
    179         from .model_store import get_model_file

TypeError: __init__() got multiple values for argument 'nclass'

The parameter that defines the expected classes for this family of models is nclass, as described here and here. So what you can do, is use an alternative definition for the model you want (use nclass = 2 for a binary classification scheme, default functions in mxnet/gluon behave better):

model  = gluoncv.model_zoo.DeepLabV3(nclass=2,backbone='resnet101',pretrained_base=True)

I tested it with pretrained_base = False, then

In [20]: model.auxlayer
Out[20]: 
_FCNHead(
  (block): HybridSequential(
    (0): Conv2D(1024 -> 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
    (1): BatchNorm(fix_gamma=False, eps=1e-05, axis=1, momentum=0.9, use_global_stats=False, in_channels=256)
    (2): Activation(relu)
    (3): Dropout(p = 0.1, axes=())
    (4): Conv2D(256 -> 2, kernel_size=(1, 1), stride=(1, 1))
  )
)

I don’t know, using this definition, on which dataset this model is trained.

edit alternatively, hack the definition of getting the model:

In [28]: def get_deeplab(nclass, dataset='pascal_voc', backbone='resnet50', pretrained=False,
    ...:             root='~/.mxnet/models', ctx=mx.cpu(0), **kwargs):
    ...:     r"""DeepLabV3
    ...:     Parameters
    ...:     ----------
    ...:     dataset : str, default pascal_voc
    ...:         The dataset that model pretrained on. (pascal_voc, ade20k)
    ...:     pretrained : bool or str
    ...:         Boolean value controls whether to load the default pretrained weights for model.
    ...:         String value represents the hashtag for a certain version of pretrained weights.
    ...:     ctx : Context, default CPU
    ...:         The context in which to load the pretrained weights.
    ...:     root : str, default '~/.mxnet/models'
    ...:         Location for keeping the model parameters.
    ...:     Examples
    ...:     --------
    ...:     >>> model = get_fcn(dataset='pascal_voc', backbone='resnet50', pretrained=False)
    ...:     >>> print(model)
    ...:     """
    ...:     acronyms = {
    ...:         'pascal_voc': 'voc',
    ...:         'pascal_aug': 'voc',
    ...:         'ade20k': 'ade',
    ...:         'coco': 'coco',
    ...:     }
    ...:     #from ..data import datasets
    ...:     # infer number of classes
    ...:     model = gluoncv.model_zoo.DeepLabV3(nclass, backbone=backbone, ctx=ctx, **kwargs)
    ...:     if pretrained:
    ...:         from .model_store import get_model_file
    ...:         model.load_parameters(get_model_file('deeplab_%s_%s'%(backbone, acronyms[dataset]),
    ...:                                              tag=pretrained, root=root), ctx=ctx)
    ...:     return model
    ...: 

In [29]: model = get_deeplab(2,'ade20k', 'resnet101')

In [30]: model.auxlayer
Out[30]: 
_FCNHead(
  (block): HybridSequential(
    (0): Conv2D(1024 -> 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
    (1): BatchNorm(fix_gamma=False, eps=1e-05, axis=1, momentum=0.9, use_global_stats=False, in_channels=256)
    (2): Activation(relu)
    (3): Dropout(p = 0.1, axes=())
    (4): Conv2D(256 -> 2, kernel_size=(1, 1), stride=(1, 1))
  )
)


1 Like