upsampling layer for 2d inputs the implementation uses interpolative resizing given the resize method specified by the interpolation argument use interpolationnearest to repeat the rows and columns of the data examples inputshape 2 2 1 3 x np arangenp prodinputshape reshapeinputshape printx 0 1 2 3 4 5 6 7 8 9 10 11 y keras layers upsampling2dsize1 2x printy 0 1 2 0 1 2 3 4 5 3 4 5 6 7 8 6 7 8 9 10 11 9 10 11 args size int or tuple of 2 integers the upsampling factors for rows and columns 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 else channelslast defaults to channelslast interpolation a string one of bicubic bilinear lanczos3 lanczos5 nearest input shape 4d tensor with shape if dataformat is channelslast batchsize rows cols channels if dataformat is channelsfirst batchsize channels rows cols output shape 4d tensor with shape if dataformat is channelslast batchsize upsampledrows upsampledcols channels if dataformat is channelsfirst batchsize channels upsampledrows upsampledcols resizes the images contained in a 4d tensor args x tensor or variable to resize heightfactor positive integer widthfactor positive integer dataformat one of channelsfirst channelslast interpolation a string one of bicubic bilinear lanczos3 lanczos5 or nearest returns a tensor https github comkerasteamkerasissues294 use ops repeat for nearest interpolation multiply the height and width factor on each dim by hand versus using elementwise multiplication by np arrayheightfactor widthfactor then listifying the tensor by calling tolist since when running under torchdynamo newshape will be traced as a symbolic variable specifically a faketensor which does not have a tolist method upsampling layer for 2d inputs the implementation uses interpolative resizing given the resize method specified by the interpolation argument use interpolation nearest to repeat the rows and columns of the data examples input_shape 2 2 1 3 x np arange np prod input_shape reshape input_shape print x 0 1 2 3 4 5 6 7 8 9 10 11 y keras layers upsampling2d size 1 2 x print y 0 1 2 0 1 2 3 4 5 3 4 5 6 7 8 6 7 8 9 10 11 9 10 11 args size int or tuple of 2 integers the upsampling factors for rows and columns 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 else channels_last defaults to channels_last interpolation a string one of bicubic bilinear lanczos3 lanczos5 nearest input shape 4d tensor with shape if data_format is channels_last batch_size rows cols channels if data_format is channels_first batch_size channels rows cols output shape 4d tensor with shape if data_format is channels_last batch_size upsampled_rows upsampled_cols channels if data_format is channels_first batch_size channels upsampled_rows upsampled_cols resizes the images contained in a 4d tensor args x tensor or variable to resize height_factor positive integer width_factor positive integer data_format one of channels_first channels_last interpolation a string one of bicubic bilinear lanczos3 lanczos5 or nearest returns a tensor https github com keras team keras issues 294 use ops repeat for nearest interpolation multiply the height and width factor on each dim by hand versus using element wise multiplication by np array height_factor width_factor then list ifying the tensor by calling tolist since when running under torchdynamo new_shape will be traced as a symbolic variable specifically a faketensor which does not have a tolist method
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.UpSampling2D")
class UpSampling2D(Layer):
    

    def __init__(
        self, size=(2, 2), data_format=None, interpolation="nearest", **kwargs
    ):
        super().__init__(**kwargs)
        self.data_format = backend.config.standardize_data_format(data_format)
        self.size = argument_validation.standardize_tuple(size, 2, "size")
        self.interpolation = interpolation.lower()
        self.input_spec = InputSpec(ndim=4)

    def compute_output_shape(self, input_shape):
        if self.data_format == "channels_first":
            height = (
                self.size[0] * input_shape[2]
                if input_shape[2] is not None
                else None
            )
            width = (
                self.size[1] * input_shape[3]
                if input_shape[3] is not None
                else None
            )
            return (input_shape[0], input_shape[1], height, width)
        else:
            height = (
                self.size[0] * input_shape[1]
                if input_shape[1] is not None
                else None
            )
            width = (
                self.size[1] * input_shape[2]
                if input_shape[2] is not None
                else None
            )
            return (input_shape[0], height, width, input_shape[3])

    def call(self, inputs):
        return self._resize_images(
            inputs,
            self.size[0],
            self.size[1],
            self.data_format,
            interpolation=self.interpolation,
        )

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

    def _resize_images(
        self,
        x,
        height_factor,
        width_factor,
        data_format,
        interpolation="nearest",
    ):
        
        if data_format == "channels_first":
            rows, cols = 2, 3
        elif data_format == "channels_last":
            rows, cols = 1, 2
        else:
            raise ValueError(f"Invalid `data_format` argument: {data_format}")

        if data_format == "channels_first":
            x = ops.transpose(x, [0, 2, 3, 1])
        
        
        if interpolation == "nearest":
            x = ops.repeat(x, height_factor, axis=1)
            x = ops.repeat(x, width_factor, axis=2)
        else:
            
            
            
            
            
            
            
            new_shape = (
                x.shape[rows] * height_factor,
                x.shape[cols] * width_factor,
            )
            x = ops.image.resize(x, new_shape, interpolation=interpolation)
        if data_format == "channels_first":
            x = ops.transpose(x, [0, 3, 1, 2])

        return x