              return self._partial_load
          with self._lock:
              return self._partial_load
  
      @property
      def extract_version(self):
          """ float: The alignments file version used to extract the faces. """
          return self._extract_version
  
      @property
      def aligned_landmarks(self):
          """ dict: The filename as key, aligned landmarks as value """
          if self._aligned_landmarks is None:
 
</s> remove     @property
    def aligned_landmarks(self):
        """ dict: The filename as key, aligned landmarks as value """
        if self._aligned_landmarks is None:
            with self._lock:
                # For Warp-To-Landmarks a race condition can occur where this is referenced from
                # the opposite side prior to it being populated, so block on a lock.
                self._aligned_landmarks = {key: val["aligned_face"].landmarks
                                           for key, val in self._cache.items()}
        return self._aligned_landmarks
 </s> add         Parameters
        ----------
        do_shuffle: bool, optional
            Whether data should be shuffled prior to loading from disk. If true, each time the full
            list of filenames are processed, the data will be reshuffled to make sure they are not
            returned in the same order. Default: ``True`` </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     def __init__(self, filenames, config):
        self._lock = Lock()
        self._cache = {os.path.basename(filename): dict(cached=False) for filename in filenames}
        self._aligned_landmarks = None
        self._partial_load = False
        self._cache_full = False
        self._extract_version = None
        self._has_reset = False
        self._size = None

        self._centering = config["centering"]
 </s> add     def __init__(self,
                 config: ConfigType,
                 model: "ModelBase",
                 side: Literal["a", "b"],
                 images: List[str],
                 batch_size: int) -> None:
        logger.debug("Initializing %s: (model: %s, side: %s, images: %s , "  # type: ignore
                     "batch_size: %s, config: %s)", self.__class__.__name__, model.name, side,
                     len(images), batch_size, config) </s> remove     @property
    def crop_size(self):
        """ int: The pixel size of the cropped aligned face """
        return self._size
 </s> add         Yields
        ------
        feed: list
            4-dimensional array of faces to feed the training the model (:attr:`x` parameter for
            :func:`keras.models.model.train_on_batch`.). The array returned is in the format
            (`batch size`, `height`, `width`, `channels`).
        targets: list
            List of 4-dimensional :class:`numpy.ndarray` objects in the order and size of each
            output of the model. The format of these arrays will be (`batch size`, `height`,
            `width`, `x`). This is the :attr:`y` parameter for
            :func:`keras.models.model.train_on_batch`. The number of channels here will vary.
            The first 3 channels are (rgb/bgr). The 4th channel is the face mask. Any subsequent
            channels are area masks (e.g. eye/mouth masks)
        """
        logger.debug("do_shuffle: %s", do_shuffle)
        args = (do_shuffle, )
        batcher = BackgroundGenerator(self._minibatch, thread_count=1, args=args)
        return batcher.iterator() </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
        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.
              return self._partial_load
          with self._lock:
              return self._partial_load
  
        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.
        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.
        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.
        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.
  
      @property
      def aligned_landmarks(self):
          """ dict: The filename as key, aligned landmarks as value """
          if self._aligned_landmarks is None:
keep keep keep keep replace 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