              as the filenames received
          """
          return [self._cache[os.path.basename(filename)] for filename in filenames]
  
      def cache_metadata(self, filenames):
          """ Obtain the batch with metadata for items that need caching and cache them to
          :attr:`_cache`.
  
          Parameters
          ----------
          filenames: list
              List of full paths to image file names
 
</s> remove         return [self._cache[os.path.basename(filename)] for filename in filenames]
 </s> add         logger.debug("Loading minibatch generator: (image_count: %s, do_shuffle: %s)",
                     len(self._images), do_shuffle) </s> remove         Returns
        -------
        list
            List of dictionaries containing the cached metadata. The list returns in the same order
            as the filenames received
 </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) </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 </s> remove         filename: str
            The file path for the current image
        detected_face: :class:`lib.align.DetectedFace`
            The detected face object that holds the masks
 </s> add         filenames: list
            List of full paths to image file names for a single batch
        images: :class:`numpy.ndarray`
            The batch of faces corresponding to the filenames
        detected_faces: list
            List of :class:`~lib.align.DetectedFace` objects with aligned data and masks loaded for
            the current batch
        batch: :class:`numpy.ndarray`
            The pre-allocated batch with images and masks populated for the selected coverage and
            centering </s> remove     def get_items(self, filenames):
        """ Obtain the cached items for a list of filenames. The returned list is in the same order
        as the provided filenames.
 </s> add     def _minibatch(self, do_shuffle: bool) -> Generator[BatchType, None, None]:
        """ A generator function that yields the augmented, target and sample images for the
        current batch on the current side.
        def _img_iter(imgs):
            """ Infinite iterator for recursing through image list and reshuffling at each epoch"""
            while True:
                if do_shuffle:
                    shuffle(imgs)
                for img in imgs:
                    yield img

        img_iter = _img_iter(self._images[:])
        while True:
            img_paths = [next(img_iter)  # pylint:disable=stop-iteration-return
                         for _ in range(self._batch_size)]
            retval = self._process_batch(img_paths)
            yield retval

    def _get_images_with_meta(self, filenames: List[str]) -> Tuple[np.ndarray, List[DetectedFace]]:
        """ Obtain the raw face images with associated :class:`DetectedFace` objects for this
        batch.

        If this is the first time a face has been loaded, then it's meta data is extracted
        from the png header and added to :attr:`_face_cache`.
              as the filenames received
          """
          return [self._cache[os.path.basename(filename)] for filename in filenames]
  
        def _img_iter(imgs):
            """ Infinite iterator for recursing through image list and reshuffling at each epoch"""
            while True:
                if do_shuffle:
                    shuffle(imgs)
                for img in imgs:
                    yield img

        img_iter = _img_iter(self._images[:])
        while True:
            img_paths = [next(img_iter)  # pylint:disable=stop-iteration-return
                         for _ in range(self._batch_size)]
            retval = self._process_batch(img_paths)
            yield retval

    def _get_images_with_meta(self, filenames: List[str]) -> Tuple[np.ndarray, List[DetectedFace]]:
        """ Obtain the raw face images with associated :class:`DetectedFace` objects for this
        batch.

        If this is the first time a face has been loaded, then it's meta data is extracted
        from the png header and added to :attr:`_face_cache`.
        def _img_iter(imgs):
            """ Infinite iterator for recursing through image list and reshuffling at each epoch"""
            while True:
                if do_shuffle:
                    shuffle(imgs)
                for img in imgs:
                    yield img

        img_iter = _img_iter(self._images[:])
        while True:
            img_paths = [next(img_iter)  # pylint:disable=stop-iteration-return
                         for _ in range(self._batch_size)]
            retval = self._process_batch(img_paths)
            yield retval

    def _get_images_with_meta(self, filenames: List[str]) -> Tuple[np.ndarray, List[DetectedFace]]:
        """ Obtain the raw face images with associated :class:`DetectedFace` objects for this
        batch.

        If this is the first time a face has been loaded, then it's meta data is extracted
        from the png header and added to :attr:`_face_cache`.
        def _img_iter(imgs):
            """ Infinite iterator for recursing through image list and reshuffling at each epoch"""
            while True:
                if do_shuffle:
                    shuffle(imgs)
                for img in imgs:
                    yield img

        img_iter = _img_iter(self._images[:])
        while True:
            img_paths = [next(img_iter)  # pylint:disable=stop-iteration-return
                         for _ in range(self._batch_size)]
            retval = self._process_batch(img_paths)
            yield retval

    def _get_images_with_meta(self, filenames: List[str]) -> Tuple[np.ndarray, List[DetectedFace]]:
        """ Obtain the raw face images with associated :class:`DetectedFace` objects for this
        batch.

        If this is the first time a face has been loaded, then it's meta data is extracted
        from the png header and added to :attr:`_face_cache`.
  
          Parameters
          ----------
          filenames: list
              List of full paths to image file names
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