def __init__(self, structure, norm_act=ABN, classes=0): """Wider ResNet with pre-activation (identity mapping) blocks Parameters ---------- structure : list of int Number of residual blocks in each of the six modules of the network. norm_act : callable Function to create normalization / activation Module. classes : int If not `0` also include global average pooling and a fully-connected layer with `classes` outputs at the end of the network. """ super(WiderResNet, self).__init__() self.structure = structure if len(structure) != 6: raise ValueError("Expected a structure with six values") # Initial layers self.mod1 = nn.Sequential( OrderedDict([("conv1", nn.Conv2d(3, 64, 3, stride=1, padding=1, bias=False))])) # Groups of residual blocks in_channels = 64 channels = [(128, 128), (256, 256), (512, 512), (512, 1024), (512, 1024, 2048), (1024, 2048, 4096)] for mod_id, num in enumerate(structure): # Create blocks for module blocks = [] for block_id in range(num): blocks.append(("block%d" % (block_id + 1), IdentityResidualBlock(in_channels, channels[mod_id], norm_act=norm_act))) # Update channels and p_keep in_channels = channels[mod_id][-1] # Create module if mod_id <= 4: self.add_module("pool%d" % (mod_id + 2), nn.MaxPool2d(3, stride=2, padding=1)) self.add_module("mod%d" % (mod_id + 2), nn.Sequential(OrderedDict(blocks))) # Pooling and predictor self.bn_out = norm_act(in_channels) if classes != 0: self.classifier = nn.Sequential( OrderedDict([("avg_pool", GlobalAvgPool2d()), ("fc", nn.Linear(in_channels, classes))]))
def __init__(self, structure, norm_act=ABN, input_3x3=False, growth=32, theta=0.5, classes=0, dilation=1): """DenseNet Parameters ---------- structure : list of int Number of layers in each of the four dense blocks of the network. norm_act : callable Function to create normalization / activation Module. input_3x3 : bool If `True` use three `3x3` convolutions in the input module instead of a single `7x7` one. growth : int Number of channels in each layer, i.e. the "growth" factor of the DenseNet. theta : float Reduction factor for the transition blocks. classes : int If not `0` also include global average pooling and a fully-connected layer with `classes` outputs at the end of the network. dilation : int or list of int List of dilation factors, or `1` to ignore dilation. If the dilation factor for a module is greater than `1` skip the pooling in the transition block right before it. """ super(DenseNet, self).__init__() self.structure = structure if len(structure) != 4: raise ValueError("Expected a structure with four values") # Initial layers if input_3x3: layers = [("conv1", nn.Conv2d(3, growth * 2, 3, stride=2, padding=1, bias=False)), ("bn1", norm_act(growth * 2)), ("conv2", nn.Conv2d(growth * 2, growth * 2, 3, stride=1, padding=1, bias=False)), ("bn2", norm_act(growth * 2)), ("conv3", nn.Conv2d(growth * 2, growth * 2, 3, stride=1, padding=1, bias=False)), ("pool", nn.MaxPool2d(3, stride=2, padding=1))] else: layers = [("conv1", nn.Conv2d(3, growth * 2, 7, stride=2, padding=3, bias=False)), ("pool", nn.MaxPool2d(3, stride=2, padding=1))] self.mod1 = nn.Sequential(OrderedDict(layers)) in_channels = growth * 2 for mod_id in range(4): d = try_index(dilation, mod_id) s = 2 if d == 1 and mod_id > 0 else 1 # Create transition module if mod_id > 0: out_channels = int(in_channels * theta) layers = [("bn", norm_act(in_channels)), ("conv", nn.Conv2d(in_channels, out_channels, 1, bias=False))] if s == 2: layers.append(("pool", nn.AvgPool2d(2, 2))) self.add_module("tra%d" % (mod_id + 1), nn.Sequential(OrderedDict(layers))) in_channels = out_channels # Create dense module mod = DenseModule(in_channels, growth, structure[mod_id], norm_act=norm_act, dilation=d) self.add_module("mod%d" % (mod_id + 2), mod) in_channels = mod.out_channels # Pooling and predictor self.bn_out = norm_act(in_channels) if classes != 0: self.classifier = nn.Sequential( OrderedDict([("avg_pool", GlobalAvgPool2d()), ("fc", nn.Linear(in_channels, classes))]))
def __init__(self, structure, groups=64, norm_act=ABN, input_3x3=False, classes=0, dilation=1, base_channels=(128, 128, 256)): """Pre-activation (identity mapping) ResNeXt model Parameters ---------- structure : list of int Number of residual blocks in each of the four modules of the network. groups : int Number of groups in each ResNeXt block norm_act : callable Function to create normalization / activation Module. input_3x3 : bool If `True` use three `3x3` convolutions in the input module instead of a single `7x7` one. classes : int If not `0` also include global average pooling and a fully-connected layer with `classes` outputs at the end of the network. dilation : list of list of int or list of int or int List of dilation factors, or `1` to ignore dilation. For each module, if a single value is given it is used for all its blocks, otherwise this expects a value for each block. base_channels : list of int Channels in the blocks of the first residual module. Each following module will multiply these values by 2. """ super(ResNeXt, self).__init__() self.structure = structure if len(structure) != 4: raise ValueError("Expected a structure with four values") if dilation != 1 and len(dilation) != 4: raise ValueError( "If dilation is not 1 it must contain four values") # Initial layers if input_3x3: layers = [ ("conv1", nn.Conv2d(3, 64, 3, stride=2, padding=1, bias=False)), ("bn1", norm_act(64)), ("conv2", nn.Conv2d(64, 64, 3, stride=1, padding=1, bias=False)), ("bn2", norm_act(64)), ("conv3", nn.Conv2d(64, 64, 3, stride=1, padding=1, bias=False)), ("pool", nn.MaxPool2d(3, stride=2, padding=1)) ] else: layers = [("conv1", nn.Conv2d(3, 64, 7, stride=2, padding=3, bias=False)), ("pool", nn.MaxPool2d(3, stride=2, padding=1))] self.mod1 = nn.Sequential(OrderedDict(layers)) # Groups of residual blocks in_channels = 64 channels = base_channels for mod_id, num in enumerate(structure): # Create blocks for module blocks = [] for block_id in range(num): s, d = self._stride_dilation(mod_id, block_id, dilation) blocks.append(("block%d" % (block_id + 1), IdentityResidualBlock(in_channels, channels, stride=s, norm_act=norm_act, groups=groups, dilation=d))) # Update channels in_channels = channels[-1] # Create and add module self.add_module("mod%d" % (mod_id + 2), nn.Sequential(OrderedDict(blocks))) channels = [c * 2 for c in channels] # Pooling and predictor self.bn_out = norm_act(in_channels) if classes != 0: self.classifier = nn.Sequential( OrderedDict([("avg_pool", GlobalAvgPool2d()), ("fc", nn.Linear(in_channels, classes))]))
def __init__(self, structure, norm_act=ABN, classes=0, dilation=False): """Wider ResNet with pre-activation (identity mapping) blocks This variant uses down-sampling by max-pooling in the first two blocks and by strided convolution in the others. Parameters ---------- structure : list of int Number of residual blocks in each of the six modules of the network. norm_act : callable Function to create normalization / activation Module. classes : int If not `0` also include global average pooling and a fully-connected layer with `classes` outputs at the end of the network. dilation : bool If `True` apply dilation to the last three modules and change the down-sampling factor from 32 to 8. """ super(WiderResNetA2, self).__init__() self.structure = structure self.dilation = dilation if len(structure) != 6: raise ValueError("Expected a structure with six values") # Initial layers self.mod1 = nn.Sequential(OrderedDict([ ("conv1", nn.Conv2d(3, 64, 3, stride=1, padding=1, bias=False)) ])) # Groups of residual blocks in_channels = 64 channels = [(128, 128), (256, 256), (512, 512), (512, 1024), (512, 1024, 2048), (1024, 2048, 4096)] for mod_id, num in enumerate(structure): # Create blocks for module blocks = [] for block_id in range(num): if not dilation: dil = 1 stride = 2 if block_id == 0 and 2 <= mod_id <= 4 else 1 else: if mod_id == 3: dil = 2 elif mod_id > 3: dil = 4 else: dil = 1 stride = 2 if block_id == 0 and mod_id == 2 else 1 if mod_id == 4: drop = partial(nn.Dropout2d, p=0.3) elif mod_id == 5: drop = partial(nn.Dropout2d, p=0.5) else: drop = None blocks.append(( "block%d" % (block_id + 1), IdentityResidualBlock(in_channels, channels[mod_id], norm_act=norm_act, stride=stride, dilation=dil, dropout=drop) )) # Update channels and p_keep in_channels = channels[mod_id][-1] # Create module if mod_id < 2: self.add_module("pool%d" % (mod_id + 2), nn.MaxPool2d(3, stride=2, padding=1)) self.add_module("mod%d" % (mod_id + 2), nn.Sequential(OrderedDict(blocks))) # Pooling and predictor self.bn_out = norm_act(in_channels) if classes != 0: self.classifier = nn.Sequential(OrderedDict([ ("avg_pool", GlobalAvgPool2d()), ("fc", nn.Linear(in_channels, classes)) ]))
def __init__(self, structure, bottleneck, norm_act=nn.BatchNorm2d, classes=0, output_stride=16, keep_outputs=False): super(ResNet, self).__init__() self.structure = structure self.bottleneck = bottleneck self.keep_outputs = keep_outputs if len(structure) != 4: raise ValueError("Expected a structure with four values") if output_stride != 8 and output_stride != 16: raise ValueError("Output stride must be 8 or 16") if output_stride == 16: dilation = [1, 1, 1, 2] # dilated conv for last 3 blocks (9 layers) elif output_stride == 8: dilation = [1, 1, 2, 4] # 23+3 blocks (78 layers) else: raise NotImplementedError self.dilation = dilation # Initial layers layers = [("conv1", nn.Conv2d(3, 64, 7, stride=2, padding=3, bias=False)), ("bn1", norm_act(64))] if try_index(dilation, 0) == 1: layers.append(("pool1", nn.MaxPool2d(3, stride=2, padding=1))) self.mod1 = nn.Sequential(OrderedDict(layers)) # Groups of residual blocks in_channels = 64 if self.bottleneck: channels = (64, 64, 256) else: channels = (64, 64) for mod_id, num in enumerate(structure): # Create blocks for module blocks = [] for block_id in range(num): stride, dil = self._stride_dilation(dilation, mod_id, block_id) blocks.append(("block%d" % (block_id + 1), ResidualBlock(in_channels, channels, norm_act=norm_act, stride=stride, dilation=dil))) # Update channels and p_keep in_channels = channels[-1] # Create module self.add_module("mod%d" % (mod_id + 2), nn.Sequential(OrderedDict(blocks))) # Double the number of channels for the next module channels = [c * 2 for c in channels] self.out_channels = in_channels # Pooling and predictor if classes != 0: self.classifier = nn.Sequential( OrderedDict([("avg_pool", GlobalAvgPool2d()), ("fc", nn.Linear(in_channels, classes))]))
def __init__( self, structure, bottleneck, norm_act=ABN, classes=0, dilation=1, keep_outputs=False, ): super(ResNet, self).__init__() self.structure = structure self.bottleneck = bottleneck self.dilation = dilation self.keep_outputs = keep_outputs if len(structure) != 4: raise ValueError("Expected a structure with four values") if dilation != 1 and len(dilation) != 4: raise ValueError( "If dilation is not 1 it must contain four values") # Initial layers layers = [ ("conv1", nn.Conv2d(3, 64, 7, stride=2, padding=3, bias=False)), ("bn1", norm_act(64)), ] if try_index(dilation, 0) == 1: layers.append(("pool1", nn.MaxPool2d(3, stride=2, padding=1))) self.mod1 = nn.Sequential(OrderedDict(layers)) # Groups of residual blocks in_channels = 64 if self.bottleneck: channels = (64, 64, 256) else: channels = (64, 64) for mod_id, num in enumerate(structure): # Create blocks for module blocks = [] for block_id in range(num): stride, dil = self._stride_dilation(dilation, mod_id, block_id) blocks.append(( "block%d" % (block_id + 1), ResidualBlock( in_channels, channels, norm_act=norm_act, stride=stride, dilation=dil, ), )) # Update channels and p_keep in_channels = channels[-1] # Create module self.add_module("mod%d" % (mod_id + 2), nn.Sequential(OrderedDict(blocks))) # Double the number of channels for the next module channels = [c * 2 for c in channels] # Pooling and predictor if classes != 0: self.classifier = nn.Sequential( OrderedDict([ ("avg_pool", GlobalAvgPool2d()), ("fc", nn.Linear(in_channels, classes)), ]))
def _add_gapool(self): l = GlobalAvgPool2d() self.W.append(l)