          if self._processing.is_display:
              processed["samples"] = batch[..., :3].astype("float32") / 255.0
  
          # Get Targets
          processed.update(self._processing.get_targets(batch))
  
          # Random Warp # TODO change masks to have a input mask and a warped target mask
          if self._no_warp:
              processed["feed"] = [self._processing.skip_warp(batch[..., :3])]
          else:
 
</s> remove         # Random Warp # TODO change masks to have a input mask and a warped target mask
        if self._no_warp:
            processed["feed"] = [self._processing.skip_warp(batch[..., :3])]
 </s> add         # TODO Look at potential for applying mask on input
        # Random Warp
        if self._warp_to_landmarks:
            landmarks = np.array([face.aligned.landmarks for face in detected_faces])
            batch_dst_pts = self._get_closest_match(filenames, landmarks)
            warp_kwargs = dict(batch_src_points=landmarks, batch_dst_points=batch_dst_pts) </s> remove         if self._color_order == "rgb":
            batch[..., :3] = batch[..., [2, 1, 0]]

        # Add samples to output if this is for display
        if self._processing.is_display:
            processed["samples"] = batch[..., :3].astype("float32") / 255.0
 </s> add         self._set_color_order(batch) </s> remove             processed["feed"] = [self._processing.warp(batch[..., :3],
                                                       self._warp_to_landmarks,
                                                       **warp_kwargs)]
 </s> add             warp_kwargs = {}

        warped = batch[..., :3] if self._no_warp else self._processing.warp(
            batch[..., :3],
            self._warp_to_landmarks,
            **warp_kwargs)

        if self._model_input_size != self._process_size:
            feed = self._to_float32(np.array([cv2.resize(image,
                                                         (self._model_input_size,
                                                          self._model_input_size),
                                                         cv2.INTER_AREA)
                                              for image in warped]))
        else:
            feed = self._to_float32(warped) </s> remove             batch = self._processing.random_flip(batch)
 </s> add             self._processing.random_flip(batch) </s> remove         batch = self._processing.transform(batch)
 </s> add         self._processing.transform(batch)

        targets = self._create_targets(batch)
          if self._processing.is_display:
              processed["samples"] = batch[..., :3].astype("float32") / 255.0
  
          # Get Targets
        targets = self._create_targets(batch)
  
          # Random Warp # TODO change masks to have a input mask and a warped target mask
          if self._no_warp:
              processed["feed"] = [self._processing.skip_warp(batch[..., :3])]
          else:
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 
lib/training/generator.py