          """ Return the inputs for the model """
          logger.debug("Getting inputs")
          inputs = [Input(shape=self.input_shape, name="face_in")]
          output_network = [network for network in self.networks.values() if network.is_output][0]
          mask_idx = [idx for idx, name in enumerate(output_network.output_names)
                      if name.startswith("mask")]
          if mask_idx:
              # Add the final mask shape as input
              mask_shape = output_network.output_shapes[mask_idx[0]]
              inputs.append(Input(shape=mask_shape[1:], name="mask_in"))
          logger.debug("Got inputs: %s", inputs)
          return inputs
  
      def build_autoencoders(self, inputs):
          """ Override for Model Specific autoencoder builds
 
</s> remove         retval = bool(self.model.training_opts.get("mask_type", None))
 </s> add         retval = (self.model.training_opts.get("replicate_input_mask", False) or
                  self.model.training_opts.get("penalized_mask_loss", True)) </s> remove #!/usr/bin/env python3
""" Plugin loader for extract, training and model tasks """

import logging
import os
from importlib import import_module

logger = logging.getLogger(__name__)  # pylint: disable=invalid-name


class PluginLoader():
    """ Plugin loader for extract, training and model tasks """
    @staticmethod
    def get_detector(name, disable_logging=False):
        """ Return requested detector plugin """
        return PluginLoader._import("extract.detect", name, disable_logging)

    @staticmethod
    def get_aligner(name, disable_logging=False):
        """ Return requested detector plugin """
        return PluginLoader._import("extract.align", name, disable_logging)

    @staticmethod
    def get_model(name, disable_logging=False):
        """ Return requested model plugin """
        return PluginLoader._import("train.model", name, disable_logging)

    @staticmethod
    def get_trainer(name, disable_logging=False):
        """ Return requested trainer plugin """
        return PluginLoader._import("train.trainer", name, disable_logging)

    @staticmethod
    def get_converter(category, name, disable_logging=False):
        """ Return the converter sub plugin """
        return PluginLoader._import("convert.{}".format(category), name, disable_logging)

    @staticmethod
    def _import(attr, name, disable_logging):
        """ Import the plugin's module """
        name = name.replace("-", "_")
        ttl = attr.split(".")[-1].title()
        if not disable_logging:
            logger.info("Loading %s from %s plugin...", ttl, name.title())
        attr = "model" if attr == "Trainer" else attr.lower()
        mod = ".".join(("plugins", attr, name))
        module = import_module(mod)
        return getattr(module, ttl)

    @staticmethod
    def get_available_extractors(extractor_type):
        """ Return a list of available aligners/detectors """
        extractpath = os.path.join(os.path.dirname(__file__),
                                   "extract",
                                   extractor_type)
        extractors = sorted(item.name.replace(".py", "").replace("_", "-")
                            for item in os.scandir(extractpath)
                            if not item.name.startswith("_")
                            and not item.name.endswith("defaults.py")
                            and item.name.endswith(".py")
                            and item.name != "manual.py")
        return extractors

    @staticmethod
    def get_available_models():
        """ Return a list of available models """
        modelpath = os.path.join(os.path.dirname(__file__), "train", "model")
        models = sorted(item.name.replace(".py", "").replace("_", "-")
                        for item in os.scandir(modelpath)
                        if not item.name.startswith("_")
                        and not item.name.endswith("defaults.py")
                        and item.name.endswith(".py"))
        return models

    @staticmethod
    def get_default_model():
        """ Return the default model """
        models = PluginLoader.get_available_models()
        return 'original' if 'original' in models else models[0]

    @staticmethod
    def get_available_convert_plugins(convert_category, add_none=True):
        """ Return a list of available models """
        convertpath = os.path.join(os.path.dirname(__file__),
                                   "convert",
                                   convert_category)
        converters = sorted(item.name.replace(".py", "").replace("_", "-")
                            for item in os.scandir(convertpath)
                            if not item.name.startswith("_")
                            and not item.name.endswith("defaults.py")
                            and item.name.endswith(".py"))
        if add_none:
            converters.insert(0, "none")
        return converters
 </s> add #!/usr/bin/env python3
""" Plugin loader for extract, training and model tasks """

import logging
import os
from importlib import import_module

logger = logging.getLogger(__name__)  # pylint: disable=invalid-name


