          for side, samples in self.images.items():
              other_side = "a" if side == "b" else "b"
              predictions = [preds["{0}_{0}".format(side)],
                             preds["{}_{}".format(other_side, side)]]
              display = self.to_full_frame(side, samples, predictions)
              headers[side] = self.get_headers(side, display[0].shape[1])
              figures[side] = np.stack([display[0], display[1], display[2], ], axis=1)
              if self.images[side][0].shape[0] % 2 == 1:
                  figures[side] = np.concatenate([figures[side],
                                                  np.expand_dims(figures[side][0], 0)])
  
 
</s> remove         preds = self.get_predictions(feeds["a"], feeds["b"])
 </s> add         preds = self._get_predictions(feeds["a"], feeds["b"]) </s> remove             save_iteration = iteration % self.args.save_interval == 0
            viewer = display_func if save_iteration or self.save_now else None
            timelapse = self.timelapse if save_iteration else None
 </s> add             save_iteration = iteration % self._args.save_interval == 0
            viewer = display_func if save_iteration or self._save_now else None
            timelapse = self._timelapse if save_iteration else None </s> remove                        self.model.iterations >= snapshot_interval and
                       self.model.iterations % snapshot_interval == 0)
 </s> add                        self._model.iterations >= snapshot_interval and
                       self._model.iterations % snapshot_interval == 0) </s> remove         for iteration in range(0, self.args.iterations):
 </s> add         for iteration in range(0, self._args.iterations): </s> remove     def get_predictions(self, feed_a, feed_b):
        """ Return the sample predictions from the model """
 </s> add     def _get_predictions(self, feed_a, feed_b):
        """ Feed the samples to the model and return predictions

        Parameters
        ----------
        feed_a: list
            List of :class:`numpy.ndarray` of feed images for the "a" side
        feed_a: list
            List of :class:`numpy.ndarray` of feed images for the "b" side

        Returns
        list:
            List of :class:`numpy.ndarray` of predictions received from the model
        """
            display = self._to_full_frame(side, samples, predictions)
            headers[side] = self._get_headers(side, display[0].shape[1])
          for side, samples in self.images.items():
              other_side = "a" if side == "b" else "b"
              predictions = [preds["{0}_{0}".format(side)],
                             preds["{}_{}".format(other_side, side)]]
            display = self._to_full_frame(side, samples, predictions)
            headers[side] = self._get_headers(side, display[0].shape[1])
            display = self._to_full_frame(side, samples, predictions)
            headers[side] = self._get_headers(side, display[0].shape[1])
              figures[side] = np.stack([display[0], display[1], display[2], ], axis=1)
              if self.images[side][0].shape[0] % 2 == 1:
                  figures[side] = np.concatenate([figures[side],
                                                  np.expand_dims(figures[side][0], 0)])
  
keep keep keep keep replace replace keep keep keep keep keep
 Smart Masks - Training Implementation (#914)

* Smart Masks - Training

- Reinstate smart mask training code
- Reinstate mask_type back to model.config
- change 'replicate_input_mask to 'learn_mask'
- Add learn mask option
- Add mask loading from alignments to plugins.train.trainer
- Add mask_blur and mask threshold options
- _base.py - Pass mask options through training_opts dict
- plugins.train.model - check for mask_type not None for learn_mask and penalized_mask_loss
- Limit alignments loading to just those faces that appear in the training folder
- Raise error if not all training images have an alignment, and alignment file is required
- lib.training_data - Mask generation code
- lib.faces_detect - cv2 dimension stripping bugfix
- Remove cv2 linting code

* Update mask helptext in cli.py

* Fix Warp to Landmarks
Remove SHA1 hashing from training data

* Update mask training config

* Capture missing masks at training init

* lib.image.read_image_batch - Return filenames with batch for ordering

* scripts.train - Documentation

* plugins.train.trainer - documentation

* Ensure backward compatibility.
Fix convert for new predicted masks

* Update removed masks to components for legacy models. 
plugins/train/trainer/_base.py