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 layer, will not be used in Ternausnet 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), # different structure per block, as channels has 2 or 3 input elements 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: # if first 4 groups of blocks, add maxpool 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=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 __init__(self, structure, groups=64, norm_act=nn.BatchNorm2d, input_3x3=True, classes=0, output_stride=16, 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 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 # 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): # stride is 2 when dilation=1, mod_id>0, block_id=0, else is 1 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] self.out_channels = 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)) ]))