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(
activationView on GitHub (pinned to 7a34a03db6)
Solutions
- Pass an int or a tuple/list of 2 (2D images) or 3 (3D volumes) ints, e.g. size=3 or size=(3, 3)
- If size comes from config or another framework, coerce it first: size = tuple(size) if isinstance(size, (list, tuple)) else int(size)
- 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
- Normalize size at the config boundary (CLI/YAML) into int or tuple
- Never forward framework objects (TensorShape, ndarray) as size
- Reuse the same validated size variable for extract and reconstruct
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
- If using `weights` as `"imagenet"` with `include_top` as tru
- Could not interpret activation function identifier: {identif
- ConvNeXt does not support the `channels_first` image data fo
- If using `weights="imagenet"` with `include_top=True`, `clas
- The `weights` argument should be either `None` (random initi
AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25).
Data as JSON: /api/errors/4b953f18f37e7f06.
Report an issue: GitHub.