<commit_before># -*- coding: utf-8 -*-

from typing import Union, Tuple, Optional
from json import encoder, dumps
from copy import deepcopy
from logging import DEBUG

from sklearn.neural_network.multilayer_perceptron import MLPClassifier \
    as MLPClassifierClass

from sklearn_porter.estimator.EstimatorApiABC import EstimatorApiABC
from sklearn_porter.estimator.EstimatorBase import EstimatorBase
from sklearn_porter.enums import Method, Language, Template
from sklearn_porter.exceptions import NotSupportedYetError
from sklearn_porter.utils import get_logger


L = get_logger(__name__)


class MLPClassifier(EstimatorBase, EstimatorApiABC):
    """Extract model data and port a MLPClassifier classifier."""

    DEFAULT_LANGUAGE = Language.JAVA
    DEFAULT_METHOD = Method.PREDICT
    DEFAULT_TEMPLATE = Template.ATTACHED

    SUPPORT = {
        Language.JAVA: {Method.PREDICT: {Template.ATTACHED, Template.EXPORTED}},
        Language.JS: {Method.PREDICT: {Template.ATTACHED, Template.EXPORTED}},
    }

    estimator = None  # type: MLPClassifierClass

    def __init__(self, estimator: MLPClassifierClass):
        super().__init__(estimator)
        L.info('Create specific estimator `%s`.', self.estimator_name)
        est = self.estimator  # alias

        # Check activation function:
        act_fn = est.activation
        supported_act_fns = ['relu', 'identity', 'tanh', 'logistic']
        if act_fn not in supported_act_fns:
            msg = 'The passed activation function `{}` is not supported yet.'
            msg = msg.format(act_fn)
            raise NotSupportedYetError(msg)

        # Check output function:
        out_fn = est.out_activation_
        supported_out_fns = ['softmax', 'logistic']
        if out_fn not in supported_out_fns:
            msg = 'The passed output function `{}` is not supported yet.'
            msg = msg.format(out_fn)
            raise NotSupportedYetError(msg)

        # Architecture:
        n_inputs = len(est.coefs_[0])
        n_outputs = est.n_outputs_
        n_hidden_layers = est.hidden_layer_sizes
        if isinstance(n_hidden_layers, int):
            n_hidden_layers = [n_hidden_layers]
        n_hidden_layers = list(n_hidden_layers)
        layers = [n_inputs] + n_hidden_layers + [n_outputs]

        self.meta_info = dict(
            n_layers=est.n_layers_,
            n_inputs=len(est.coefs_[0]),
            n_features=len(est.coefs_[0]),
            n_outputs=est.n_outputs_,
            n_hidden_layers=est.n_layers_ - 2,
            layer_units=layers
        )
        L.info('Meta info (keys): {}'.format(
            self.meta_info.keys()))
        if L.isEnabledFor(DEBUG):
            L.debug('Meta info: {}'.format(self.meta_info))

        self.model_data = dict(
            layers=list(map(int, layers[1:])),
            weights=est.coefs_,
            bias=est.intercepts_,
            hidden_activation=est.activation,
            output_activation=est.out_activation_,
        )
        L.info('Model data (keys): {}'.format(
            self.model_data.keys()))
        if L.isEnabledFor(DEBUG):
            L.debug('Model data: {}'.format(self.model_data))<commit_msg>feature/oop-api-refactoring: Fix np.ndarray serialization Remove useless meta info<commit_after># -*- coding: utf-8 -*-

from typing import Union, Tuple, Optional
from json import encoder, dumps
from copy import deepcopy
from logging import DEBUG
import numpy as np

from sklearn.neural_network.multilayer_perceptron import MLPClassifier \
    as MLPClassifierClass

from sklearn_porter.estimator.EstimatorApiABC import EstimatorApiABC
from sklearn_porter.estimator.EstimatorBase import EstimatorBase
from sklearn_porter.enums import Method, Language, Template
from sklearn_porter.exceptions import NotSupportedYetError
from sklearn_porter.utils import get_logger


L = get_logger(__name__)


class MLPClassifier(EstimatorBase, EstimatorApiABC):
    """Extract model data and port a MLPClassifier classifier."""

    DEFAULT_LANGUAGE = Language.JAVA
    DEFAULT_METHOD = Method.PREDICT
    DEFAULT_TEMPLATE = Template.ATTACHED

    SUPPORT = {
        Language.JAVA: {Method.PREDICT: {Template.ATTACHED, Template.EXPORTED}},
        Language.JS: {Method.PREDICT: {Template.ATTACHED, Template.EXPORTED}},
    }

    estimator = None  # type: MLPClassifierClass

    def __init__(self, estimator: MLPClassifierClass):
        super().__init__(estimator)
        L.info('Create specific estimator `%s`.', self.estimator_name)
        est = self.estimator  # alias

        # Check activation function:
        act_fn = est.activation
        supported_act_fns = ['relu', 'identity', 'tanh', 'logistic']
        if act_fn not in supported_act_fns:
            msg = 'The passed activation function `{}` is not supported yet.'
            msg = msg.format(act_fn)
            raise NotSupportedYetError(msg)

        # Check output function:
        out_fn = est.out_activation_
        supported_out_fns = ['softmax', 'logistic']
        if out_fn not in supported_out_fns:
            msg = 'The passed output function `{}` is not supported yet.'
            msg = msg.format(out_fn)
            raise NotSupportedYetError(msg)

        # Architecture:
        n_inputs = len(est.coefs_[0])
        n_outputs = est.n_outputs_
        n_hidden_layers = est.hidden_layer_sizes
        if isinstance(n_hidden_layers, int):
            n_hidden_layers = [n_hidden_layers]
        n_hidden_layers = list(n_hidden_layers)
        layers = [n_inputs] + n_hidden_layers + [n_outputs]

        self.meta_info = dict(
            n_features=n_inputs,
        )
        L.info('Meta info (keys): {}'.format(
            self.meta_info.keys()))
        if L.isEnabledFor(DEBUG):
            L.debug('Meta info: {}'.format(self.meta_info))

        self.model_data = dict(
            layers=list(map(int, layers[1:])),
            weights=list(map(np.ndarray.tolist, est.coefs_)),
            bias=list(map(np.ndarray.tolist, est.coefs_)),
            hidden_activation=est.activation,
            output_activation=est.out_activation_,
        )
        L.info('Model data (keys): {}'.format(
            self.model_data.keys()))
        if L.isEnabledFor(DEBUG):
            L.debug('Model data: {}'.format(self.model_data))
{'fraction_non_alphanumeric': 0.09837631327602674, 'fraction_numerical': 0.0014326647564469914, 'mean_word_length': 2.791792395896198, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6265578', 'n_tokens_mistral': 1951, 'n_tokens_neox': 1870, 'n_words': 414}