                  loss_names.insert(0, "total_loss")
              if initialize:
                  self.state.add_session_loss_names(side, loss_names)
                  self.history[side] = list()
          logger.debug("Compiled Predictors. Losses: %s", loss_names)
  
      def get_optimizer(self, lr=5e-5, beta_1=0.5, beta_2=0.999):  # pylint: disable=invalid-name
          """ Build and return Optimizer """
          opt_kwargs = dict(lr=lr, beta_1=beta_1, beta_2=beta_2)
          if (self.config.get("clipnorm", False) and
 
</s> remove                 self.state.add_session_loss_names(side, loss_names)
 </s> add                 self.state.add_session_loss_names(side, loss.names) </s> remove             mask = [inp for inp in model.inputs if inp.name.startswith("mask")]
            loss_names = ["loss"]
            loss_funcs = [self.loss_function(mask, side, initialize)]
            if mask:
                loss_names.append("mask_loss")
                loss_funcs.append(self.mask_loss_function(side, initialize))
            model.compile(optimizer=optimizer, loss=loss_funcs)

            if len(loss_names) > 1:
                loss_names.insert(0, "total_loss")
 </s> add             mask_input = [inp for inp in model.inputs if inp.name.startswith("mask")]
            loss = Loss(side, model.outputs, mask_input, self.predict)
            model.compile(optimizer=optimizer, loss=loss.funcs) </s> remove     def loss_function(self, mask, side, initialize):
        """ Set the loss function
            Side is input so we only log once """
        if self.config.get("dssim_loss", False):
            if side == "a" and not self.predict and initialize:
                logger.verbose("Using DSSIM Loss")
            loss_func = DSSIMObjective()
        else:
            if side == "a" and not self.predict and initialize:
                logger.verbose("Using Mean Absolute Error Loss")
            loss_func = losses.mean_absolute_error

        if mask and self.config.get("penalized_mask_loss", False):
            loss_mask = mask[0]
            if side == "a" and not self.predict and initialize:
                logger.verbose("Penalizing mask for Loss")
            loss_func = PenalizedLoss(loss_mask, loss_func)
        return loss_func

    def mask_loss_function(self, side, initialize):
        """ Set the mask loss function
            Side is input so we only log once """
        if side == "a" and not self.predict and initialize:
            logger.verbose("Using Mean Squared Error Loss for mask")
        mask_loss_func = losses.mean_squared_error
        return mask_loss_func

 </s> add  </s> remove         target_image = cv2.resize(  # pylint:disable=no-member
            target_image[slices, slices, :], (self.output_size, self.output_size),
            cv2.INTER_AREA)  # pylint:disable=no-member
        logger.trace("Target image shape: %s", target_image.shape)

        warped_image, warped_mask = self.separate_mask(warped_image)
        target_image, target_mask = self.separate_mask(target_image)

        if target_mask is None:
            logger.trace("Randomly warped image")
            return [warped_image, target_image]

        logger.trace("Target mask shape: %s", target_mask.shape)
        logger.trace("Randomly warped image and mask")
        return [warped_image, target_image, target_mask]
 </s> add         target_images = [cv2.resize(target_image[slices, slices, :],  # pylint:disable=no-member
                                    (size, size),
                                    cv2.INTER_AREA)  # pylint:disable=no-member
                         for size in self.output_sizes]

        logger.trace("Target image shapea: %s", [img.shape for img in target_images])
        return self.compile_images(warped_image, target_images)

    def compile_images(self, warped_image, target_images):
        """ Compile the warped images, target images and mask for feed """
        warped_image, _ = self.separate_mask(warped_image)
        final_target_images = list()
        target_mask = None
        for target_image in target_images:
            image, mask = self.separate_mask(target_image)
            final_target_images.append(image)
            # Add the mask if it exists and is the same size as our largest output
            if mask is not None and mask.shape[1] == max(self.output_sizes):
                target_mask = mask

        retval = [warped_image] + final_target_images
        if target_mask is not None:
            logger.trace("Target mask shape: %s", target_mask.shape)
            retval.append(target_mask)

        logger.trace("Final shapes: %s", [img.shape for img in retval])
        return retval </s> remove     def compile_mask(self, batch):
        """ Compile the mask into training data """
        logger.trace("Compiling Mask: (side: '%s')", self.side)
        mask = batch[-1]
        retval = list()
        for idx in range(len(batch) - 1):
            image = batch[idx]
            retval.append([image, mask])
        return retval

 </s> add 
        logger.debug("Compiled Predictors. Losses: %s", loss.names)
                  loss_names.insert(0, "total_loss")
              if initialize:
                  self.state.add_session_loss_names(side, loss_names)
                  self.history[side] = list()
        logger.debug("Compiled Predictors. Losses: %s", loss.names)
  
      def get_optimizer(self, lr=5e-5, beta_1=0.5, beta_2=0.999):  # pylint: disable=invalid-name
          """ Build and return Optimizer """
          opt_kwargs = dict(lr=lr, beta_1=beta_1, beta_2=beta_2)
          if (self.config.get("clipnorm", False) and
keep keep keep keep replace keep keep keep keep keep
 Training: Add Multi-Output Support

- Name output nodes of models
- Add support for multiple outputs in models and in training
- Update loss output format for cli and gui
- Sort graphs tabs on training
- Fix analysis graph for new loss names
- Multi output support in convert 
plugins/train/model/_base.py