Exemple #1
0
 def _to_lib_selectors(
     dependencies: Set[Union[LibSelector, str, Tuple[str, str]]]
 ) -> Set[LibSelector]:
     selectors = set()
     for d in dependencies:
         selectors.add(
             LibSelector(name=d[0], constraint=d[1]) if isinstance(
                 d, tuple) else LibSelector(
                     name=d) if not isinstance(d, LibSelector) else d)
     return selectors
Exemple #2
0
class MetricTorch(MetricILF):
    """
    Function logging wrapped metrics of PyTroch
    """

    supported_libraries = {LibSelector(name="torch", constraint="*", specificity=1)}

    _dependencies = {"torch"}

    def __init__(self,*args, **kwargs):
        super().__init__(*args, **kwargs)
        self.identity = MetricILF.__name__

    def __post__(self, ctx, *args, _pypads_artifact_fallback=False, _pypads_env, _logger_call, _logger_output,
                 _pypads_result,
                 **kwargs):
        """
        :param ctx:
        :param args:
        :param _pypads_artifact_fallback: Write to artifact if metric can not be logged as an double value into mlflow
        :param _pypads_result:
        :param kwargs:
        :return:
        """
        result = _pypads_result

        if result is not None:
            from torch import Tensor
            if isinstance(result, Tensor):
                super().__post__(ctx, *args, _pypads_env=_pypads_env,_pypads_artifact_fallback=_pypads_artifact_fallback,
                                 _logger_call=_logger_call, _logger_output=_logger_output,
                                 _pypads_result=result.item(), **kwargs)
class DecisionsTorchILF(SingleInstanceILF):
    """
    Function getting the prediction scores from torch models.
        Hook:
            Hook this logger to the inference function of your model, e.g, torch.modules.container.Sequential.forward.
    """
    name = "PyTorch Decisions Logger"
    category = "TorchDecisionsLogger"

    supported_libraries = {LibSelector(name="torch", constraint="*", specificity=1)}

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.identity = SingleInstanceILF.__name__

    def __post__(self, ctx, *args, _logger_call, _pypads_pre_return, _pypads_result, _logger_output, _args, _kwargs,
                 **kwargs):
        from pypads.app.pypads import get_current_pads
        pads = get_current_pads()

        if hasattr(ctx, "training") and ctx.training:
            pass
        else:
            pads.cache.run_add("probabilities", _pypads_result.data.numpy())
            pads.cache.run_add("predictions", _pypads_result.argmax(dim=1).data.numpy())

            return super().__post__(ctx, *args, _logger_call=_logger_call, _pypads_pre_return=_pypads_pre_return,
                                    _pypads_result=_pypads_result, _logger_output=_logger_output, _args=_args,
                                    _kwargs=_kwargs, **kwargs)
class DecisionsKerasILF(SingleInstanceILF):
    """
    Function getting the prediction scores from keras models.
        Hook:
            Hook this logger to the inference function of your model, i.e. keras.engine.training.Model.predict_classes.
    """
    name = "Keras Decisions Logger"
    category = "KerasDecisionsLogger"

    supported_libraries = {LibSelector(name="keras", constraint="*", specificity=1)}

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.identity = SingleInstanceILF.__name__

    def __pre__(self, ctx, *args,
                _logger_call, _logger_output, _args, _kwargs, **kwargs):
        """

        :param ctx:
        :param args:
        :param kwargs:
        :return:
        """
        from pypads.app.pypads import get_current_pads
        pads = get_current_pads()

        probabilities = None
        try:
            probabilities = ctx.predict(*_args, **_kwargs)
        except Exception as e:
            logger.warning("Couldn't compute probabilities because %s" % str(e))

        pads.cache.run_add("probabilities", probabilities)
Exemple #5
0
    def get_relevant_mappings(self, package: Package):
        """
        Function to find all relevant mappings. This produces a generator getting extended with found subclasses
        :return:
        """
        if any([
                package.path.segments[0] == s.name
                for s, _ in self.get_entries()
        ]):
            lib_version = find_package_version(str(package.path.segments[0]))
            mappings = set()

            # Take only mappings which are fitting for versions if we have a selector
            if lib_version:
                lib_selector = LibSelector(name=str(package.path.segments[0]),
                                           constraint=lib_version)
                for k, collection in [(s, c) for s, c in self.get_entries()
                                      if s.allows_any(lib_selector)]:
                    for m in collection.find_mappings(package.path.segments):
                        mappings.add(m)

            # Otherwise just use all name fitting mappings
            else:
                for k, collection in [(s, c) for s, c in self.get_entries()
                                      if s.name == package.path.segments[0]]:
                    for m in collection.find_mappings(package.path.segments):
                        mappings.add(m)
            return mappings
        return set()
