zeropadding layer for 2d input e g picture this layer can add rows and columns of zeros at the top bottom left and right side of an image tensor examples inputshape 1 1 2 2 x np arangenp prodinputshape reshapeinputshape x 0 1 2 3 y keras layers zeropadding2dpadding1x y 0 0 0 0 0 0 0 0 0 0 0 1 2 3 0 0 0 0 0 0 0 0 0 0 args padding int or tuple of 2 ints or tuple of 2 tuples of 2 ints if int the same symmetric padding is applied to height and width if tuple of 2 ints interpreted as two different symmetric padding values for height and width symmetricheightpad symmetricwidthpad if tuple of 2 tuples of 2 ints interpreted as toppad bottompad leftpad rightpad dataformat a string one of channelslast default or channelsfirst the ordering of the dimensions in the inputs channelslast corresponds to inputs with shape batchsize height width channels while channelsfirst corresponds to inputs with shape batchsize channels height width when unspecified uses imagedataformat value found in your keras config file at keraskeras json if exists defaults to channelslast input shape 4d tensor with shape if dataformat is channelslast batchsize height width channels if dataformat is channelsfirst batchsize channels height width output shape 4d tensor with shape if dataformat is channelslast batchsize paddedheight paddedwidth channels if dataformat is channelsfirst batchsize channels paddedheight paddedwidth zero padding layer for 2d input e g picture this layer can add rows and columns of zeros at the top bottom left and right side of an image tensor examples input_shape 1 1 2 2 x np arange np prod input_shape reshape input_shape x 0 1 2 3 y keras layers zeropadding2d padding 1 x y 0 0 0 0 0 0 0 0 0 0 0 1 2 3 0 0 0 0 0 0 0 0 0 0 args padding int or tuple of 2 ints or tuple of 2 tuples of 2 ints if int the same symmetric padding is applied to height and width if tuple of 2 ints interpreted as two different symmetric padding values for height and width symmetric_height_pad symmetric_width_pad if tuple of 2 tuples of 2 ints interpreted as top_pad bottom_pad left_pad right_pad data_format a string one of channels_last default or channels_first the ordering of the dimensions in the inputs channels_last corresponds to inputs with shape batch_size height width channels while channels_first corresponds to inputs with shape batch_size channels height width when unspecified uses image_data_format value found in your keras config file at keras keras json if exists defaults to channels_last input shape 4d tensor with shape if data_format is channels_last batch_size height width channels if data_format is channels_first batch_size channels height width output shape 4d tensor with shape if data_format is channels_last batch_size padded_height padded_width channels if data_format is channels_first batch_size channels padded_height padded_width
from keras import backend
from keras import ops
from keras.api_export import keras_export
from keras.layers.input_spec import InputSpec
from keras.layers.layer import Layer
from keras.utils import argument_validation


@keras_export("keras.layers.ZeroPadding2D")
class ZeroPadding2D(Layer):
    

    def __init__(self, padding=(1, 1), data_format=None, **kwargs):
        super().__init__(**kwargs)
        self.data_format = backend.standardize_data_format(data_format)
        if isinstance(padding, int):
            self.padding = ((padding, padding), (padding, padding))
        elif hasattr(padding, "__len__"):
            if len(padding) != 2:
                raise ValueError(
                    "`padding` should have two elements. "
                    f"Received: padding={padding}."
                )
            height_padding = argument_validation.standardize_tuple(
                padding[0], 2, "1st entry of padding", allow_zero=True
            )
            width_padding = argument_validation.standardize_tuple(
                padding[1], 2, "2nd entry of padding", allow_zero=True
            )
            self.padding = (height_padding, width_padding)
        else:
            raise ValueError(
                "`padding` should be either an int, a tuple of 2 ints "
                "(symmetric_height_crop, symmetric_width_crop), "
                "or a tuple of 2 tuples of 2 ints "
                "((top_crop, bottom_crop), (left_crop, right_crop)). "
                f"Received: padding={padding}."
            )
        self.input_spec = InputSpec(ndim=4)

    def compute_output_shape(self, input_shape):
        output_shape = list(input_shape)
        spatial_dims_offset = 2 if self.data_format == "channels_first" else 1
        for index in range(0, 2):
            if output_shape[index + spatial_dims_offset] is not None:
                output_shape[index + spatial_dims_offset] += (
                    self.padding[index][0] + self.padding[index][1]
                )
        return tuple(output_shape)

    def call(self, inputs):
        if self.data_format == "channels_first":
            all_dims_padding = ((0, 0), (0, 0), *self.padding)
        else:
            all_dims_padding = ((0, 0), *self.padding, (0, 0))
        return ops.pad(inputs, all_dims_padding)

    def get_config(self):
        config = {"padding": self.padding, "data_format": self.data_format}
        base_config = super().get_config()
        return {**base_config, **config}