Menu

Helper Module for Deep Learning.

Source code for pynet.models.torchvisnet

# -*- coding: utf-8 -*-
##########################################################################
# NSAp - Copyright (C) CEA, 2019 - 2020
# Distributed under the terms of the CeCILL-B license, as published by
# the CEA-CNRS-INRIA. Refer to the LICENSE file or to
# http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
# for details.
##########################################################################


"""
Import classifier models defined in torchvision.
"""

# Imports
import re
import sys
import torch.nn as nn
from torchvision import models
from pynet.interfaces import DeepLearningDecorator
from pynet.utils import Networks


[docs]@Networks.register @DeepLearningDecorator(family="classifier") class VGG(models.VGG): """ VGGNet (2014) by Simonyan and Zisserman. """
[docs] def __init__(self, cfg, num_classes, batch_norm=False, init_weights=True, pretrained=None, make_layers=models.vgg.make_layers): """ Class initilization. Parameters ---------- cfg: list the model features: output channels number for convolution or 'M' for max pooling. num_classes: int the number of classes to predict. batch_norm: bool, default False use batch normalization after each convolution. init_weights: bool, default True initialize the model weights. pretrained: str, default None update the weights of the model using this state information. make_layers: @func a function to create the feature layers: default 2d max pooling with kernel size 2 and stride 2, and convolution with kernel size 3 and padding 1. """ models.VGG.__init__( self, features=make_layers(cfg, batch_norm=batch_norm), num_classes=num_classes, init_weights=init_weights)
[docs]@Networks.register @DeepLearningDecorator(family="classifier") class DenseNet(models.DenseNet): """ DenseNet. """
[docs] def __init__(self, growth_rate, block_config, num_init_features, num_classes, bn_size=4, drop_rate=0, memory_efficient=False): """ Class initilization. Parameters ---------- growth_rate: int how many filters to add each layer ('k' in paper). block_config: 1-uplet how many layers in each pooling block. num_init_features: int the number of filters to learn in the first convolution layer. num_classes: int number of classification classes. bn_size: int, default 4 multiplicative factor for number of bottle neck layers (i.e. bn_size * k features in the bottleneck layer). drop_rate: float, default 0 dropout rate after each dense layer. memory_efficient: bool, default False if True, uses checkpointing. Much more memory efficient, but slower. """ models.DenseNet.__init__( self, growth_rate=growth_rate, block_config=block_config, num_init_features=num_init_features, bn_size=bn_size, drop_rate=drop_rate, num_classes=num_classes, memory_efficient=memory_efficient)
[docs]@Networks.register @DeepLearningDecorator(family="classifier") class ResNet(models.ResNet): """ Residual Neural Network (ResNet) by Kaiming He et al. """
[docs] def __init__(self, block, layers, num_classes, zero_init_residual=False, groups=1, width_per_group=64, replace_stride_with_dilation=None, norm_layer=None): """ Class initilization. Parameters ---------- block: nn Module one block architecture. layers: 4-uplet control the number of element in each layer. num_classes: int number of classification classes. zero_init_residual: bool, default False zero-initialize the last BN in each residual branch, so that the residual branch starts with zeros, and each residual block behaves like an identity. groups: int, default 1 controls the connections between inputs and outputs during convolution. width_per_group: int, default 64 control the number of input and output channels during convolution. replace_stride_with_dilation: uplet, default None each element in the tuple indicates if we should replace the 2x2 stride with a dilated convolution instead. norm_layer: nn Module, default None use the specified normalization module, by default use batch normalization. """ models.ResNet.__init__( self, block=block, layers=layers, num_classes=num_classes, zero_init_residual=zero_init_residual, groups=groups, width_per_group=width_per_group, replace_stride_with_dilation=replace_stride_with_dilation, norm_layer=norm_layer)
[docs]@Networks.register @DeepLearningDecorator(family="classifier") class Inception3(models.Inception3): """ Inception v3 by Google. """
[docs] def __init__(self, num_classes, aux_logits=True, transform_input=False): """ Class initilization. Parameters ---------- num_classes: int number of classification classes. aux_logits: bool, default False auxiliary classifier for the training. transform_input: bool, default False normalize the data. """ models.Inception3.__init__( self, num_classes=num_classes, aux_logits=aux_logits, transform_input=transform_input)
[docs]def class_factory(klass_name, klass_params, destination_module_globals): """ Dynamically overload a class. In order to make the class publicly accessible, we assign the result of the function to a variable dynamically using globals(). Parameters ---------- klass_name: str the class name that will be created. klass_params: dict the class specific parameters. """ class VGGBase(VGG): """ VGGNet X-layer. """ cfg = None def __init__(self, num_classes, batch_norm=False, init_weights=True): if self.cfg is None: raise ValueError("Please specify a configuration first.") VGG.__init__( self, cfg=self.cfg, num_classes=num_classes, batch_norm=batch_norm, init_weights=init_weights) class DenseNetBase(DenseNet): """ DenseNet-X model. """ growth_rate = None block_config = None num_init_features = None def __init__(self, num_classes, bn_size=4, drop_rate=0, memory_efficient=False): for name in ("growth_rate", "block_config", "num_init_features"): if getattr(self, name) is None: raise ValueError( "Please specify '{0}' first.".format(name)) DenseNet.__init__( self, growth_rate=self.growth_rate, block_config=self.block_config, num_init_features=self.num_init_features, num_classes=num_classes, bn_size=bn_size, drop_rate=drop_rate, memory_efficient=memory_efficient) class ResNetBase(ResNet): """ ResNet-X model. """ block = None layers = None groups = 1 width_per_group = 64 def __init__(self, num_classes, zero_init_residual=False, groups=1, width_per_group=64, replace_stride_with_dilation=None, norm_layer=None): for name in ("block", "layers"): if getattr(self, name) is None: raise ValueError( "Please specify '{0}' first.".format(name)) ResNet.__init__( self, block=self.block, layers=self.layers, num_classes=num_classes, zero_init_residual=zero_init_residual, groups=groups, width_per_group=width_per_group, replace_stride_with_dilation=replace_stride_with_dilation, norm_layer=norm_layer) for klass, ref_klass in ((VGGBase, VGG), (DenseNetBase, DenseNet), (ResNetBase, ResNet)): klass.__doc__ = ref_klass.__doc__ klass.__init__.__doc__ = ref_klass.__init__.__doc__ klass_map = { "VGG": VGGBase, "DenseNet": DenseNetBase, "ResNet": ResNetBase } klass_params.update({ "__module__": destination_module_globals["__name__"], "_id": destination_module_globals["__name__"] + "." + klass_name }) klass_base_name = re.findall(r"([a-zA-Z]+)[0-9]+", klass_name)[0] decorator = DeepLearningDecorator(family="classifier") destination_module_globals[klass_name] = Networks.register(decorator( type(klass_name, (klass_map[klass_base_name], ), klass_params)))
CFG = { "VGG11": { "cfg": [64, "M", 128, "M", 256, 256, "M", 512, 512, "M", 512, 512, "M"] }, "VGG13": { "cfg": [64, 64, "M", 128, 128, "M", 256, 256, "M", 512, 512, "M", 512, 512, "M"] }, "VGG16": { "cfg": [64, 64, "M", 128, 128, "M", 256, 256, 256, "M", 512, 512, 512, "M", 512, 512, 512, "M"] }, "VGG19": { "cfg": [64, 64, "M", 128, 128, "M", 256, 256, 256, 256, "M", 512, 512, 512, 512, "M", 512, 512, 512, 512, "M"] }, "DenseNet121": { "growth_rate": 32, "block_config": (6, 12, 24, 16), "num_init_features": 64 }, "DenseNet161": { "growth_rate": 48, "block_config": (6, 12, 36, 24), "num_init_features": 96 }, "DenseNet169": { "growth_rate": 32, "block_config": (6, 12, 32, 32), "num_init_features": 64 }, "DenseNet201": { "growth_rate": 32, "block_config": (6, 12, 48, 32), "num_init_features": 64 }, "ResNet18": { "block": models.resnet.BasicBlock, "layers": [2, 2, 2, 2] }, "ResNet34": { "block": models.resnet.BasicBlock, "layers": [3, 4, 6, 3] }, "ResNet50x32x4d": { "block": models.resnet.Bottleneck, "layers": [3, 4, 6, 3], "groups": 32, "width_per_group": 4 }, "ResNet50Wide": { "block": models.resnet.Bottleneck, "layers": [3, 4, 6, 3], "width_per_group": 64 * 2 }, "ResNet50": { "block": models.resnet.Bottleneck, "layers": [3, 4, 6, 3] }, "ResNet101": { "block": models.resnet.Bottleneck, "layers": [3, 4, 23, 3] }, "ResNet101x32x8d": { "block": models.resnet.Bottleneck, "layers": [3, 4, 23, 3], "groups": 32, "width_per_group": 8 }, "ResNet101Wide": { "block": models.resnet.Bottleneck, "layers": [3, 4, 23, 3], "width_per_group": 64 * 2 }, "ResNet152": { "block": models.resnet.Bottleneck, "layers": [3, 8, 36, 3] }, } destination_module_globals = globals() for klass_name, klass_params in CFG.items(): class_factory(klass_name, klass_params, destination_module_globals)

Follow us

© 2019, pynet developers .
Inspired by AZMIND template.