class DecisionsSklearnILF(SingleInstanceILF):
    """
    Function getting the prediction scores from sklearn estimators
        Hook:
            Hook this logger to the inference function of your model, i.e. sklearn.BaseEstimator.predict.
    """
    name = "Sklearn Decisions Logger"
    type = "SklearnDecisionsLogger"

    supported_libraries = {LibSelector(name="sklearn", constraint="*", specificity=1)}

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.identity = SingleInstanceILF.__name__

    def __pre__(self, ctx, *args,
                _logger_call, _logger_output, _args, _kwargs, **kwargs):
        """

        :param ctx:
        :param args:
        :param kwargs:
        :return:
        """
        from pypads.app.pypads import get_current_pads
        pads = get_current_pads()

        # check if the estimator computes decision scores
        probabilities = None
        predict_proba = None
        if hasattr(ctx, "predict_proba"):
            # TODO find a cleaner way to invoke the original predict_proba in case it is wrapped
            predict_proba = ctx.predict_proba
            if _logger_call.original_call.call_id.context.has_original(predict_proba):
                predict_proba = _logger_call.original_call.call_id.context.original(predict_proba)
        elif hasattr(ctx, "_predict_proba"):
            predict_proba = ctx._predict_proba
            if _logger_call.original_call.call_id.context.has_original(predict_proba):
                _logger_call.original_call.call_id.context.original(predict_proba)
        if hasattr(predict_proba, "__wrapped__"):
            predict_proba = predict_proba.__wrapped__
        try:
            probabilities = predict_proba(*_args, **_kwargs)
        except Exception as e:
            if isinstance(e, TypeError):
                try:
                    predict_proba = predict_proba.__get__(ctx)
                    probabilities = predict_proba(*_args, **_kwargs)
                except Exception as ee:
                    logger.warning("Couldn't compute probabilities because %s" % str(ee))
            else:
                logger.warning("Couldn't compute probabilities because %s" % str(e))
        finally:
            pads.cache.run_add("probabilities", probabilities)
class ParameterSearchILF(InjectionLogger):
    """
    Function logging the cv results of a parameter search
    """
    name = "Parameter Search Logger"
    category = "ParameterSearchLogger"

    supported_libraries = {
        LibSelector(name="sklearn", constraint="*", specificity=1)
    }

    class ParameterSearchOutput(OutputModel):
        category: str = "ParameterSearchOutput"

        gridsearch_cv: str = None

        class Config:
            orm_mode = True

    @classmethod
    def output_schema_class(cls) -> Optional[Type[OutputModel]]:
        return cls.ParameterSearchOutput

    def __pre__(self,
                ctx,
                *args,
                _pypads_write_format=None,
                _logger_call: LoggerCall,
                _logger_output,
                _args,
                _kwargs,
                **kwargs):
        from pypads.app.pypads import get_current_pads
        pads = get_current_pads()
        pads.cache.run_add("parameter_search", True)

    def __post__(self, ctx, *args, _logger_call, _pypads_pre_return,
                 _pypads_result, _logger_output, _args, _kwargs, **kwargs):
        from pypads.app.pypads import get_current_pads
        pads = get_current_pads()
        pads.cache.run_pop("parameter_search")
        from sklearn.model_selection._search import BaseSearchCV
        if isinstance(ctx, BaseSearchCV):
            gridsearch = ParameterSearchTO(parent=_logger_output)
            gridsearch.number_of_splits = ctx.n_splits_

            # Track individual decisions for all splits
            pads.cache.add("tracking_mode", "multiple")

            gridsearch.best_candidate = ctx.best_index_
            gridsearch.add_results(ctx.cv_results_)
            _logger_output.gridsearch_cv = gridsearch.store()
Exemple #8
0
 def __init__(self, key, version, library, author=None, **kwargs):
     """
     Object holding a set of mappings related to a library
     :param key: Name / key of the collection
     :param version: Version of the collection
     :param library: Library information including library version constraint and name
     """
     self._mappings = {}
     self._name = key
     self._author = author
     self._version = version
     self._lib = LibSelector.from_dict(library)
     self._hash = persistent_hash(
         (self._name, self._version, hash(self._lib)))
     self.uid = self._hash
     super().__init__()