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

illegal stride value.

Error message

illegal stride value.

What it means

ShuffleNetV2's InvertedResidual block validates that stride is 1 or 2 and raises ValueError otherwise. Only these strides are implemented: stride 2 uses the split/concat with downsampling branch; stride 1 relies on channel-split residual connections.

Source

Thrown at pytorch_classification/Test7_shufflenet/model.py:30

    # reshape
    # [batch_size, num_channels, height, width] -> [batch_size, groups, channels_per_group, height, width]
    x = x.view(batch_size, groups, channels_per_group, height, width)

    x = torch.transpose(x, 1, 2).contiguous()

    # flatten
    x = x.view(batch_size, -1, height, width)

    return x


class InvertedResidual(nn.Module):
    def __init__(self, input_c: int, output_c: int, stride: int):
        super(InvertedResidual, self).__init__()

        if stride not in [1, 2]:
            raise ValueError("illegal stride value.")
        self.stride = stride

        assert output_c % 2 == 0
        branch_features = output_c // 2
        # 当stride为1时,input_channel应该是branch_features的两倍
        # python中 '<<' 是位运算,可理解为计算×2的快速方法
        assert (self.stride != 1) or (input_c == branch_features << 1)

        if self.stride == 2:
            self.branch1 = nn.Sequential(
                self.depthwise_conv(input_c, input_c, kernel_s=3, stride=self.stride, padding=1),
                nn.BatchNorm2d(input_c),
                nn.Conv2d(input_c, branch_features, kernel_size=1, stride=1, padding=0, bias=False),
                nn.BatchNorm2d(branch_features),
                nn.ReLU(inplace=True)
            )
        else:
            self.branch1 = nn.Sequential()

View on GitHub (pinned to 1ec3fe6f37)

Solutions

  1. Use stride=1 or stride=2 for every InvertedResidual in the network.
  2. Chain multiple stride-2 stages instead of a single larger-stride layer.
  3. Keep the standard presets (0.5x/1.0x/1.5x/2.0x) that hard-code legal strides in _stage.

Example fix

// before
layers += [InvertedResidual(24, 116, stride=3)]
// after
layers += [InvertedResidual(24, 116, stride=2)]
Defensive patterns

Strategy: validation

Validate before calling

for layer in my_layers:
    if isinstance(layer, InvertedResidual) and layer.stride not in (1, 2):
        raise ValueError(f"bad stride {layer.stride} for ShuffleNetV2 block")

Type guard

def legal_shufflenet_stride(s: int) -> bool:
    return s in (1, 2)

Try / catch

try:
    block = InvertedResidual(input_c, output_c, stride)
except ValueError as e:
    if "illegal stride" in str(e):
        block = InvertedResidual(input_c, output_c, 2 if stride > 1 else 1)
    else:
        raise

Prevention

When it happens

Trigger: Instantiating InvertedResidual(input_c, output_c, stride) with stride = 3, 0, -1, etc., usually via a custom stages_repeats/stages_out_channels architecture or a hand-modified layer list passed to ShuffleNetV2.

Common situations: Users editing the model to add stronger downsampling; adapting code from other networks (e.g. ResNet which supports stride 4 in deeper blocks) and reusing stride values not supported here.

Related errors


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