keras-team/keras · error · ValueError

Unknown activation function '{activation}' cannot be seriali

Error message

Unknown activation function '{activation}' cannot be serialized due to invalid function name. Make sure to use an activation name that matches the references defined in activations.py or use `@keras.saving.register_keras_serializable()`to register any custom activations. config={fn_config}

What it means

Raised by keras.ops.image.extract_patches when the size argument is neither an int nor a tuple/list. extract_patches slices images into patches and must know the patch extent before touching tensors, so it validates size eagerly and rejects any other type with a TypeError naming the received type.

Source

Thrown at keras/src/activations/__init__.py:80

    hard_shrink,
    linear,
    mish,
    log_softmax,
    log_sigmoid,
    sparsemax,
}

ALL_OBJECTS_DICT = {fn.__name__: fn for fn in ALL_OBJECTS}
# Additional aliases
ALL_OBJECTS_DICT["swish"] = silu
ALL_OBJECTS_DICT["hard_swish"] = hard_silu


@keras_export("keras.activations.serialize")
def serialize(activation):
    fn_config = serialization_lib.serialize_keras_object(activation)
    if "config" not in fn_config:
        raise ValueError(
            f"Unknown activation function '{activation}' cannot be "
            "serialized due to invalid function name. Make sure to use "
            "an activation name that matches the references defined in "
            "activations.py or use "
            "`@keras.saving.register_keras_serializable()`"
            "to register any custom activations. "
            f"config={fn_config}"
        )
    if not isinstance(activation, types.FunctionType):
        # Case for additional custom activations represented by objects
        return fn_config
    if (
        isinstance(fn_config["config"], str)
        and fn_config["config"] not in globals()
    ):
        # Case for custom activation functions from external activations modules
        fn_config["config"] = object_registration.get_registered_name(
            activation

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Pass an int or a tuple/list of 2 (2D images) or 3 (3D volumes) ints, e.g. size=3 or size=(3, 3)
  2. If size comes from config or another framework, coerce it first: size = tuple(size) if isinstance(size, (list, tuple)) else int(size)
  3. Guard inputs with a small validator before calling extract_patches when size is user-supplied

Example fix

before: patches = ops.image.extract_patches(img, size=np.array([3, 3])) -> TypeError; after: patches = ops.image.extract_patches(img, size=(3, 3))
Defensive patterns

Strategy: type-guard

Validate before calling

def check_size(size):
    if not isinstance(size, int) and not (isinstance(size, (tuple, list)) and 2 <= len(size) <= 3 and all(isinstance(v, int) for v in size)):
        raise ValueError("size must be an int or a tuple/list of 2 or 3 ints")
    return size if isinstance(size, int) else tuple(size)

Type guard

def is_valid_patch_size(size) -> bool:
    if isinstance(size, bool):
        return False
    if isinstance(size, int):
        return True
    return isinstance(size, (tuple, list)) and len(size) in (2, 3) and all(isinstance(v, int) and not isinstance(v, bool) for v in size)

Try / catch

try:
    patches = keras.ops.image.extract_patches(img, size=size)
except TypeError as e:
    raise ValueError(f"bad patch size from config: {size!r}") from e

Prevention

When it happens

Trigger: Calling extract_patches(images, size=...) with a numpy array, a TensorShape, a string, None, or a generator as size; passing a config value loaded from YAML/JSON that arrived as something other than int, tuple or list.

Common situations: Dynamically built hyperparameter dicts (e.g. from a config file or CLI args) feeding size; porting code from torch.nn.Unfold or tf.image.extract_patches where size was a tensor; wrapping extract_patches in a layer whose build() passes through unvalidated user input.

Understand the failure class

Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.

Related errors


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