          self._nearest_landmarks = dict()
          self._processing = None
          logger.debug("Initialized %s", self.__class__.__name__)
  
      def minibatch_ab(self, images, batchsize, side,
                       do_shuffle=True, is_preview=False, is_timelapse=False):
          """ A Background iterator to return augmented images, samples and targets.
  
          The exit point from this class and the sole attribute that should be referenced. Called
          from :mod:`plugins.train.trainer._base`. Returns an iterator that yields images for
          training, preview and time-lapses.
  
 
</s> remove         The exit point from this class and the sole attribute that should be referenced. Called
        from :mod:`plugins.train.trainer._base`. Returns an iterator that yields images for
        training, preview and time-lapses.
 </s> add     def _create_targets(self, batch: np.ndarray) -> List[np.ndarray]:
        """ Compile target images, with masks, for the model output sizes. </s> remove     @property
    def extract_version(self):
        """ float: The alignments file version used to extract the faces. """
        return self._extract_version
 </s> add         The exit point from this class and the sole attribute that should be referenced. Called
        from :mod:`plugins.train.trainer._base`. Returns an iterator that yields images for
        training, preview and time-lapses. </s> remove     def __init__(self, model_input_size, model_output_shapes, coverage_ratio, color_order,
                 augment_color, no_flip, no_warp, warp_to_landmarks, config):
        logger.debug("Initializing %s: (model_input_size: %s, model_output_shapes: %s, "
                     "coverage_ratio: %s, color_order: %s, augment_color: %s, no_flip: %s, "
                     "no_warp: %s, warp_to_landmarks: %s, config: %s)",
                     self.__class__.__name__, model_input_size, model_output_shapes,
                     coverage_ratio, color_order, augment_color, no_flip, no_warp,
                     warp_to_landmarks, config)
        self._config = config
        self._model_input_size = model_input_size
        self._model_output_shapes = model_output_shapes
        self._coverage_ratio = coverage_ratio
        self._color_order = color_order.lower()
        self._augment_color = augment_color
        self._no_flip = no_flip
        self._warp_to_landmarks = warp_to_landmarks
        self._no_warp = no_warp

        # Batchsize and processing class are set when this class is called by a feeder
        # from lib.training_data
        self._batchsize = 0
        self._face_cache = None
        self._nearest_landmarks = dict()
        self._processing = None
        logger.debug("Initialized %s", self.__class__.__name__)
 </s> add     def __init__(self,
                 config: ConfigType,
                 model: "ModelBase",
                 side: Literal["a", "b"],
                 images: List[str],
                 batch_size: int) -> None:
        super().__init__(config, model, side, images, batch_size)
        self._augment_color = not model.command_line_arguments.no_augment_color
        self._no_flip = model.command_line_arguments.no_flip
        self._no_warp = model.command_line_arguments.no_warp
        self._warp_to_landmarks = (not self._no_warp
                                   and model.command_line_arguments.warp_to_landmarks)
        self._model_input_size = model.input_shape[1] </s> remove     def cache_full(self):
        """bool: ``True`` if the cache has been fully populated. ``False`` if there are items still
        to be cached. """
        if self._cache_full:
            return self._cache_full
        with self._lock:
            return self._cache_full

    @property
    def partially_loaded(self):
        """ bool: ``True`` if the cache has been partially loaded for Warp To Landmarks otherwise
        ``False`` """
        if self._partial_load:
            return self._partial_load
        with self._lock:
            return self._partial_load
 </s> add     def _total_channels(self) -> int:
        """int: The total number of channels, including mask channels that the target image
        should hold. """
        channels = 3
        if self._config["mask_type"] and (self._config["learn_mask"] or
                                          self._config["penalized_mask_loss"]):
            channels += 1

        mults = [area for area in ["eye", "mouth"] if int(self._config[f"{area}_multiplier"]) > 1]
        if self._config["penalized_mask_loss"] and mults:
            channels += len(mults)
        return channels

    def minibatch_ab(self, do_shuffle: bool = True) -> Generator[BatchType, None, None]:
        """ A Background iterator to return augmented images, samples and targets. </s> remove         for idx, side in enumerate(("a", "b")):
            self._display_feeds["timelapse"][side] = self._load_generator(idx).minibatch_ab(
                images[side][:batch_size],
                batch_size,
                side,
                do_shuffle=False,
                is_timelapse=True)
 </s> add         # MyPy can't recurse into nested dicts to get the type :(
        iterator = cast(Dict[Literal["a", "b"], Generator[BatchType, None, None]],
                        self._display_feeds["timelapse"])

        for side in get_args(Literal["a", "b"]):
            imgs = images[side]
            logger.debug("Setting preview feed: (side: '%s', images: %s)", side, len(imgs))

            iterator[side] = self._load_generator(side,
                                                  True,
                                                  batch_size=batch_size,
                                                  images=imgs).minibatch_ab()
        if self._warp_to_landmarks:
            self._face_cache.pre_fill(images, side)
        self._processing = ImageAugmentation(batch_size,
                                             self._process_size,
                                             self._config)
        self._nearest_landmarks: Dict[str, Tuple[str, ...]] = {}
        logger.debug("Initialized %s", self.__class__.__name__)
          self._nearest_landmarks = dict()
          self._processing = None
          logger.debug("Initialized %s", self.__class__.__name__)
  
        if self._warp_to_landmarks:
            self._face_cache.pre_fill(images, side)
        self._processing = ImageAugmentation(batch_size,
                                             self._process_size,
                                             self._config)
        self._nearest_landmarks: Dict[str, Tuple[str, ...]] = {}
        logger.debug("Initialized %s", self.__class__.__name__)
        if self._warp_to_landmarks:
            self._face_cache.pre_fill(images, side)
        self._processing = ImageAugmentation(batch_size,
                                             self._process_size,
                                             self._config)
        self._nearest_landmarks: Dict[str, Tuple[str, ...]] = {}
        logger.debug("Initialized %s", self.__class__.__name__)
        if self._warp_to_landmarks:
            self._face_cache.pre_fill(images, side)
        self._processing = ImageAugmentation(batch_size,
                                             self._process_size,
                                             self._config)
        self._nearest_landmarks: Dict[str, Tuple[str, ...]] = {}
        logger.debug("Initialized %s", self.__class__.__name__)
  
          The exit point from this class and the sole attribute that should be referenced. Called
          from :mod:`plugins.train.trainer._base`. Returns an iterator that yields images for
          training, preview and time-lapses.
  
keep keep keep keep replace replace 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 
lib/training/generator.py