  
          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> remove         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         logger.trace("Target image shapes: %s", [tgt.shape for tgt in target_images])
        return self.compile_images(warped_image, target_images) </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         dst_points = np.mgrid[dst_slice, dst_slice]
        mat = umeyama(src_points, True, dst_points.T.reshape(-1, 2))[0:2]
        target_image = cv2.warpAffine(  # pylint:disable=no-member
            image, mat, (self.output_size, self.output_size))
        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)
 </s> add         dst_points = [np.mgrid[dst_slice, dst_slice] for dst_slice in dst_slices]
        mats = [umeyama(src_points, True, dst_pts.T.reshape(-1, 2))[0:2]
                for dst_pts in dst_points] </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 
        target_images = [cv2.warpAffine(image,  # pylint:disable=no-member
                                        mat,
                                        (self.output_sizes[idx], self.output_sizes[idx]))
                         for idx, mat in enumerate(mats)]
  
          warped_image, warped_mask = self.separate_mask(warped_image)
          target_image, target_mask = self.separate_mask(target_image)
  
        target_images = [cv2.warpAffine(image,  # pylint:disable=no-member
                                        mat,
                                        (self.output_sizes[idx], self.output_sizes[idx]))
                         for idx, mat in enumerate(mats)]
        target_images = [cv2.warpAffine(image,  # pylint:disable=no-member
                                        mat,
                                        (self.output_sizes[idx], self.output_sizes[idx]))
                         for idx, mat in enumerate(mats)]
        target_images = [cv2.warpAffine(image,  # pylint:disable=no-member
                                        mat,
                                        (self.output_sizes[idx], self.output_sizes[idx]))
                         for idx, mat in enumerate(mats)]
  
          logger.trace("Target mask shape: %s", target_mask.shape)
          logger.trace("Randomly warped image and mask")
          return [warped_image, target_image, target_mask]
  
keep keep keep keep replace replace 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 
lib/training_data.py