| 201 | return x |
| 202 | |
| 203 | class RepLKNet(nn.Module): |
| 204 | |
| 205 | def __init__(self, large_kernel_sizes, layers, channels, drop_path_rate, small_kernel, |
| 206 | dw_ratio=1, ffn_ratio=4, in_channels=3, num_classes=1000, out_indices=None, |
| 207 | use_checkpoint=False, |
| 208 | small_kernel_merged=False, |
| 209 | use_sync_bn=True, |
| 210 | norm_intermediate_features=False # for RepLKNet-XL on COCO and ADE20K, use an extra BN to normalize the intermediate feature maps then feed them into the heads |
| 211 | ): |
| 212 | super().__init__() |
| 213 | |
| 214 | if num_classes is None and out_indices is None: |
| 215 | raise ValueError('must specify one of num_classes (for pretraining) and out_indices (for downstream tasks)') |
| 216 | elif num_classes is not None and out_indices is not None: |
| 217 | raise ValueError('cannot specify both num_classes (for pretraining) and out_indices (for downstream tasks)') |
| 218 | elif num_classes is not None and norm_intermediate_features: |
| 219 | raise ValueError('for pretraining, no need to normalize the intermediate feature maps') |
| 220 | self.out_indices = out_indices |
| 221 | if use_sync_bn: |
| 222 | enable_sync_bn() |
| 223 | |
| 224 | base_width = channels[0] |
| 225 | self.use_checkpoint = use_checkpoint |
| 226 | self.norm_intermediate_features = norm_intermediate_features |
| 227 | self.num_stages = len(layers) |
| 228 | self.stem = nn.ModuleList([ |
| 229 | conv_bn_relu(in_channels=in_channels, out_channels=base_width, kernel_size=3, stride=2, padding=1, groups=1), |
| 230 | conv_bn_relu(in_channels=base_width, out_channels=base_width, kernel_size=3, stride=1, padding=1, groups=base_width), |
| 231 | conv_bn_relu(in_channels=base_width, out_channels=base_width, kernel_size=1, stride=1, padding=0, groups=1), |
| 232 | conv_bn_relu(in_channels=base_width, out_channels=base_width, kernel_size=3, stride=2, padding=1, groups=base_width)]) |
| 233 | # stochastic depth. We set block-wise drop-path rate. The higher level blocks are more likely to be dropped. This implementation follows Swin. |
| 234 | dpr = [x.item() for x in torch.linspace(0, drop_path_rate, sum(layers))] |
| 235 | self.stages = nn.ModuleList() |
| 236 | self.transitions = nn.ModuleList() |
| 237 | for stage_idx in range(self.num_stages): |
| 238 | layer = RepLKNetStage(channels=channels[stage_idx], num_blocks=layers[stage_idx], |
| 239 | stage_lk_size=large_kernel_sizes[stage_idx], |
| 240 | drop_path=dpr[sum(layers[:stage_idx]):sum(layers[:stage_idx + 1])], |
| 241 | small_kernel=small_kernel, dw_ratio=dw_ratio, ffn_ratio=ffn_ratio, |
| 242 | use_checkpoint=use_checkpoint, small_kernel_merged=small_kernel_merged, |
| 243 | norm_intermediate_features=norm_intermediate_features) |
| 244 | self.stages.append(layer) |
| 245 | if stage_idx < len(layers) - 1: |
| 246 | transition = nn.Sequential( |
| 247 | conv_bn_relu(channels[stage_idx], channels[stage_idx + 1], 1, 1, 0, groups=1), |
| 248 | conv_bn_relu(channels[stage_idx + 1], channels[stage_idx + 1], 3, stride=2, padding=1, groups=channels[stage_idx + 1])) |
| 249 | self.transitions.append(transition) |
| 250 | |
| 251 | if num_classes is not None: |
| 252 | self.norm = get_bn(channels[-1]) |
| 253 | self.avgpool = nn.AdaptiveAvgPool2d(1) |
| 254 | self.head = nn.Linear(channels[-1], num_classes) |
| 255 | |
| 256 | |
| 257 | |
| 258 | def forward_features(self, x): |
| 259 | x = self.stem[0](x) |
| 260 | for stem_layer in self.stem[1:]: |
no outgoing calls
no test coverage detected