def __init__(self, in_channels, out_channels, kernel_size, stride, nonLinear, SE, exp_size, dropout_rate=1.0): super(MobileBlock, self).__init__() self.out_channels = out_channels self.nonLinear = nonLinear self.SE = SE self.dropout_rate = dropout_rate padding = (kernel_size - 1) // 2 self.use_connect = (stride == 1 and in_channels == out_channels) # RE: ReLU;HS: h_swish if self.nonLinear == "RE": activation = nn.ReLU else: activation = h_swish self.conv = nn.Sequential( nn.Conv2d(in_channels, exp_size, kernel_size=1, stride=1, padding=0, bias=False), FrozenBatchNorm2d(exp_size), activation(inplace=True) ) self.depth_conv = nn.Sequential( Conv2d(exp_size, exp_size, kernel_size=kernel_size, stride=stride, padding=padding, groups=exp_size), FrozenBatchNorm2d(exp_size) ) # Squeeze-and-Excite if self.SE: self.squeeze_block = SqueezeBlock(exp_size) self.point_conv = nn.Sequential( Conv2d(exp_size, out_channels, kernel_size=1, stride=1, padding=0), FrozenBatchNorm2d(out_channels), activation(inplace=True) )
def __init__(self, inplanes, planes, stride=1): super(Bottleneck, self).__init__() self.inplanes = inplanes self.planes = planes self.conv1 = Conv2d(inplanes, planes, kernel_size=1, bias=False) self.bn1 = FrozenBatchNorm2d(planes) self.conv2 = Conv2d(planes, planes, kernel_size=3, stride=stride, padding=1, bias=False) self.bn2 = FrozenBatchNorm2d(planes) self.conv3 = Conv2d(planes, planes * self.expansion, kernel_size=1, bias=False) self.bn3 = FrozenBatchNorm2d(planes * self.expansion) self.relu = nn.ReLU(inplace=True) if self.inplanes != self.planes * self.expansion: self.downsample = nn.Sequential( Conv2d(self.inplanes, self.planes * self.expansion, kernel_size=1, stride=stride, bias=False), FrozenBatchNorm2d(self.planes * self.expansion), )
def _make_fuse_layers(self): if self.num_branches == 1: return None num_branches = self.num_branches num_inchannels = self.num_inchannels fuse_layers = [] for i in range(num_branches if self.multi_scale_output else 1): fuse_layer = [] for j in range(num_branches): if j > i: fuse_layer.append( nn.Sequential( Conv2d(num_inchannels[j], num_inchannels[i], 1, 1, 0, bias=False), FrozenBatchNorm2d(num_inchannels[i]), nn.Upsample(scale_factor=2**(j - i), mode='nearest'))) elif j == i: fuse_layer.append(None) else: conv3x3s = [] for k in range(i - j): if k == i - j - 1: num_outchannels_conv3x3 = num_inchannels[i] conv3x3s.append( nn.Sequential( Conv2d(num_inchannels[j], num_outchannels_conv3x3, 3, 2, 1, bias=False), FrozenBatchNorm2d( num_outchannels_conv3x3))) else: num_outchannels_conv3x3 = num_inchannels[j] conv3x3s.append( nn.Sequential( Conv2d(num_inchannels[j], num_outchannels_conv3x3, 3, 2, 1, bias=False), FrozenBatchNorm2d(num_outchannels_conv3x3), nn.ReLU(True))) fuse_layer.append(nn.Sequential(*conv3x3s)) fuse_layers.append(nn.ModuleList(fuse_layer)) return nn.ModuleList(fuse_layers)
def __init__(self, inp, oup, stride): super(InvertedResidual, self).__init__() if not (1 <= stride <= 3): raise ValueError('illegal stride value') self.stride = stride branch_features = oup // 2 assert (self.stride != 1) or (inp == branch_features << 1) if self.stride > 1: self.branch1 = nn.Sequential( self.depthwise_conv(inp, inp, kernel_size=3, stride=self.stride, padding=1), FrozenBatchNorm2d(inp), Conv2d(inp, branch_features, kernel_size=1, stride=1, padding=0, bias=False), FrozenBatchNorm2d(branch_features), nn.ReLU(inplace=True), ) else: self.branch1 = nn.Sequential() self.branch2 = nn.Sequential( Conv2d(inp if (self.stride > 1) else branch_features, branch_features, kernel_size=1, stride=1, padding=0, bias=False), FrozenBatchNorm2d(branch_features), nn.ReLU(inplace=True), self.depthwise_conv(branch_features, branch_features, kernel_size=3, stride=self.stride, padding=1), FrozenBatchNorm2d(branch_features), Conv2d(branch_features, branch_features, kernel_size=1, stride=1, padding=0, bias=False), FrozenBatchNorm2d(branch_features), nn.ReLU(inplace=True), )
def __init__(self, block_args, global_params): super().__init__() self._block_args = block_args self._bn_mom = 1 - global_params.batch_norm_momentum self._bn_eps = global_params.batch_norm_epsilon self.has_se = (self._block_args.se_ratio is not None) and (0 < self._block_args.se_ratio <= 1) self.id_skip = block_args.id_skip # skip connection and drop connect # Get static or dynamic convolution depending on image size Conv2d = get_same_padding_conv2d(image_size=global_params.image_size) # Expansion phase inp = self._block_args.input_filters # number of input channels oup = self._block_args.input_filters * self._block_args.expand_ratio # number of output channels if self._block_args.expand_ratio != 1: self._expand_conv = Conv2d(in_channels=inp, out_channels=oup, kernel_size=1, bias=False) self._bn0 = FrozenBatchNorm2d(oup) # Depthwise convolution phase k = self._block_args.kernel_size s = self._block_args.stride self._depthwise_conv = Conv2d( in_channels=oup, out_channels=oup, groups=oup, # groups makes it depthwise kernel_size=k, stride=s, bias=False) self._bn1 = FrozenBatchNorm2d(oup) # Squeeze and Excitation layer, if desired if self.has_se: num_squeezed_channels = max( 1, int(self._block_args.input_filters * self._block_args.se_ratio)) self._se_reduce = Conv2d(in_channels=oup, out_channels=num_squeezed_channels, kernel_size=1) self._se_expand = Conv2d(in_channels=num_squeezed_channels, out_channels=oup, kernel_size=1) # Output phase final_oup = self._block_args.output_filters self._project_conv = Conv2d(in_channels=oup, out_channels=final_oup, kernel_size=1, bias=False) self._bn2 = FrozenBatchNorm2d(final_oup) self._swish = MemoryEfficientSwish()
def __init__(self, in_channels, bottleneck_channels, out_channels, num_groups=1, stride_in_1x1=True, stride=1, activation_function=F.relu_): super(BottleneckWithFixedBatchNorm, self).__init__() self.downsample = None if in_channels != out_channels: self.downsample = nn.Sequential( Conv2d(in_channels, out_channels, kernel_size=1, stride=stride, bias=False), FrozenBatchNorm2d(out_channels), ) # The original MSRA ResNet models have stride in the first 1x1 conv # The subsequent fb.torch.resnet and Caffe2 ResNe[X]t implementations have # stride in the 3x3 conv stride_1x1, stride_3x3 = (stride, 1) if stride_in_1x1 else (1, stride) self.conv1 = Conv2d( in_channels, bottleneck_channels, kernel_size=1, stride=stride_1x1, bias=False, ) self.bn1 = FrozenBatchNorm2d(bottleneck_channels) # TODO: specify init for the above self.conv2 = Conv2d( bottleneck_channels, bottleneck_channels, kernel_size=3, stride=stride_3x3, padding=1, bias=False, groups=num_groups, ) self.bn2 = FrozenBatchNorm2d(bottleneck_channels) self.conv3 = Conv2d(bottleneck_channels, out_channels, kernel_size=1, bias=False) self.bn3 = FrozenBatchNorm2d(out_channels) self.acf = activation_function
def __init__(self, cfg): super(StemWithFixedBatchNorm, self).__init__() out_channels = cfg.MODEL.RESNETS.STEM_OUT_CHANNELS self.conv1 = Conv2d(3, out_channels, kernel_size=7, stride=2, padding=3, bias=False) self.bn1 = FrozenBatchNorm2d(out_channels)
def __init__(self, stages_repeats, stages_out_channels, num_classes=1000, inverted_residual=InvertedResidual): super(ShuffleNetV2, self).__init__() if len(stages_repeats) != 3: raise ValueError( 'expected stages_repeats as list of 3 positive ints') if len(stages_out_channels) != 5: raise ValueError( 'expected stages_out_channels as list of 5 positive ints') self._stage_out_channels = stages_out_channels input_channels = 3 output_channels = self._stage_out_channels[0] self.conv1 = nn.Sequential( Conv2d(input_channels, output_channels, 3, 2, 1, bias=False), FrozenBatchNorm2d(output_channels), nn.ReLU(inplace=True), ) input_channels = output_channels self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) stage_names = ['stage{}'.format(i) for i in [2, 3, 4]] for name, repeats, output_channels in zip( stage_names, stages_repeats, self._stage_out_channels[1:]): seq = [inverted_residual(input_channels, output_channels, 2)] for i in range(repeats - 1): seq.append( inverted_residual(output_channels, output_channels, 1)) setattr(self, name, nn.Sequential(*seq)) input_channels = output_channels output_channels = self._stage_out_channels[-1] self.conv5 = nn.Sequential( Conv2d(input_channels, output_channels, 1, 1, 0, bias=False), FrozenBatchNorm2d(output_channels), nn.ReLU(inplace=True), ) self.fc = nn.Linear(output_channels, num_classes)
def __init__(self, inp, oup, stride, expand_ratio): super(InvertedResidual, self).__init__() self.stride = stride assert stride in [1, 2] hidden_dim = int(round(inp * expand_ratio)) self.use_res_connect = self.stride == 1 and inp == oup if expand_ratio == 1: self.conv = nn.Sequential( # dw Conv2d(hidden_dim, hidden_dim, 3, stride, 1, groups=hidden_dim, bias=False), FrozenBatchNorm2d(hidden_dim), nn.ReLU6(inplace=True), # pw-linear Conv2d(hidden_dim, oup, 1, 1, 0, bias=False), FrozenBatchNorm2d(oup), ) else: self.conv = nn.Sequential( # pw Conv2d(inp, hidden_dim, 1, 1, 0, bias=False), FrozenBatchNorm2d(hidden_dim), nn.ReLU6(inplace=True), # dw Conv2d(hidden_dim, hidden_dim, 3, stride, 1, groups=hidden_dim, bias=False), FrozenBatchNorm2d(hidden_dim), nn.ReLU6(inplace=True), # pw-linear Conv2d(hidden_dim, oup, 1, 1, 0, bias=False), FrozenBatchNorm2d(oup), )
def conv3x3(in_channels, out_channels, module_name, postfix, stride=1, groups=1, kernel_size=3, padding=1): """3x3 convolution with padding""" return [ (f'{module_name}_{postfix}/conv', nn.Conv2d(in_channels, out_channels, kernel_size=kernel_size, stride=stride, padding=padding, groups=groups, bias=False)), (f'{module_name}_{postfix}/norm', group_norm(out_channels) if _GN else FrozenBatchNorm2d(out_channels) ), (f'{module_name}_{postfix}/relu', nn.ReLU(inplace=True)) ]
def __init__( self, input_depth, output_depth, kernel, stride, pad, no_bias, use_relu, bn_type, group=1, *args, **kwargs ): super(ConvBNRelu, self).__init__() assert use_relu in ["relu", None] if isinstance(bn_type, (list, tuple)): assert len(bn_type) == 2 assert bn_type[0] == "gn" gn_group = bn_type[1] bn_type = bn_type[0] assert bn_type in ["bn", "af", "gn", None] assert stride in [1, 2, 4] op = Conv2d( input_depth, output_depth, kernel_size=kernel, stride=stride, padding=pad, bias=not no_bias, groups=group, *args, **kwargs ) nn.init.kaiming_normal_(op.weight, mode="fan_out", nonlinearity="relu") if op.bias is not None: nn.init.constant_(op.bias, 0.0) self.add_module("conv", op) if bn_type == "bn": bn_op = BatchNorm2d(output_depth) elif bn_type == "gn": bn_op = nn.GroupNorm(num_groups=gn_group, num_channels=output_depth) elif bn_type == "af": bn_op = FrozenBatchNorm2d(output_depth) if bn_type is not None: self.add_module("bn", bn_op) if use_relu == "relu": self.add_module("relu", nn.ReLU(inplace=True))
def _make_transition_layer(self, num_channels_pre_layer, num_channels_cur_layer): num_branches_cur = len(num_channels_cur_layer) num_branches_pre = len(num_channels_pre_layer) transition_layers = [] for i in range(num_branches_cur): if i < num_branches_pre: if num_channels_cur_layer[i] != num_channels_pre_layer[i]: transition_layers.append( nn.Sequential( Conv2d(num_channels_pre_layer[i], num_channels_cur_layer[i], 3, 1, 1, bias=False), FrozenBatchNorm2d(num_channels_cur_layer[i]), nn.ReLU(inplace=True))) else: transition_layers.append(None) else: conv3x3s = [] for j in range(i + 1 - num_branches_pre): inchannels = num_channels_pre_layer[-1] outchannels = num_channels_cur_layer[i] \ if j == i-num_branches_pre else inchannels conv3x3s.append( nn.Sequential( Conv2d(inchannels, outchannels, 3, 2, 1, bias=False), FrozenBatchNorm2d(outchannels), nn.ReLU(inplace=True))) transition_layers.append(nn.Sequential(*conv3x3s)) return nn.ModuleList(transition_layers)
def DFConv3x3(in_channels, out_channels, module_name, postfix, stride=1, groups=1, kernel_size=3, with_modulated_dcn=None, deformable_groups=None): """3x3 convolution with padding""" return [ (f'{module_name}_{postfix}/conv', DFConv2d(in_channels, out_channels, with_modulated_dcn=with_modulated_dcn, kernel_size=kernel_size, stride=stride, groups=groups, deformable_groups=deformable_groups, bias=False)), (f'{module_name}_{postfix}/norm', group_norm(out_channels) if _GN else FrozenBatchNorm2d(out_channels) ), (f'{module_name}_{postfix}/relu', nn.ReLU(inplace=True)) ]
def __init__(self, cfg, multiplier=1.0): super(MobileNetV3, self).__init__() self.activation_HS = nn.ReLU6(inplace=True) bneck2_in_channels = cfg.MODEL.MOBILENETS.STEM_OUT_CHANNELS bneck2_out_channels = cfg.MODEL.MOBILENETS.BNECK2_OUT_CHANNELS layers = [ [bneck2_in_channels, bneck2_in_channels, 3, 1, "RE", False, 16, 1], [bneck2_in_channels, bneck2_out_channels, 3, 2, "RE", False, 64, 1], [bneck2_out_channels, bneck2_out_channels, 3, 1, "RE", False, 72, 1], [bneck2_out_channels, 40, 5, 2, "RE", True, 72, 2], [40, 40, 5, 1, "RE", True, 120, 2], [40, 40, 5, 1, "RE", True, 120, 2], [40, 80, 3, 2, "HS", False, 240, 3], [80, 80, 3, 1, "HS", False, 200, 3], [80, 80, 3, 1, "HS", False, 184, 3], [80, 80, 3, 1, "HS", False, 184, 3], [80, 112, 3, 1, "HS", True, 480, 4], [112, 112, 3, 1, "HS", True, 672, 4], [112, 160, 5, 1, "HS", True, 672, 4], [160, 160, 5, 2, "HS", True, 672, 4], [160, 160, 5, 1, "HS", True, 960, 4], ] indices = np.array(layers)[:, -1].tolist() r = Counter(indices) self.stages = [] self.init_conv = nn.Sequential( Conv2d(in_channels=3, out_channels=bneck2_in_channels, kernel_size=3, stride=2, padding=1), FrozenBatchNorm2d(bneck2_in_channels), h_swish(inplace=True) ) counts = [0, 3, 6, 10] for index in r.keys(): blocks = [] name = "layer{}".format(index) for _ in range(r[index]): in_channels, out_channels, kernel_size, stride, nonlinear, se, exp_size = layers[counts[int( index) - 1] + _][:7] in_channels = _make_divisible(in_channels * multiplier) out_channels = _make_divisible(out_channels * multiplier) exp_size = _make_divisible(exp_size * multiplier) blocks.append(MobileBlock(in_channels, out_channels, kernel_size, stride, nonlinear, se, exp_size)) self.add_module(name, nn.Sequential(*blocks)) self.stages.append(name)
def conv1x1(in_channels, out_channels, module_name, postfix, stride=1, groups=1, kernel_size=1, padding=0): """1x1 convolution with padding""" return [ ('{}_{}/conv'.format(module_name, postfix), nn.Conv2d(in_channels, out_channels, kernel_size=kernel_size, stride=stride, padding=padding, groups=groups, bias=False)), ('{}_{}/norm'.format(module_name, postfix), group_norm(out_channels) if _GN else FrozenBatchNorm2d(out_channels)), ('{}_{}/relu'.format(module_name, postfix), nn.ReLU(inplace=True)) ]
def __init__(self, cfg, in_channels): super(DepthCostFeatureExtractor, self).__init__() self.depth_bin_rate = torch.tensor( cfg.MODEL.ROI_BOX_HEAD.DEPTH_BIN_RATE).cuda() self.max_depth = len(self.depth_bin_rate) #resolution = cfg.MODEL.ROI_BOX_HEAD.POOLER_RESOLUTION * 2 resolution = 16 scales = cfg.MODEL.ROI_BOX_HEAD.POOLER_SCALES sampling_ratio = cfg.MODEL.ROI_BOX_HEAD.POOLER_SAMPLING_RATIO pooler = Pooler( output_size=(resolution, resolution), scales=scales, sampling_ratio=sampling_ratio, ) self.pooler = pooler self.reduced_channel = 32 self.resolution = resolution #self.dim_reduce = nn.Conv2d(in_channels, 32, kernel_size=1, stride=1) self.dim_reduce = nn.Sequential( nn.Conv2d(in_channels, 64, kernel_size=3, stride=1), FrozenBatchNorm2d(64), nn.ReLU(inplace=True), nn.Conv2d(64, 32, kernel_size=1, stride=1), FrozenBatchNorm2d(32), nn.ReLU(inplace=True)) #------------------------------lalala---------------------- #self.avg_pool = nn.MaxPool2d(resolution,resolution) self.dres0 = nn.Sequential(convbn_3d(96, 64, 3, 1, 1), nn.ReLU(inplace=True), convbn_3d(64, 128, 3, 1, 1), nn.ReLU(inplace=True)) self.max_pool1 = nn.MaxPool3d((1, 2, 2)) self.dres1 = nn.Sequential(convbn_3d(128, 128, 3, 1, 1), nn.ReLU(inplace=True), convbn_3d(128, 128, 3, 1, 1)) self.max_pool2 = nn.MaxPool3d((1, 2, 2)) self.dres2 = nn.Sequential( convbn_3d(128, 64, 3, 1, 1), nn.ReLU(inplace=True), nn.Conv3d(64, 1, kernel_size=3, padding=1, stride=1, bias=False)) self.avg_pool = nn.AvgPool2d(4, 4) for m in self.modules(): if isinstance(m, nn.Conv2d): n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels m.weight.data.normal_(0, math.sqrt(2. / n)) elif isinstance(m, nn.Conv3d): n = m.kernel_size[0] * m.kernel_size[1] * m.kernel_size[ 2] * m.out_channels m.weight.data.normal_(0, math.sqrt(2. / n)) elif isinstance(m, nn.BatchNorm2d): m.weight.data.fill_(1) m.bias.data.zero_() elif isinstance(m, nn.BatchNorm3d): m.weight.data.fill_(1) m.bias.data.zero_() elif isinstance(m, nn.Linear): m.bias.data.zero_()
def conv_bn(inp, oup, stride): return nn.Sequential(Conv2d(inp, oup, 3, stride, 1, bias=False), FrozenBatchNorm2d(oup), nn.ReLU6(inplace=True))
def __init__(self, cfg, **kwargs): super(HRNet, self).__init__() blocks_dict = { 'BasicBlockWithFixedBatchNorm': BasicBlock, 'BottleneckWithFixedBatchNorm': Bottleneck } self.blocks_dict = blocks_dict self.inplanes = 64 # stem net self.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=2, padding=1, bias=False) self.bn1 = FrozenBatchNorm2d(64) self.conv2 = nn.Conv2d(64, 64, kernel_size=3, stride=2, padding=1, bias=False) self.bn2 = FrozenBatchNorm2d(64) self.relu = nn.ReLU(inplace=True) self.stage1_cfg = cfg.MODEL.HRNET.STAGE1 num_channels = self.stage1_cfg['NUM_CHANNELS'][0] block = blocks_dict[self.stage1_cfg['BLOCK']] num_blocks = self.stage1_cfg['NUM_BLOCKS'][0] self.layer1 = self._make_layer(block, 64, num_channels, num_blocks) # stage1_out_channel = block.expansion*num_channels # self.layer1 = self._make_layer(Bottleneck, self.inplanes, 64, 4) self.stage2_cfg = cfg.MODEL.HRNET.STAGE2 num_channels = self.stage2_cfg['NUM_CHANNELS'] block = blocks_dict[self.stage2_cfg['BLOCK']] num_channels = [ num_channels[i] * block.expansion for i in range(len(num_channels)) ] self.transition1 = self._make_transition_layer([256], num_channels) self.stage2, pre_stage_channels = self._make_stage( self.stage2_cfg, num_channels) self.stage3_cfg = cfg.MODEL.HRNET.STAGE3 num_channels = self.stage3_cfg['NUM_CHANNELS'] block = blocks_dict[self.stage3_cfg['BLOCK']] num_channels = [ num_channels[i] * block.expansion for i in range(len(num_channels)) ] self.transition2 = self._make_transition_layer(pre_stage_channels, num_channels) self.stage3, pre_stage_channels = self._make_stage( self.stage3_cfg, num_channels) self.stage4_cfg = cfg.MODEL.HRNET.STAGE4 num_channels = self.stage4_cfg['NUM_CHANNELS'] block = blocks_dict[self.stage4_cfg['BLOCK']] num_channels = [ num_channels[i] * block.expansion for i in range(len(num_channels)) ] self.transition3 = self._make_transition_layer(pre_stage_channels, num_channels) self.stage4, pre_stage_channels = self._make_stage( self.stage4_cfg, num_channels, multi_scale_output=self.stage4_cfg.MULTI_OUTPUT)
def __init__(self, blocks_args=None, global_params=None): super().__init__() assert isinstance(blocks_args, list), 'blocks_args should be a list' assert len(blocks_args) > 0, 'block args must be greater than 0' self._global_params = global_params self._blocks_args = blocks_args # Get static or dynamic convolution depending on image size Conv2d = get_same_padding_conv2d(image_size=global_params.image_size) # Batch norm parameters bn_mom = 1 - self._global_params.batch_norm_momentum bn_eps = self._global_params.batch_norm_epsilon # Stem in_channels = 3 # rgb out_channels = round_filters( 32, self._global_params) # number of output channels self._conv_stem = Conv2d(in_channels, out_channels, kernel_size=3, stride=2, bias=False) self._bn0 = FrozenBatchNorm2d(out_channels) # Build blocks self._blocks = nn.ModuleList([]) for i in range(len(self._blocks_args)): # Update block input and output filters based on depth multiplier. self._blocks_args[i] = self._blocks_args[i]._replace( input_filters=round_filters(self._blocks_args[i].input_filters, self._global_params), output_filters=round_filters( self._blocks_args[i].output_filters, self._global_params), num_repeat=round_repeats(self._blocks_args[i].num_repeat, self._global_params)) # The first block needs to take care of stride and filter size increase. self._blocks.append( MBConvBlock(self._blocks_args[i], self._global_params)) if self._blocks_args[i].num_repeat > 1: self._blocks_args[i] = self._blocks_args[i]._replace( input_filters=self._blocks_args[i].output_filters, stride=1) for _ in range(self._blocks_args[i].num_repeat - 1): self._blocks.append( MBConvBlock(self._blocks_args[i], self._global_params)) # Head'efficientdet-d0': 'efficientnet-b0', in_channels = self._blocks_args[ len(self._blocks_args) - 1].output_filters # output of final block out_channels = round_filters(1280, self._global_params) self._conv_head = Conv2d(in_channels, out_channels, kernel_size=1, bias=False) self._bn1 = FrozenBatchNorm2d(out_channels) # Final linear layer # self._avg_pooling = nn.AdaptiveAvgPool2d(1) # self._dropout = nn.Dropout(self._global_params.dropout_rate) # self._fc = nn.Linear(out_channels, self._global_params.num_classes) self._swish = MemoryEfficientSwish()
def conv_1x1_bn(inp, oup): return nn.Sequential(Conv2d(inp, oup, 1, 1, 0, bias=False), FrozenBatchNorm2d(oup), nn.ReLU6(inplace=True))