Source code for mlprodict.onnx_conv.operator_converters.conv_transfer_transformer

"""
Converters for models from :epkg:`mlinsights`.


:githublink:`%|py|5`
"""
from sklearn.base import ClassifierMixin
from skl2onnx import get_model_alias
from skl2onnx.common.data_types import FloatTensorType
from skl2onnx.common._registration import get_shape_calculator
from skl2onnx._parse import parse_sklearn
from skl2onnx.common._apply_operation import apply_identity


[docs]def _model_outputs(existing_scope, model, inputs, custom_parsers=None): """ Retrieves the outputs of one particular models. :githublink:`%|py|16` """ scope = existing_scope.temp() if custom_parsers is not None and model in custom_parsers: return custom_parsers[model]( scope, model, inputs, custom_parsers=custom_parsers) return parse_sklearn(scope, model, inputs, custom_parsers=custom_parsers)
[docs]def parser_transfer_transformer(scope, model, inputs, custom_parsers=None): """ Parser for :epkg:`TransferTransformer`. :githublink:`%|py|27` """ if custom_parsers is not None and model in custom_parsers: return custom_parsers[model]( scope, model, inputs, custom_parsers=custom_parsers) if model.method == 'predict_proba': name = 'probabilities' elif model.method == 'transform': name = 'variable' else: raise NotImplementedError( # pragma: no cover "Unable to defined the output for method='{}' and model='{}'.".format( model.method, model.__class__.__name__)) prob = scope.declare_local_variable(name, FloatTensorType()) alias = get_model_alias(type(model)) this_operator = scope.declare_local_operator(alias, model) this_operator.inputs = inputs this_operator.outputs.append(prob) return this_operator.outputs
[docs]def shape_calculator_transfer_transformer(operator): """ Shape calculator :epkg:`TransferTransformer`. :githublink:`%|py|52` """ op = operator.raw_operator alias = get_model_alias(type(op.estimator_)) calc = get_shape_calculator(alias) scope = operator.scope_inst.temp() this_operator = scope.declare_local_operator(alias) this_operator.raw_operator = op.estimator_ this_operator.inputs = operator.inputs res = _model_outputs(scope, op.estimator_, operator.inputs) this_operator.outputs.extend([ scope.declare_local_variable( "%sTTS" % r.onnx_name, r.type) for r in res]) this_operator.outputs = res calc(this_operator) if op.method == 'predict_proba': operator.outputs[0].type = this_operator.outputs[1].type elif op.method == 'transform': operator.outputs[0].type = this_operator.outputs[0].type else: raise NotImplementedError( # pragma: no cover "Unable to defined the output for method='{}' and model='{}'.".format( op.method, op.__class__.__name__))
[docs]def convert_transfer_transformer(scope, operator, container): """ Converters for :epkg:`TransferTransformer`. :githublink:`%|py|81` """ op = operator.raw_operator op_type = get_model_alias(type(op.estimator_)) this_operator = scope.declare_local_operator(op_type) this_operator.raw_operator = op.estimator_ this_operator.inputs = operator.inputs if isinstance(op.estimator_, ClassifierMixin): container.add_options(id(op.estimator_), {'zipmap': False}) res = _model_outputs(scope.temp(), op.estimator_, operator.inputs) this_operator.outputs.extend([ scope.declare_local_variable( "%sTTC" % r.onnx_name, r.type) for r in res]) if op.method == 'predict_proba': index = 1 elif op.method == 'transform': index = 0 else: raise NotImplementedError( # pragma: no cover "Unable to defined the output for method='{}' and model='{}'.".format( op.method, op.__class__.__name__)) apply_identity(scope, this_operator.outputs[index].onnx_name, operator.outputs[0].full_name, container, operator_name=scope.get_unique_operator_name("IdentityTT"))