def __init__(self, block, layers, groups, reduction, dropout_p 0.5,
inplanes 128, input_3x3 True, downsample_kernel_size 3,
downsample_padding 1, num_classes 1000, zero_init_residual False):
Parameters
----------
block (nn.Module): Bottleneck class.
- For SENet154: SEBottleneck
- For SE-ResNet models: SEResNetBottleneck
- For SE-ResNeXt models: SEResNeXtBottleneck
layers (list of ints): Number of residual blocks for 4 layers of the
network (layer1...layer4).
groups (int): Number of groups for the 3x3 convolution in each
bottleneck block.
- For SENet154: 64
- For SE-ResNet models: 1
- For SE-ResNeXt models: 32
reduction (int): Reduction ratio for Squeeze-and-Excitation modules.
- For all models: 16
dropout_p (float or None): Drop probability for the Dropout layer.
If None the Dropout layer is not used.
- For SENet154: 0.2
- For SE-ResNet models: None
- For SE-ResNeXt models: None
inplanes (int): Number of input channels for layer1.
- For SENet154: 128
- For SE-ResNet models: 64
- For SE-ResNeXt models: 64
input_3x3 (bool): If True , use three 3x3 convolutions instead of
a single 7x7 convolution in layer0.
- For SENet154: True
- For SE-ResNet models: False
- For SE-ResNeXt models: False
downsample_kernel_size (int): Kernel size for downsampling convolutions
in layer2, layer3 and layer4.
- For SENet154: 3
- For SE-ResNet models: 1
- For SE-ResNeXt models: 1
downsample_padding (int): Padding for downsampling convolutions in
layer2, layer3 and layer4.
- For SENet154: 1
- For SE-ResNet models: 0
- For SE-ResNeXt models: 0
num_classes (int): Number of outputs in last_linear layer.
- For all models: 1000
super(SENet, self).__init__()
self.inplanes inplanes
if input_3x3:
layer0_modules [
( conv1 , nn.Conv2d(3, 64, 3, stride 2, padding 1,
bias False)),
( bn1 , nn.BatchNorm2d(64)),
( relu1 , nn.ReLU(inplace True)),
( conv2 , nn.Conv2d(64, 64, 3, stride 1, padding 1,
bias False)),
( bn2 , nn.BatchNorm2d(64)),
( relu2 , nn.ReLU(inplace True)),
( conv3 , nn.Conv2d(64, inplanes, 3, stride 1, padding 1,
bias False)),
( bn3 , nn.BatchNorm2d(inplanes)),
( relu3 , nn.ReLU(inplace True)),
else:
layer0_modules [
( conv1 , nn.Conv2d(3, inplanes, kernel_size 7, stride 2,
padding 3, bias False)),
( bn1 , nn.BatchNorm2d(inplanes)),
( relu1 , nn.ReLU(inplace True)),
# To preserve compatibility with Caffe weights ceil_mode True
# is used instead of padding 1 .
layer0_modules.append(( pool , nn.MaxPool2d(3, stride 2,
ceil_mode True)))
self.layer0 nn.Sequential(OrderedDict(layer0_modules))
self.layer1 self._make_layer(
block,
planes 64,
blocks layers[0],
groups groups,
reduction reduction,
downsample_kernel_size 1,
downsample_padding 0
self.layer2 self._make_layer(
block,
planes 128,
blocks layers[1],
stride 2,
groups groups,
reduction reduction,
downsample_kernel_size downsample_kernel_size,
downsample_padding downsample_padding
self.layer3 self._make_layer(
block,
planes 256,
blocks layers[2],
stride 2,
groups groups,
reduction reduction,
downsample_kernel_size downsample_kernel_size,
downsample_padding downsample_padding
self.layer4 self._make_layer(
block,
planes 512,
blocks layers[3],
stride 2,
groups groups,
reduction reduction,
downsample_kernel_size downsample_kernel_size,
downsample_padding downsample_padding
self.avg_pool nn.AvgPool2d(7, stride 1)
self.dropout nn.Dropout(dropout_p) if dropout_p is not None else None
self.last_linear nn.Linear(512 * block.expansion, 1000)
self.bottleneck nn.Sequential(
nn.Linear(1000, 1000),
nn.BatchNorm1d(1000),
nn.ReLU(),
nn.Dropout(0.5)
self.bottleneck[0].weight.data.normal_(0, 0.005)
self.bottleneck[0].bias.data.fill_(0.1)
self.head nn.Sequential(
nn.Linear(1000, 4),
# nn.ReLU(),
# nn.Dropout(0.5),
# nn.Linear(512, 4)
# self.fc nn.Linear(512, num_classes)
for dep in range(1):
self.head[dep * 1].weight.data.normal_(0, 0.01)
self.head[dep * 1].bias.data.fill_(0.0)
for m in self.modules():
if isinstance(m, nn.Conv2d):
nn.init.kaiming_normal_(m.weight, mode fan_out , nonlinearity relu )
elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)):
nn.init.constant_(m.weight, 1)
nn.init.constant_(m.bias, 0)
if zero_init_residual:
for m in self.modules():
if isinstance(m, Def_Bottleneck):
nn.init.constant_(m.bn3.weight, 0)
elif isinstance(m, BasicBlock):
nn.init.constant_(m.bn2.weight, 0)
def _make_layer(self, block, planes, blocks, groups, reduction, stride 1,
downsample_kernel_size 1, downsample_padding 0):
downsample None
if stride ! 1 or self.inplanes ! planes * block.expansion:
downsample nn.Sequential(
nn.Conv2d(self.inplanes, planes * block.expansion,
kernel_size downsample_kernel_size, stride stride,
padding downsample_padding, bias False),
nn.BatchNorm2d(planes * block.expansion),
layers []
layers.append(block(self.inplanes, planes, groups, reduction, stride,
downsample))
self.inplanes planes * block.expansion
for i in range(1, blocks):
layers.append(block(self.inplanes, planes, groups, reduction))
return nn.Sequential(*layers)
def features(self, x):
x self.layer0(x)
x self.layer1(x)
x self.layer2(x)
x self.layer3(x)
x self.layer4(x)
return x
def logits(self, x):
x self.avg_pool(x)
if self.dropout is not None:
x self.dropout(x)
x x.view(x.size(0), -1)
x self.last_linear(x)
x self.bottleneck(x)
x self.head(x)
return x
def forward(self, x):
x self.features(x)
x self.logits(x)
return x