  
      def call(self, y_true, y_pred):
          """ Call the sub loss functions for the loss wrapper.
  
          Weights are returned as the weighted sum of the chosen losses.
  
          If a mask is being applied to the loss, then the appropriate mask is extracted from y_true
          and added as the 4th channel being passed to the penalized loss function.
  
          Parameters
 
</s> remove     def call(self, y_true, y_pred):
 </s> add     def __call__(self, y_true: tf.Tensor, y_pred: tf.Tensor) -> tf.Tensor: </s> remove         If a mask is being applied to the loss, then the appropriate mask is extracted from y_true
        and added as the 4th channel being passed to the penalized loss function.
 </s> add         If masks are being applied to the loss function inputs, then they should be included as
        additional channels at the end of :param:`y_true`, so that they can be split off and
        applied to the actual inputs to the selected loss function(s). </s> remove         y_true: tensor or variable
            The ground truth value
        y_pred: tensor or variable
            The predicted value
 </s> add         y_true: :class:`tensorflow.Tensor`
            The ground truth batch of images, with any required masks stacked on the end
        y_pred: :class:`tensorflow.Tensor`
            The batch of model predictions </s> remove     def _apply_mask(cls, y_true, y_pred, mask_channel, mask_prop=1.0):
 </s> add     def _apply_mask(cls,
                    y_true: tf.Tensor,
                    y_pred: tf.Tensor,
                    mask_channel: int,
                    mask_prop: float = 1.0) -> Tuple[tf.Tensor, tf.Tensor]: </s> remove class LossWrapper(tf.keras.losses.Loss):
    """ A wrapper class for multiple keras losses to enable multiple weighted loss functions on a
    single output.
 </s> add class LossWrapper():
    """ A wrapper class for multiple keras losses to enable multiple masked weighted loss
    functions on a single output.

    Notes
    -----
    Whilst Keras does allow for applying multiple weighted loss functions, it does not allow
    for an easy mechanism to add additional data (in our case masks) that are batch specific
    but are not fed in to the model.

    This wrapper receives this additional mask data for the batch stacked onto the end of the
    color channels of the received :param:`y_true` batch of images. These masks are then split
    off the batch of images and applied to both the :param:`y_true` and :param:`y_pred` tensors
    prior to feeding into the loss functions.

    For example, for an image of shape (4, 128, 128, 3) 3 additional masks may be stacked onto
    the end of y_true, meaning we receive an input of shape (4, 128, 128, 6). This wrapper then
    splits off (4, 128, 128, 3:6) from the end of the tensor, leaving the original y_true of
    shape (4, 128, 128, 3) ready for masking and feeding through the loss functions.
        Loss is returned as the weighted sum of the chosen losses.
  
      def call(self, y_true, y_pred):
          """ Call the sub loss functions for the loss wrapper.
  
        Loss is returned as the weighted sum of the chosen losses.
  
          If a mask is being applied to the loss, then the appropriate mask is extracted from y_true
          and added as the 4th channel being passed to the penalized loss function.
  
          Parameters
keep keep keep keep replace keep keep keep keep keep
 bugfix: distibuted training with dssim 
lib/model/losses_tf.py