class PluginLoader():
    """ Plugin loader for extract, training and model tasks """
    @staticmethod
    def get_detector(name, disable_logging=False):
        """ Return requested detector plugin """
        return PluginLoader._import("extract.detect", name, disable_logging)

    @staticmethod
    def get_aligner(name, disable_logging=False):
        """ Return requested detector plugin """
        return PluginLoader._import("extract.align", name, disable_logging)

    @staticmethod
    def get_masker(name, disable_logging=False):
        """ Return requested detector plugin """
        return PluginLoader._import("extract.mask", name, disable_logging)

    @staticmethod
    def get_model(name, disable_logging=False):
        """ Return requested model plugin """
        return PluginLoader._import("train.model", name, disable_logging)

    @staticmethod
    def get_trainer(name, disable_logging=False):
        """ Return requested trainer plugin """
        return PluginLoader._import("train.trainer", name, disable_logging)

    @staticmethod
    def get_converter(category, name, disable_logging=False):
        """ Return the converter sub plugin """
        return PluginLoader._import("convert.{}".format(category), name, disable_logging)

    @staticmethod
    def _import(attr, name, disable_logging):
        """ Import the plugin's module """
        name = name.replace("-", "_")
        ttl = attr.split(".")[-1].title()
        if not disable_logging:
            logger.info("Loading %s from %s plugin...", ttl, name.title())
        attr = "model" if attr == "Trainer" else attr.lower()
        mod = ".".join(("plugins", attr, name))
        module = import_module(mod)
        return getattr(module, ttl)

    @staticmethod
    def get_available_extractors(extractor_type):
        """ Return a list of available aligners/detectors """
        extractpath = os.path.join(os.path.dirname(__file__),
                                   "extract",
                                   extractor_type)
        extractors = sorted(item.name.replace(".py", "").replace("_", "-")
                            for item in os.scandir(extractpath)
                            if not item.name.startswith("_")
                            and not item.name.endswith("defaults.py")
                            and item.name.endswith(".py")
                            and item.name != "manual.py")
        return extractors

    @staticmethod
    def get_available_models():
        """ Return a list of available models """
        modelpath = os.path.join(os.path.dirname(__file__), "train", "model")
        models = sorted(item.name.replace(".py", "").replace("_", "-")
                        for item in os.scandir(modelpath)
                        if not item.name.startswith("_")
                        and not item.name.endswith("defaults.py")
                        and item.name.endswith(".py"))
        return models

    @staticmethod
    def get_default_model():
        """ Return the default model """
        models = PluginLoader.get_available_models()
        return 'original' if 'original' in models else models[0]

    @staticmethod
    def get_available_convert_plugins(convert_category, add_none=True):
        """ Return a list of available models """
        convertpath = os.path.join(os.path.dirname(__file__),
                                   "convert",
                                   convert_category)
        converters = sorted(item.name.replace(".py", "").replace("_", "-")
                            for item in os.scandir(convertpath)
                            if not item.name.startswith("_")
                            and not item.name.endswith("defaults.py")
                            and item.name.endswith(".py"))
        if add_none:
            converters.insert(0, "none")
        return converters </s> remove     def _set__mask_class(self):
        """ Returns the correct mask class from :mod:`lib`.model.masks` as defined in the
        :attr:`mask_type` parameter. """
        mask_type = self._training_opts.get("mask_type", None)
        if mask_type:
            logger.debug("Mask type: '%s'", mask_type)
            _mask_class = getattr(masks, mask_type)
        else:
            _mask_class = None
        logger.debug("Mask class: %s", _mask_class)
        return _mask_class

 </s> add  </s> remove         qname = "extract_align_out" if self.final_pass else "extract_align_in"
 </s> add         qname_dict = dict(detect="extract_align_in",
                          align="extract_mask_in",
                          mask="extract_mask_out")
        qname = "extract_mask_out" if self.final_pass else qname_dict[self.phase] </s> remove         cache_path = os.path.join(root_path, "plugins", "extract", ".cache")
 </s> add         cache_path = os.path.join(root_path, "plugins", "extract", "recognition", ".cache")
        if self.config["replicate_input_mask"] or self.config["penalized_mask_loss"]:
            # penalized mask doesn't have a mask ouput, so we can't use output shapes
            # mask should always be last output..this needs to be a rule
            mask_shape = output_network.output_shapes[-1]
            inputs.append(Input(shape=(mask_shape[1:-1] + (1,)), name="mask_in"))
          """ Return the inputs for the model """
          logger.debug("Getting inputs")
          inputs = [Input(shape=self.input_shape, name="face_in")]
          output_network = [network for network in self.networks.values() if network.is_output][0]
        if self.config["replicate_input_mask"] or self.config["penalized_mask_loss"]:
            # penalized mask doesn't have a mask ouput, so we can't use output shapes
            # mask should always be last output..this needs to be a rule
            mask_shape = output_network.output_shapes[-1]
            inputs.append(Input(shape=(mask_shape[1:-1] + (1,)), name="mask_in"))
        if self.config["replicate_input_mask"] or self.config["penalized_mask_loss"]:
            # penalized mask doesn't have a mask ouput, so we can't use output shapes
            # mask should always be last output..this needs to be a rule
            mask_shape = output_network.output_shapes[-1]
            inputs.append(Input(shape=(mask_shape[1:-1] + (1,)), name="mask_in"))
        if self.config["replicate_input_mask"] or self.config["penalized_mask_loss"]:
            # penalized mask doesn't have a mask ouput, so we can't use output shapes
            # mask should always be last output..this needs to be a rule
            mask_shape = output_network.output_shapes[-1]
            inputs.append(Input(shape=(mask_shape[1:-1] + (1,)), name="mask_in"))
        if self.config["replicate_input_mask"] or self.config["penalized_mask_loss"]:
            # penalized mask doesn't have a mask ouput, so we can't use output shapes
            # mask should always be last output..this needs to be a rule
            mask_shape = output_network.output_shapes[-1]
            inputs.append(Input(shape=(mask_shape[1:-1] + (1,)), name="mask_in"))
        if self.config["replicate_input_mask"] or self.config["penalized_mask_loss"]:
            # penalized mask doesn't have a mask ouput, so we can't use output shapes
            # mask should always be last output..this needs to be a rule
            mask_shape = output_network.output_shapes[-1]
            inputs.append(Input(shape=(mask_shape[1:-1] + (1,)), name="mask_in"))
        if self.config["replicate_input_mask"] or self.config["penalized_mask_loss"]:
            # penalized mask doesn't have a mask ouput, so we can't use output shapes
            # mask should always be last output..this needs to be a rule
            mask_shape = output_network.output_shapes[-1]
            inputs.append(Input(shape=(mask_shape[1:-1] + (1,)), name="mask_in"))
          logger.debug("Got inputs: %s", inputs)
          return inputs
  
      def build_autoencoders(self, inputs):
          """ Override for Model Specific autoencoder builds
keep keep keep keep replace replace replace replace replace replace keep keep keep keep keep
 Smart Mask Exposure for Extraction & Training (#831)

Smart Masks - Initial Commit 
plugins/train/model/_base.py