keras-team/keras · error · ValueError

Invalid value for argument `filters`. Expected a strictly po

Error message

Invalid value for argument `filters`. Expected a strictly positive value. Received filters={self.filters}.

What it means

Separable convolutions require filters (number of output channels) to be strictly positive. The pointwise stage must produce at least one channel, so __init__ rejects filters <= 0.

Source

Thrown at keras/src/layers/convolutional/base_separable_conv.py:142

        self.depthwise_regularizer = regularizers.get(depthwise_regularizer)
        self.pointwise_regularizer = regularizers.get(pointwise_regularizer)
        self.bias_regularizer = regularizers.get(bias_regularizer)
        self.depthwise_constraint = constraints.get(depthwise_constraint)
        self.pointwise_constraint = constraints.get(pointwise_constraint)
        self.bias_constraint = constraints.get(bias_constraint)
        self.data_format = self.data_format

        self.input_spec = InputSpec(min_ndim=self.rank + 2)

        if self.depth_multiplier is not None and self.depth_multiplier <= 0:
            raise ValueError(
                "Invalid value for argument `depth_multiplier`. Expected a "
                "strictly positive value. Received "
                f"depth_multiplier={self.depth_multiplier}."
            )

        if self.filters is not None and self.filters <= 0:
            raise ValueError(
                "Invalid value for argument `filters`. Expected a strictly "
                f"positive value. Received filters={self.filters}."
            )

        if not all(self.kernel_size):
            raise ValueError(
                "The argument `kernel_size` cannot contain 0. Received: "
                f"kernel_size={self.kernel_size}."
            )

        if not all(self.strides):
            raise ValueError(
                "The argument `strides` cannot contains 0(s). Received: "
                f"strides={self.strides}"
            )

    def build(self, input_shape):
        if self.data_format == "channels_last":

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Set filters to a positive integer (e.g. max(1, int(base * alpha))).
  2. Validate before construction: isinstance(filters, int) and filters > 0.
  3. Check hyperparameter sweep ranges for 0/negative filter counts.

Example fix

# before
filters = int(32 * alpha)  # alpha small -> 0
keras.layers.SeparableConv2D(filters, 3)

# after
filters = max(1, int(round(32 * alpha)))
keras.layers.SeparableConv2D(filters, 3)
Defensive patterns

Strategy: validation

Validate before calling

filters = max(1, int(round(base * alpha)))
assert isinstance(filters, int) and filters > 0

Type guard

def valid_filters(filters) -> bool:
    return isinstance(filters, int) and filters > 0

Prevention

When it happens

Trigger: Constructing SeparableConv1D/2D with filters=0 or negative, e.g. when filters is computed from a width multiplier (filters = base * alpha) that truncates to 0.

Common situations: EfficientNet/MobileNet-style width-multiplier code where alpha < 1/filter_base truncates to 0; config parsing that loses the filters value.

Related errors


AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25). Data as JSON: /api/errors/ed16c025718fc0cf. Report an issue: GitHub.