WZMIAOMIAO/deep-learning-for-image-processing · error · ValueError

replace_stride_with_dilation should be None or a 3-element t

Error message

replace_stride_with_dilation should be None or a 3-element tuple, got {}

What it means

ResNet supports replacing the 2x2 stride of stages 3-5 with dilation, controlled by a 3-element boolean sequence (one flag per stage). If replace_stride_with_dilation is provided but its length is not 3, __init__ raises ValueError, since the stage count is fixed.

Source

Thrown at pytorch_segmentation/deeplab_v3/src/resnet_backbone.py:82

class ResNet(nn.Module):

    def __init__(self, block, layers, num_classes=1000, zero_init_residual=False,
                 groups=1, width_per_group=64, replace_stride_with_dilation=None,
                 norm_layer=None):
        super(ResNet, self).__init__()
        if norm_layer is None:
            norm_layer = nn.BatchNorm2d
        self._norm_layer = norm_layer

        self.inplanes = 64
        self.dilation = 1
        if replace_stride_with_dilation is None:
            # each element in the tuple indicates if we should replace
            # the 2x2 stride with a dilated convolution instead
            replace_stride_with_dilation = [False, False, False]
        if len(replace_stride_with_dilation) != 3:
            raise ValueError("replace_stride_with_dilation should be None "
                             "or a 3-element tuple, got {}".format(replace_stride_with_dilation))
        self.groups = groups
        self.base_width = width_per_group
        self.conv1 = nn.Conv2d(3, self.inplanes, kernel_size=7, stride=2, padding=3,
                               bias=False)
        self.bn1 = norm_layer(self.inplanes)
        self.relu = nn.ReLU(inplace=True)
        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
        self.layer1 = self._make_layer(block, 64, layers[0])
        self.layer2 = self._make_layer(block, 128, layers[1], stride=2,
                                       dilate=replace_stride_with_dilation[0])
        self.layer3 = self._make_layer(block, 256, layers[2], stride=2,
                                       dilate=replace_stride_with_dilation[1])
        self.layer4 = self._make_layer(block, 512, layers[3], stride=2,
                                       dilate=replace_stride_with_dilation[2])
        self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
        self.fc = nn.Linear(512 * block.expansion, num_classes)

View on GitHub (pinned to 1ec3fe6f37)

Solutions

  1. Always pass exactly a 3-element list/tuple of booleans, e.g. (False, True, True), or pass None for the default strided behavior.
  2. Check DeepLab config: typically replace_stride_with_dilation=(False, False, True) for output_stride=16 variants.
  3. Normalize your config to a list and assert len == 3 before calling the model constructor.

Example fix

// before
model = resnet50(replace_stride_with_dilation=[True])
// after
model = resnet50(replace_stride_with_dilation=[False, False, True])
Defensive patterns

Strategy: validation

Validate before calling

if replace_stride_with_dilation is not None:
    assert len(replace_stride_with_dilation) == 3, "need exactly 3 stage flags"

Type guard

def is_valid_dilation_flag(flags) -> bool:
    return flags is None or (hasattr(flags, '__len__') and len(flags) == 3)

Try / catch

try:
    model = resnet50(replace_stride_with_dilation=flags)
except ValueError as e:
    logging.error(f"{e}"); raise

Prevention

When it happens

Trigger: Calling resnet50/101/... (or _make_layer-driven constructors) with replace_stride_with_dilation of length != 3, e.g. [True] or a 4-element list, and not None.

Common situations: Configuring output_stride for DeepLab and getting the dilation flags wrong; using a list built conditionally that omitted entries; confusing it with other frameworks' per-layer dilation settings.

Related errors


AI-assisted analysis of WZMIAOMIAO/deep-learning-for-image-processing@1ec3fe6f37 (2026-08-30). Data as JSON: /api/errors/68356211b8462749. Report an issue: GitHub.