          logger.debug("Setting up time-lapse")
          if output is None:
              output = get_folder(os.path.join(str(self._model.model_dir),
                                               f"{self._model.name}_timelapse"))
          self._output_file = str(output)
          logger.debug("Time-lapse output set to '%s'", self._output_file)
  
          # Rewrite paths to pull from the training images so mask and face data can be accessed
          images = {}
          for side, input_ in zip(("a", "b"), (input_a, input_b)):
 
</s> remove         images = {}
        for side, input_ in zip(("a", "b"), (input_a, input_b)):
 </s> add         images: Dict[Literal["a", "b"], List[str]] = {}
        for side, input_ in zip(get_args(Literal["a", "b"]), (input_a, input_b)): </s> remove         if output is None:
 </s> add         if not output: </s> remove     def output_timelapse(self, timelapse_kwargs):
 </s> add     def output_timelapse(self, timelapse_kwargs: Dict[str, str]) -> None: </s> remove         list
            The targets for the model with the mask compiled into the 4th channel. The original
            mask is still output as the final item in the list
        """
        if not self._model.config["penalized_mask_loss"] and additional_masks is None:
            logger.trace("No masks to compile. Returning targets")
            return targets

        if not self._model.config["penalized_mask_loss"] and additional_masks is not None:
            masks = additional_masks
        elif additional_masks is not None:
            masks = np.concatenate((masks, additional_masks), axis=-1)

        for idx, tgt in enumerate(targets):
            tgt_dim = tgt.shape[1]
            if tgt_dim == masks.shape[1]:
                add_masks = masks
            else:
                add_masks = np.array([cv2.resize(mask, (tgt_dim, tgt_dim))
                                      for mask in masks])
                if add_masks.ndim == 3:
                    add_masks = add_masks[..., None]
            targets[idx] = np.concatenate((tgt, add_masks), axis=-1)
        logger.trace("masks added to targets: %s", [tgt.shape for tgt in targets])
        return targets

    def generate_preview(self, do_preview):
        """ Generate the preview images.

        Parameters
        ----------
        do_preview: bool
            Whether the previews should be generated. ``True`` if they should ``False`` if they
            should not be generated, in which case currently stored previews should be deleted.
 </s> add         dict
            Dictionary for side A and B of list of numpy arrays corresponding to the
            samples, targets and masks for this preview </s> remove         :class:`numpy.ndarray`
            The batch of face images loaded from disk
 </s> add         raw_faces: :class:`numpy.ndarray`
            The full sized batch of training images for the given filenames
        list
            Batch of :class:`~lib.align.DetectedFace` objects for the given filename including the
            aligned face objects for the model output size
        self._output_file = output
          logger.debug("Setting up time-lapse")
          if output is None:
              output = get_folder(os.path.join(str(self._model.model_dir),
                                               f"{self._model.name}_timelapse"))
        self._output_file = output
          logger.debug("Time-lapse output set to '%s'", self._output_file)
  
          # Rewrite paths to pull from the training images so mask and face data can be accessed
          images = {}
          for side, input_ in zip(("a", "b"), (input_a, input_b)):
keep keep keep keep replace keep keep keep keep keep
 Data Augmentation update (#1263)

- lib.detected_face
    - Subclass Masks for Landmark based masks
    - Add training mask propery + methods to DetectedFace
  - lib.training_training
    - subclass TrainingDataGenerator for training and preview data
    - Split cache into own module
    - Reduce thread count to 1 to prevent image corruption + data re-use
    - Process on largest model input/output size rather than stored image size
    - Size and crop masks during caching stage
    - Implement ring buffer for data flow
    - Fix preview reload bug
  - augmentation
    - typing
    - switch color aug order
    - better initialization
    - Fix warp + landmark warp to correctly apply at different image scales
    - Slightly improved warp caching
    - Don't store whether image is_preview. Handle all data as training images implicitly
  - plugins.trainer: Typing and fixes to work with trainingdata refactor 
plugins/train/trainer/_base.py