{"record":{"id":"6812766abc24c664","repo":"keras-team/keras","slug":"the-rank-of-mean-must-be-less-than-or-equal-to-t","errorCode":null,"errorMessage":"The rank of `mean` must be less than or equal to the number of axes ({len(self.axis)}). Received: mean shape {np.shape(mean)} for axis {self.axis}","messagePattern":"The rank of `mean` must be less than or equal to the number of axes \\((.+?)\\)\\. Received: mean shape (.+?) for axis (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"keras/src/layers/preprocessing/normalization.py","lineNumber":148,"sourceCode":"\n        # Set `mean` and `variance` if passed.\n        if (mean is not None) != (variance is not None):\n            raise ValueError(\n                \"When setting values directly, both `mean` and `variance` \"\n                f\"must be set. Received: mean={mean} and variance={variance}\"\n            )\n        if mean is not None:\n            # Verify mean and variance have the same shape.\n            if np.shape(mean) != np.shape(variance):\n                raise ValueError(\n                    \"When setting values directly, `mean` and `variance` \"\n                    \"must have the same shape. Received: \"\n                    f\"mean shape {np.shape(mean)} and \"\n                    f\"variance shape {np.shape(variance)}\"\n                )\n            # Verify mean rank <= number of axes.\n            if len(np.shape(mean)) > len(self.axis):\n                raise ValueError(\n                    \"The rank of `mean` must be less than or equal to the \"\n                    f\"number of axes ({len(self.axis)}). Received: \"\n                    f\"mean shape {np.shape(mean)} for axis {self.axis}\"\n                )\n\n    def build(self, input_shape):\n        if input_shape is None:\n            return\n\n        ndim = len(input_shape)\n        self._build_input_shape = input_shape\n\n        if any(a < -ndim or a >= ndim for a in self.axis):\n            raise ValueError(\n                \"All `axis` values must be in the range [-ndim, ndim). \"\n                f\"Received inputs with ndim={ndim}, while axis={self.axis}\"\n            )\n","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/layers/preprocessing/normalization.py#L130-L166","documentation":"Normalization replaces each kept axis with one statistic value, so mean (and variance) must have rank <= number of kept axes. __init__ raises when len(np.shape(mean)) > len(self.axis).","triggerScenarios":"Normalization(axis=-1) with a 2-D mean; Normalization(axis=[1,2]) with a rank-3 statistics tensor (e.g. a full-resolution mean image).","commonSituations":"Image pipelines passing a full HxWxC mean image instead of per-channel stats; expecting per-pixel normalization, which the layer does not support.","solutions":["Reduce stats to one value per kept axis (e.g. per-channel mean of shape (3,) for axis=-1)","If you need per-pixel normalization, subtract the mean image yourself before the layer","Pick axis values whose count matches the rank of your statistics arrays"],"exampleFix":"// before\nmean_img = np.load('mean.npy')  # (224,224,3)\nlayer = Normalization(axis=-1, mean=mean_img, variance=var_img)\n// after\nlayer = Normalization(axis=-1, mean=mean_img.mean((0,1)), variance=var_img.mean((0,1)))","handlingStrategy":"validation","validationCode":"import numpy as np\nif mean is not None and len(np.shape(mean)) > len(axis_list):\n    mean = mean.mean(tuple(range(mean.ndim - 1)))  # reduce to per-axis stats\n# do the same for variance before constructing the layer","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use per-channel 1-D statistics, not full mean images","Remember rank(stats) <= len(axis)"],"tags":["keras","normalization","rank-validation"],"backgroundTag":"array-shape-mismatch","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}