              batch = self.compile_mask(batch)
          self.generate_preview(do_preview)
          return batch
  
      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
  
      def generate_preview(self, do_preview):
          """ Generate the preview if a preview iteration """
          if not do_preview:
              self.samples = None
              self.target = None
 
</s> remove             batch = self.compile_mask(batch)
        self.target = batch[1]
 </s> add             mask = batch[-1]
            batch = [[feed, mask], batch]
            self.target = [self.target, mask] </s> remove             batch = self.compile_mask(batch)
 </s> add             # Add mask to inputs
            mask = batch[-1]
            batch = [[feed, mask], batch] </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         batch = batch[1:]   # Remove full size samples from batch
 </s> add         feed = batch[1]
        batch = batch[2:]   # Remove full size samples and feed from batch
              batch = self.compile_mask(batch)
          self.generate_preview(do_preview)
          return batch
  










      def generate_preview(self, do_preview):
          """ Generate the preview if a preview iteration """
          if not do_preview:
              self.samples = None
              self.target = None
keep keep keep keep replace replace replace replace replace replace replace 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 
plugins/train/trainer/_base.py