{"record":{"id":"4878d80a44b28e36","repo":"keras-team/keras","slug":"invalid-image1-rank-expected-rank-3-single-image","errorCode":null,"errorMessage":"Invalid image1 rank: expected rank 3 (single image) or rank 4 (batch of images). Received input with shape: image1.shape={image1.shape}","messagePattern":"Invalid image1 rank: expected rank 3 \\(single image\\) or rank 4 \\(batch of images\\)\\. Received input with shape: image1\\.shape=(.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"keras/src/ops/image.py","lineNumber":2721,"sourceCode":"        self.k1 = k1\n        self.k2 = k2\n        self.data_format = backend.standardize_data_format(data_format)\n\n    def call(self, image1, image2):\n        return _ssim(\n            image1,\n            image2,\n            max_val=self.max_val,\n            filter_size=self.filter_size,\n            filter_sigma=self.filter_sigma,\n            k1=self.k1,\n            k2=self.k2,\n            data_format=self.data_format,\n        )\n\n    def compute_output_spec(self, image1, image2):\n        if len(image1.shape) not in (3, 4):\n            raise ValueError(\n                \"Invalid image1 rank: expected rank 3 (single image) \"\n                \"or rank 4 (batch of images). Received input with shape: \"\n                f\"image1.shape={image1.shape}\"\n            )\n        if len(image2.shape) not in (3, 4):\n            raise ValueError(\n                \"Invalid image2 rank: expected rank 3 (single image) \"\n                \"or rank 4 (batch of images). Received input with shape: \"\n                f\"image2.shape={image2.shape}\"\n            )\n        # Output is a scalar per image in the batch\n        if len(image1.shape) == 3:\n            output_shape = ()\n        else:\n            output_shape = (image1.shape[0],)\n        return KerasTensor(shape=output_shape, dtype=image1.dtype)\n\n","sourceCodeStart":2703,"sourceCodeEnd":2739,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/ops/image.py#L2703-L2739","documentation":"compute_output_spec of the SSIM op (keras.ops.image.ssim / SSIM layer) validates image1 is rank 3 (single) or rank 4 (batch). SSIM compares two images structurally, so a non-image-shaped tensor is rejected here first.","triggerScenarios":"keras.ops.image.ssim(pred_2d, target_3c, max_val=1.0) with mismatched ranks; passing flattened pixel vectors.","commonSituations":"Computing SSIM in a custom metric where model output was reshaped to (N, H*W); comparing pre- and post-augmentation images after a squeeze somewhere in the pipeline.","solutions":["Reshape image1 to (H, W, C) or (N, H, W, C).","Check the tensor right before the ssim call, not at model output — intermediate ops may reshape it.","Keep both images produced by the same reshape logic so ranks stay equal."],"exampleFix":"# before\nssim(y_pred.reshape(-1, 1024), y_true, 1.0)\n\n# after\nssim(y_pred.reshape(-1, 32, 32, 1), y_true, 1.0)","handlingStrategy":"validation","validationCode":"import numpy as np\na = np.asarray(image1)\nif a.ndim == 2: a = a[..., None]\nassert a.ndim in (3, 4), a.shape","typeGuard":"def is_valid_image_rank(x):\n    return getattr(x, 'ndim', None) in (3, 4)","tryCatchPattern":null,"preventionTips":["Reshape predictions to (N, H, W, C) inside custom metrics, not to flat vectors.","Add rank assertions in metric update_state."],"tags":["keras","image","ssim","shape-validation"],"backgroundTag":"tensor-rank-mismatch","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}