[PYTHON] Création d'un outil qui facilite la définition des paramètres des modèles d'apprentissage automatique

Nous avons créé un outil pratique colt pour écrire des paramètres d'application tels que l'apprentissage automatique. En bref, colt est un outil pour écrire des paramètres comme ʻAllenNLP`. J'ai écrit "Machine learning" dans le titre, mais je pense qu'il peut être utilisé pour définir de nombreuses applications, sans se limiter à l'apprentissage automatique.

sample code

introduction

Lors de l'expérimentation de modèles d'apprentissage automatique, nous voyons souvent «argparse» et «Hydra» utilisés pour gérer les hyperparamètres. Je pense que le problème avec beaucoup de ces outils de gestion des paramètres existants est que lorsque vous effectuez un changement majeur de modèle, vous devez également modifier le processus de chargement des paramètres.

Par exemple (un exemple très agressif), SVC de scikit-learn J'avais l'intention d'utiliser generated / sklearn.svm.SVC.html? Highlight = svc # sklearn-svm-svc) et j'ai écrit un paramètre pour lire des paramètres tels que C, noyau, class_weight dans ʻargparse. , [RandomForestClassifier](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html?highlight=randomforest#sklearn-ensemble-randomforestclassifier) Est-il nécessaire de réécrire même la pièce? De plus, si vous souhaitez définir un modèle d'ensemble tel que [StackingClassifier`](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.StackingClassifier.html?highlight=stacking#sklearn-ensemble-stackingclassifier) , Si vous souhaitez définir le classificateur de base et le méta-classificateur, vous vous demandez comment écrire les paramètres.

AllenNLP

L'un des moyens de résoudre ces problèmes est la ** fonction Register ** adoptée par ʻAllenNLP`, qui est un cadre d'apprentissage en profondeur pour le traitement du langage naturel. Il y a.

Ici, je vais expliquer un peu cette ** fonction de registre **. Si vous le connaissez, veuillez l'ignorer.

ʻAllenNLP` décrit les paramètres au format JSON. Voici quelques-uns des paramètres du modèle de classification des phrases:

    "model": {
        "type": "basic_classifier",
        "text_field_embedder": {
            "token_embedders": {
                "tokens": {
                    "type": "embedding",
                    "embedding_dim": 10,
                    "trainable": true
                }
            }
        },
        "seq2vec_encoder": {
           "type": "cnn",
           "num_filters": 8,
           "embedding_dim": 10,
           "output_dim": 16
        }
    },

Spécifiez la classe que vous souhaitez utiliser avec type et définissez les paramètres dans le champ du même niveau. Regardons également le code pour basic_classifier et cnn. Les éléments de paramétrage correspondent aux arguments de la méthode __init__:

@Model.register("basic_classifier")
class BasicClassifier(Model):
    def __init__(
        self,
        ...,
        text_field_embedder: TextFieldEmbedder,
        seq2vec_encoder: Seq2VecEncoder,
        ...,
    ) -> None:
    ...


@Seq2VecEncoder.register("cnn")
class CnnEncoder(Seq2VecEncoder):
    def __init__(self,
                 embedding_dim: int,
                 num_filters: int,
                 ngram_filter_sizes: Tuple[int, ...] = (2, 3, 4, 5),
                 conv_layer_activation: Activation = None,
                 output_dim: Optional[int] = None) -> None:

Si vous enregistrez des classes avec le décorateur register, vous pouvez spécifier ces classes à partir des paramètres. Avec ʻAllenNLP, vous pouvez écrire les paramètres d'une classe simplement en créant une classe et register`. Ici, cette fonction est appelée ** fonction de registre **. Comme la fonction Register associe une classe à ses paramètres, il n'est pas nécessaire de modifier le processus de lecture des paramètres en fonction du changement de modèle.

Vous pouvez facilement remplacer divers composants du modèle à partir des paramètres. Pour changer le type de seq2vec_encoder de cnn à lstm, réécrivez simplement les paramètres comme suit (lstm est déjà fourni dans ʻAllenNLP`)

        "seq2vec_encoder": {
           "type": "lstm",
           "num_layers": 1,
           "input_size": 10,
           "hidden_size": 16
        }

Caractéristiques de colt

colt est un outil pour réaliser la même fonction que ** Register function ** de ʻAllenNLP. En utilisant colt, vous pouvez facilement définir des paramètres flexibles et résistants aux changements de code comme ʻAllenNLP. Il implémente également certaines fonctionnalités non trouvées dans ʻAllenNLP` pour le rendre plus facile à utiliser dans plus de cas.

Fonction d'enregistrement

Voici un exemple d'utilisation de colt:

import typing as tp
import colt

@colt.register("foo")
class Foo:
    def __init__(self, message: str) -> None:
        self.message = message

@colt.register("bar")
class Bar:
    def __init__(self, foos: tp.List[Foo]) -> None:  # ---- (*)
        self.foos = foos

config = {
    "@type": "bar",  # `@type`Spécifiez la classe avec
    "foos": [
        {"message": "hello"},  #Le type ici est(*)Déduit de l'indice de type
        {"message": "world"},
    ]
}

bar = colt.build(config)  #Construire des objets à partir de la configuration

assert isinstance(bar, Bar)

print(" ".join(foo.message for foo in bar.foos))  # => "hello world"

Enregistrez la classe avec colt.register (" <identificateur de classe> "). Côté paramétrage, décrivez au format {" @type ":" <identificateur de classe> ", (argument) ...}.

Lors de la construction d'un objet à partir d'un paramètre, appelez colt.build (<setting dict>).

S'il n'y a pas de champ «@ type» dans le paramètre et que l'indication de type est écrite dans l'argument correspondant, l'objet est créé en fonction de l'indication de type. Dans l'exemple ci-dessus, l'indication de type List [Foo] est donnée à l'argument foos de Bar, ainsi le contenu de foos dans config est converti en objets de la classe Foo.

Les indices de type ne sont pas toujours requis pour «colt». Si vous n'utilisez pas d'indices de type, écrivez @ type sans l'omettre.


config = {
    "@type": "bar",
    "foos": [
        {"@type": "bar", "message": "hello"},
        {"@type": "bar", "message": "world"},
    ]
}

S'il n'y a pas de @ type ou d'indice de type, il est simplement traité comme dict.

Fonction d'importation

Vous pouvez également utiliser colt pour les modèles existants inclus dans scikit-learn etc. Si le nom spécifié par «@ type» n'est pas «enregistré», il sera importé automatiquement.

Voici un exemple d'utilisation de StackingClassifier de scikit-learn:

import colt

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

config = {
    "@type": "sklearn.ensemble.StackingClassifier",
    "estimators": [
        ("rfc", { "@type": "sklearn.ensemble.RandomForestClassifier",
                  "n_estimators": 10 }),
        ("svc", { "@type": "sklearn.svm.SVC",
                  "gamma": "scale" }),
    ],
    "final_estimator": {
      "@type": "sklearn.linear_model.LogisticRegression",
      "C": 5.0,
    },
    "cv": 5,
}

X, y = load_iris(return_X_y=True)
X_train, X_valid, y_train, y_valid = train_test_split(X, y)

model = colt.build(config)
model.fit(X_train, y_train)

valid_accuracy = model.score(X_valid, y_valid)
print(f"valid_accuracy: {valid_accuracy}")

Dans l'exemple ci-dessus, le modèle décrit dans config peut être remplacé s'il a l'API de scikit-learn. Par exemple, pour rechercher dans la grille LGBMClassifier avec GridSearchCV:

config = {
    "@type": "sklearn.model_selection.GridSearchCV",
    "estimator": {
        "@type": "lightgbm.LGBMClassifier",
        "boosting_type": "gbdt",
        "objective": "multiclass",
    },
    "param_grid": {
        "n_estimators": [10, 50, 100],
        "num_leaves": [16, 32, 64],
        "max_depth": [-1, 4, 16],
    }
}

À propos de la lecture du fichier de paramètres

colt ne fournit pas de fonction pour lire les paramètres d'un fichier. Si vous voulez lire les paramètres d'un fichier, convertissez votre format préféré tel que JSON / Jsonnet ou YAML en «dict» et transmettez-le à «colt».

Autres fonctions détaillées

Importation de module

Si vous vous inscrivez dans plusieurs fichiers différents, toutes les classes à utiliser au moment de «colt.build» doivent être importées. colt peut utiliser cold.import_modules pour importer récursivement plusieurs modules.

Par exemple, considérez la structure de fichiers suivante:

.
|-- main.py
 `- models
    |-- __init__.py
    |-- foo.py
     `- bar.py

Disons que models / foo.py et models / bar.py ont respectivement la classe Foo et la classe Bar register, et main.py fait colt.build. .. Utilisez colt.import_modules ([" <nom du module> ", ...]) dans main.py comme suit.

main.py


colt.import_modules(["models"])
colt.build(config)

Si vous passez une liste de noms de modules à colt.import_modules, chaque module et ci-dessous seront importés récursivement. Dans l'exemple ci-dessus, nous avons passé [" models "] comme argument, donc tous les modules sous le module models seront importés et Foo, Bar sera disponible.

Argument de position

Lors de la description des arguments positionnels dans les paramètres, spécifiez * comme clé et passez une liste (ou taple) d'arguments positionnels comme valeur.

@colt.register("foo")
class Foo:
    def __init__(self, x, y):
        ...

config = {"@type": "foo", "*": ["x", "y"]}

Spécifier le constructeur

Par défaut, colt construit un objet en passant des arguments de classe à __init__. Si vous souhaitez créer un objet à partir d'une méthode autre que __init__, vous pouvez spécifier:

@colt.register("foo", constructor="build")
class FooWrapper:
    @classmethod
    def build(cls, *args, **kwargs) -> Foo:
        ...

C'est pratique lorsque vous souhaitez l'utiliser comme wrapper pour une autre classe.

Changement de Metakey

Les clés spéciales telles que @ type et * ʻutilisées par coltpeuvent être modifiées. Par exemple, si vous voulez changer@ type en @et*en+, spécifiez-le dans colt.build` comme argument:

colt.build(config, typekey="@", argskey="+")

Si vous souhaitez conserver les paramètres communs, utilisez ColtBuilder.

builder = colt.ColtBuilder(typekey="@", argskey="+")
builder(config_one)
builder(config_two)

Exemple d'utilisation avec kaggle Titanic

J'ai essayé la compétition Titanic de kaggle en utilisant colt.

https://github.com/altescy/colt/tree/master/examples/titanic

De la création de fonctionnalités au modèle en utilisant pdpipe et scikit-learn La plupart du traitement de l'apprentissage à l'évaluation peut être défini. Tous les paramètres sont décrits comme Jsonnet ci-dessous configs. J'espère que cela vous sera utile lors de l'utilisation de colt.

en conclusion

Nous avons présenté les fonctions et les exemples d'utilisation de colt. J'espère que cela vous aidera lors de l'écriture des paramètres.

De plus, la fonctionnalité de colt est basée sur un excellent framework appelé ʻAllenNLP](https://allennlp.org/). [ʻAllenNLP regorge d'idées utiles pour de nombreuses tâches d'apprentissage automatique ainsi que pour le traitement du langage naturel, donc si vous êtes intéressé, veuillez l'utiliser.

Recommended Posts

Création d'un outil qui facilite la définition des paramètres des modèles d'apprentissage automatique
J'ai créé un outil qui facilite un peu la création et l'installation d'une clé publique.
[Python] J'ai créé un classificateur pour les iris [Machine learning]
[Mise à jour Ver1.3.1] J'ai créé une bibliothèque de prétraitement de données DataLiner pour l'apprentissage automatique
J'ai créé un outil qui facilite un peu la décompression avec CLI (Python3)
J'ai créé un outil utile pour Digital Ocean
J'ai créé un outil de nettoyage pour Google Container Registry
J'ai créé une VM qui exécute OpenCV pour Python
MALSS (introduction), un outil qui prend en charge l'apprentissage automatique en Python
J'ai créé un outil en Python qui clique avec le bouton droit sur un fichier Excel et le divise en fichiers pour chaque feuille.
Création d'un toolver qui crache le système d'exploitation, Python, les modules et les versions d'outils à Markdown
Ensemble de données pour l'apprentissage automatique
J'ai essayé de comparer la précision des modèles d'apprentissage automatique en utilisant kaggle comme thème.
J'ai créé un outil pour créer un nuage de mots à partir de wikipedia
J'ai fait un kit d'apprentissage pour word2vec / doc2vec / GloVe / fastText
J'ai créé un outil pour générer automatiquement un diagramme de transition d'état pouvant être utilisé à la fois pour le développement Web et le développement d'applications
[Python] J'ai écrit un test de "Streamlit" qui facilite la création d'applications de visualisation.
[Titan Craft] J'ai créé un outil pour invoquer un géant sur Minecraft
J'ai essayé de créer un site qui permet de voir facilement les informations mises à jour d'Azure
Je souhaite spécifier un fichier qui n'est pas une certaine chaîne de caractères comme cible logrotate, mais est-ce impossible?
Création d'un outil CLI client / serveur WebSocket (comme WebSocket version netcat)
Je souhaite créer un service d'apprentissage automatique sans programmation! API Web
J'ai essayé de créer un outil d'échafaudage pour le framework Web Python Bottle
J'ai créé un site d'apprentissage C ++
J'ai écrit un livre qui vous permet d'apprendre les implémentations et les algorithmes d'apprentissage automatique de manière équilibrée.
J'ai créé un conteneur Docker pour utiliser JUMAN ++, KNP, python (pour pyKNP).
J'ai changé de travail pour devenir ingénieur en apprentissage automatique chez AtCoder Jobs
[Python] J'ai fait un décorateur qui ne semble pas avoir d'utilité.
J'ai créé un outil pour parcourir automatiquement plusieurs sites avec Selenium (Python)
J'ai créé une application Web en Python qui convertit Markdown en HTML
J'ai créé un bot Discord en Python qui se traduit quand il réagit
J'ai créé un outil CLI pour convertir les images de chaque répertoire en PDF
J'ai créé un konoha de bibliothèque qui fait passer le tokenizer à une belle sensation
J'ai créé un outil pour convertir Jupyter py en ipynb avec VS Code
[Python] Il était très pratique d'utiliser la classe Python pour le programme ROS.
Je souhaite créer un service d'apprentissage automatique sans programmation!
J'ai demandé à un ami qui travaille dans l'apprentissage automatique dans une entreprise informatique très connue. Apprentissage automatique (traitement du langage naturel) Ce que je veux apprendre pour l'auto-apprentissage
J'ai créé un docset de tableau de bord pour Holoviews
Introduction à l'apprentissage automatique: fonctionnement du modèle
J'ai installé Python 3.5.1 pour étudier l'apprentissage automatique
Une introduction à OpenCV pour l'apprentissage automatique
Une introduction à Python pour l'apprentissage automatique
J'ai créé un système qui décide automatiquement de s'exécuter demain avec Python et l'ajoute à Google Agenda.
J'ai créé un outil d'estampage automatique du navigateur.
Je pensais qu'il serait lent d'utiliser l'instruction for dans NumPy, mais ce n'était pas le cas.
Créer un environnement de développement pour l'apprentissage automatique
J'ai fait une bibliothèque pour l'assurance actuarielle
J'ai fait un outil pour estimer le temps d'exécution de cron (+ débuts de PyPI)
Je viens de créer un outil pour afficher facilement les données sous forme de graphique par opération GUI
Version gratuite de DataRobot! ?? Introduction à «PyCaret», une bibliothèque qui automatise l'apprentissage automatique
Retour sur le concours d'apprentissage automatique sur lequel j'ai travaillé pour la première fois
J'ai créé un outil pour générer du Markdown à partir du fichier JSON Scrapbox exporté
J'ai essayé de prédire l'évolution de la quantité de neige pendant 2 ans par apprentissage automatique
J'ai essayé d'implémenter diverses méthodes d'apprentissage automatique (modèle de prédiction) en utilisant scicit-learn
J'ai essayé de traiter et de transformer l'image et d'élargir les données pour l'apprentissage automatique
J'ai créé un outil pour sauvegarder automatiquement les métadonnées de l'organisation Salesforce
Je veux faire du machine learning même sans serveur - Time Series Edition -
Une histoire à laquelle j'étais accro après la communication SFTP avec python
GTUG Girls + PyLadiesTokyo Meetup Je suis allé au premier machine learning