      Example
      -------
      >>> # A standard sub-pixel up-scaling block
      >>> x = Convolution2D(256, 3, 3, padding="same", activation="relu")(...)
      >>> u = SubPixelUpscaling(scale_factor=2)(x)
      [Optional]
      >>> x = Convolution2D(256, 3, 3, padding="same", activation="relu")(u)
  
      Parameters
      ----------
 
</s> remove     :class:`SubPixelUpscaling` layer to speed up the learning process. However, if you are stacking
    multiple :class:`SubPixelUpscaling` blocks, it may increase the number of parameters greatly,
    so the Convolution layer after :class:`SubPixelUpscaling` layer can be removed.
 </s> add     :class:`PixelShuffler` layer to speed up the learning process. However, if you are stacking
    multiple :class:`PixelShuffler` blocks, it may increase the number of parameters greatly,
    so the Convolution layer after :class:`PixelShuffler` layer can be removed. </s> remove class L2_normalize(keras.layers.Layer):  # type:ignore[name-defined]  # pylint:disable=invalid-name
    """ Normalizes a tensor w.r.t. the L2 norm alongside the specified axis.
 </s> add         if data_format == "channels_first":
            inputs = tf.transpose(inputs, (0, 3, 1, 2)) </s> remove     @classmethod
    def _depth_to_space(cls, ipt, scale, data_format=None):
        """ Uses phase shift algorithm to convert channels/depth for spatial resolution """
        if data_format is None:
            data_format = K.image_data_format()
        data_format = data_format.lower()
        ipt = cls._preprocess_conv2d_input(ipt, data_format)
        out = tf.nn.depth_to_space(ipt, scale)
        out = cls._postprocess_conv2d_output(out, data_format)
 </s> add             out = K.reshape(inputs, (batch_size, height, width, r_height, r_width, o_channels))
            out = K.permute_dimensions(out, (0, 1, 3, 2, 4, 5))
            out = K.reshape(out, (batch_size, o_height, o_width, o_channels)) </s> remove         if self.data_format == 'channels_first':
            batch_size, channels, height, width = input_shape
            if batch_size is None:
                batch_size = -1
            r_height, r_width = self.size
            o_height, o_width = height * r_height, width * r_width
            o_channels = channels // (r_height * r_width)
 </s> add     def call(self, inputs: tf.Tensor, *args, **kwargs) -> tf.Tensor:
        """ Override to call the layer. </s> remove         if self.data_format == 'channels_last':
            pooled = K.std(inputs, axis=[1, 2])
        else:
            pooled = K.std(inputs, axis=[2, 3])
        return pooled

 </s> add 
    >>> u = PixelShuffler(size=(2, 2))(x)
      Example
      -------
      >>> # A standard sub-pixel up-scaling block
      >>> x = Convolution2D(256, 3, 3, padding="same", activation="relu")(...)
    >>> u = PixelShuffler(size=(2, 2))(x)
      [Optional]
      >>> x = Convolution2D(256, 3, 3, padding="same", activation="relu")(u)
  
      Parameters
      ----------
keep keep keep keep replace keep keep keep keep keep
 Training fixes:
  - Fix mixed precision layer storing and switching
  - typofix in _requirements_base.txt
  - lib.model.layers - cleanup, docs and tests fixes
  - lib.model.nn_blocks - typing fixes 
lib/model/layers.py