AI-United » NLP » HMTL hilft die Gesamtgenauigkeit bei NLP-Aufgaben zu verbessern

HMTL hilft die Gesamtgenauigkeit bei NLP-Aufgaben zu verbessern

HMTL hilft die NLP zu verbessern

HMTL ist ein Modell des Hierarchischen Multi-Task Learning, das wörtlich übersetzt wird als hierarchisches Multi-Task Learning. Es gibt  eine wachsende Welle sowohl im NLP als auch im Deep Learning im Allgemeinen, genannt Multi-Task Learning!


Multi-Task Learning ist eine Methode, bei der einer einzelnen Architektur beigebracht wird, verschiedene Aufgaben gleichzeitig auszuführen.

Eine hochwertige Online-Demoversion wurde erstellt, in der Sie interaktiv mit HMTL interagieren können. Probieren Sie es selbst aus!

In der Regel wurden für jede dieser NLP-Aufgaben spezielle Modelle unabhängig voneinander trainiert (Named-Entity Recognition, Entity Mention Detection, Relation Extraction, Coreference Resolution).

Bei HMTL werden alle diese Ergebnisse von einem Modell mit einem direkten Durchgang erzielt!

Multi-Task Learning ist aber mehr als nur ein Weg, die Anzahl der Berechnungen zu reduzieren, indem mehrere Modelle durch ein einziges ersetzt werden.

Multi-Task Learning (MTL) ermutigt Modelle, Attribute und Methoden zu verwenden, die für andere Aufgaben sinnvoll sein können. Die grundlegende Antriebskraft von MTL liegt darin, dass enge Aufgaben voneinander profitieren müssen, indem sie ansprechendere Repräsentationen induzieren.

Warum verwendet man MTL?

Im klassischen Paradigma des Machine Learning lehren wir ein Modell, indem wir eine Verlustfunktion für eine bestimmte Aufgabe optimieren. Obwohl die Fokussierung auf eine interessante Aufgabe für viele Aufgaben des Machine Learning immer noch ein gängiger Ansatz ist, hat sie Nachteile. Diese Methode berücksichtigt keine Informationen, die von verwandten (oder fast verwandten) Aufgaben bereitgestellt werden können, um genauere Ergebnisse zu erreichen.

Lassen Sie uns einen Vergleich mit Usain Bolt anstellen, einem der vielleicht größten Sprinter, einem neunmaligen Olympiasieger und hältmehrere aktive Weltrekorde (November 2018). So trainiert der große Läufer intensiv und vielfältig, der größte Teil seiner Trainingskraft wird nicht für das Laufen, sondern für andere Übungen aufgewendet. Usain Bolt zum Beispiel hebt Gewichte, springt auf einen Hügel, macht Sprünge. Diese Übungen stehen nicht in direktem Zusammenhang mit dem Laufen, sondern entwickeln Muskeln und explosive Kraft, um die Hauptaufgabe (den Sprint) zu verbessern.

In der natürlichen Verarbeitung der Sprache wurde MTL zunächst in neuronalen Ansätzen von Forschern R. Collobert und J. Weston verwendet. Das von ihnen vorgeschlagene Modell war die MTL-Instanz, bei der mehrere verschiedene Aufgaben (mit Schichten für hochspezialisierte Aufgaben) auf den gleichen allgemeinen Investitionen basieren, die für verschiedene Aufgaben ausgebildet sind.

Wenn Sie eine Ansicht für verschiedene Aufgaben gemeinsam verwenden, kann dies wie eine einfache Möglichkeit klingen, relevante Informationen von einer Aufgabe zur anderen zu übertragen. Dies hat sich jedoch als ein wirklich sinnvoller Weg erwiesen, um die Verallgemeinerbarkeit des Modells zu verbessern.

Obwohl es möglich ist, im Voraus einfach zu erfassen, wie Informationen zwischen den Aufgaben übertragen werden, können wir dem Modell auch erlauben, selbst zu entscheiden, welche Parameter und Schichten es teilen soll, sowie welche Schichten für die Aufgabe am besten geeignet sind.

Seit kurzem sind Ideen gemeinsamer Vorstellungen wieder aufgetaucht, vor allem aufgrund der Verfolgung universeller Anlagevorschläge, die in allen Bereichen unabhängig von der spezifischen Aufgabe eingesetzt werden können. Einige Leute sind auf die MTL angewiesen. Subramanian et al. zum Beispiel stellten fest, dass, um ein breites Spektrum von Aufgaben verallgemeinern zu können, mehrere linguistische Aspekte des Vorschlags kodiert werden müssen. Eine Gensen – MTL-Architektur mit einer allgemeinen Darstellung des Gebers mit mehreren nachfolgenden Schichten für spezifische Aufgaben wurde vorgeschlagen.

Multi-Task Learning erregt heute viel Aufmerksamkeit und wird für ein breites Aufgabenspektrum nicht nur in der natürlichen Sprachverarbeitung, sondern auch in der Bildverarbeitung zwingend vorgeschrieben. Vor kurzem wurden Benchmarks wie der GLUE Benchmark vorgestellt, um die allgemeine Leistungsfähigkeit von MTL-Architekturen und ganz allgemein die Modelle des Sprachverständnisses zu bewerten.

Multi-Task Learning in Python

Lassen Sie uns nun den Code schreiben, um zu sehen, wie MTL in der Praxis funktioniert. Ein sehr wichtiger Teil ist das Training, wobei  die folgenden Fragen beantwortet werden müssen:

  • Wie kann man das neuronale Netzwerk lehren?
  • In welcher Reihenfolge muss man die verschiedenen Probleme lösen?
  • Sollen alle Aufgaben in der gleichen Anzahl von Epochen gelehrt werden?

Es gibt keinen Konsens zu diesen Fragen. In der Literatur sind viele Variationen vorhanden.

Lassen Sie uns zunächst mit einem einfachen und allgemeinen Teil des Codes beginnen, der für Lernprozesse gleichgültig ist:

  • Wählen Sie die Aufgabe aus (unabhängig vom gewählten Algorithmus);
  • Wählen Sie die Charge im Datensatz für die ausgewählte Aufgabe aus (Stichproben der Charge sind fast immer eine gute Wahl);
  • Wir werden einen direkten Durchgang durch das neuronale Netzwerk machen;
  • Lassen Sie uns den Fehler in die entgegengesetzte Richtung verteilen.

Diese vier Schritte müssen ausreichen.

Während der direkten Vorwärtsrechnung berücksichtigt das Modell die Verluste bei der Aufgabe des Interesses. Beim Rückwärtsfahren werden die aus der Verlustfunktion berechneten Gradienten jedoch über das Netzwerk verteilt, um beide Schichten für spezifische Aufgaben und allgemeine (und alle anderen relevanten) Lernparameter gleichzeitig zu optimieren.

Die Website von Hugging Face präsentiert eine gute Bibliothek, AllenNLP, die von Allen Institute of Information Technology entwickelt wurde. Diese Bibliothek ist ein leistungsstarkes und dennoch flexibles Werkzeug für die Forschung am NLP. AllenNLP kombiniert die Flexibilität von PyTorch mit intelligenten Datenlade- und Verarbeitungsmodulen, die speziell für NLP-Aufgaben entwickelt wurden.

Code

Unten betrachten wir einen einfachen Teil des Codes zur Erstellung eines MTL-Trainingsmodells auf der Grundlage von AllenNLP.

Lassen Sie uns zuerst eine Task-Klasse vorstellen, die Datensätze für bestimmte Aufgaben und zugehörige Attribute enthält.

from allennlp.data.iterators import DataIterator

class Task():
    """
    A class to encapsulate the necessary informations (and datasets)
    about each task.
    Parameters
    ----------
    name : ``str``, required
        The name of the task.
    validation_metric_name : ``str``, required
        The name of the validation metric to use to monitor training
        to select the best epoch and to stop the training based on exit condition.
    validation_metric_decreases : ``bool``, required
        Whether or not the validation metric should decrease for improvement.
    evaluate_on_test : ``bool`, optional (default = False)
        Whether or not the task should be evaluated on the test set at the end of the training.
    """
    def __init__(self,
                name: str,
                validation_metric_name: str,
                validation_metric_decreases: bool,
                evaluate_on_test: bool = False) -> None:
        self._name = name

        self._train_data = None
        self._validation_data = None
        self._test_data = None
        self._evaluate_on_test = evaluate_on_test

        self._val_metric = validation_metric_name
        self._val_metric_decreases = validation_metric_decreases

        self._data_iterator = None

    def load_data(self,
                dataset_path: str,
                dataset_type: str):
        """
        Load a dataset from a file and store it.
        Parameters
        ----------
        dataset_path: ``str``, required
            The path to the dataset.
        dataset_type: ``str``, required
            The type of the dataset (train, validation, test)
        """
        assert dataset_type in ["train", "validation", "test"]

        dataset = read(dataset_path) # Replace with whatever loading you want.
        setattr(self, "_%s_data" % dataset_type, dataset)
    
    def set_data_iterator(self,
                         data_iterator: DataIterator):
        self._data_iterator = data_iterator

Nachdem wir nun die Task-Klasse haben, können wir unser Model definieren.

Das Erstellen eines Modells in AllenNLP ist nicht schwer. Dazu machen Sie Ihre Klasse einfach von der Klasse allennlp.models.model.Model vererbbar. Dabei werden viele Methoden automatisch erhalten, wie z.B. get_regularization_penalty(), die das Modell (d.h. L1 oder L2 Regularisierung) während des Trainings verfeinern.

Lassen Sie uns über die beiden wichtigsten Methoden sprechen, die wir im Netzwerk verwenden werden, forward() und get_metrics(). Diese Methoden berechnen während des Trainings den direkten Durchlauf (bis hin zur Berechnung von Verlusten) bzw. die Trainings-/Bewertungskennzahlen für diese Aufgabe.

Zu den wichtigen Elementen des Multi-Task-Trainings gehört das Hinzufügen eines spezifischen Arguments task_name, das verwendet wird, um die Aufgabe auszuwählen, die während des Trainings von Interesse ist. Wir können dies so schreiben:

import torch

from allennlp.models.model import Model

class MyMTLModel(Model):
    def __init__(self):
        """
        Whatever you need to initialize your MTL model/architecture.
        """
  
    def forward(self,
                task_name: str,
                tensor_batch: torch.Tensor):
        """
        Defines the forward pass of the model. This function is designed
        to compute a loss function defined by the user.
        It should return 
        
        Parameters
        ----------
        task_name: ``str``, required
            The name of the task for which to compute the forward pass.
        tensor_batch: ``torch.Tensor``, required
            An embedding representation of the input to pass through the model.
            
        Returns
        -------
        output_dict: ``Dict[str, torch.Tensor]``
            An output dictionary containing at least the computed loss for the task of interest.
        """
        raise NotImplementedError
  
    def get_metrics(self, 
                    task_name: str):
        """
        Compute and update the metrics for the current task of interest.
        
        Parameters
        ----------
        task_name: ``str``, required
            The name of the current task of interest.
        Returns
        -------
        A dictionary of metrics.
        """
        raise NotImplementedError

Der Schlüsselpunkt in MTL ist die Wahl der Reihenfolge, in der die Aufgaben ausgeführt (gelernt) werden müssen. Man muss eine Aufgabe nach jedem Parameter-Update zufällig aus einer einheitlichen Verteilung auswählen (vorwärts + rückwärts durch das neuronale Netzwerk). Dieser Algorithmus wurde in mehreren frühen Werken verwendet, wie z.B. im oben genannten Gensen.

Im nächsten Teil des Codes ist das Verfahren der Aufgabenauswahl implementiert. Hier ist task_list definiert als eine Liste von Task-Aufgaben, auf die wir unser Modell trainieren wollen.

from typing import List
import numpy as np

from allennlp.data.iterators import DataIterator

### Set the Data Iterator for each task ###
# The data iterator is responsible for yield batches over the specified dataset.
for task in task_list:
    task_name = task._name
    task.set_data_iterator(DataIterator()) # Set whatever DataIterator you like.
    
    
### Create the sampling probability distribution over the tasks ###
sampling_prob = [task._data_iterator.get_num_batches(task._train_data) for task in task_list]
sampling_prob = sampling_prob / np.sum(sampling_prob)


def choose_task(sampling_prob):
    """
    Randomly choose one task to train.
    """
    return np.argmax(np.random.multinomial(1, sampling_prob))

Lassen Sie uns unser MTL-Modell starten. Man kann sehen, wie man alle elementaren Teile, die man zuvor erstellt hat, bauen kann.

Iterationen der train()-Methode werden von Aufgaben entsprechend ihrer Wahrscheinlichkeitsverteilung durchgeführt. Das Verfahren optimiert auch die Parameter des MTL-Modells Schritt für Schritt.

from allennlp.training.optimizers import Optimizer


class MultiTaskTrainer():
    def __init__(self,
                model: Model,
                task_list: List[Task])
        self._model = model
        self._task_list = task_list
        
        self._optimizers = {}
        for task in self._task_list:
            self._optimizers[task._name] = Optimizer() # Set the Optimizer you like.
            # Each task can have its own optimizer and own learning rate scheduler.
        
        
    def train(self,
             n_epochs: int = 50):
        
        ### Instantiate the training generators ###
        self._tr_generators = {}
        for task in self._task_list:
            data_iterator = task._data_iterator
            tr_generator = data_iterator(task._train_data,
                                        num_epochs = None)
            self._tr_generators[task._name] = tr_generator
        
        ### Begin Training ###
        self._model.train() # Set the model to train mode.
        for i in range(n_epochs):
            for _ in range(total_nb_training_batches):
                task_idx = choose_task()
                task = self._task_list[task_idx]
                task_name = task._name
                
                next_batch = next(self._tr_generators[task._name]) # Sample the next batch for the current task of interest.
                
                optimizer = self._optimizers[task._name] # Get the task-specific optimizer for the current task of interest.			
                optimizer.zero_grad()
                
                output_dict = self._model.forward(task_name = task_name, 
                                                  tensor_batch = batch) #Forward Pass
                
                loss = output_dict["loss"]
                loss.backward() # Backward Pass

Es gibt noch andere Methoden, mit denen Sie das MTL-Modell weiterführen können.  Hier sind die wichtigsten Ideen zur weiteren Verbesserung des Modells:

  • Konsequente Regularisierung. Eines der Hauptprobleme beim MTL-Modelltraining ist das Vergessen. Das Modell vergisst alle oder einen Teil der Informationen, die sich auf das Lernen der vorherigen Aufgabe beziehen. Dieses Phänomen wiederholt sich immer wieder, wenn mehrere Aufgaben nacheinander ausgeführt werden. Hashimoto et al. stellen eine konsequente Regularisierung dar: Sie verhindert zu viel Parameteraktualisierung im Vergleich zu früheren Epochen, indem sie der Verlustfunktion eine L2-Feineinstellung hinzufügt. In dieser Konfiguration ändert der MTL-Coach die Aufgabe nicht nach der Aktualisierung der Parameter, sondern durchläuft den gesamten Trainingsdatensatz der jeweiligen Aufgabe.
  • Multi-Task Learning als Frage-Antwort-System. Vor kurzem präsentierten McCann et al. [7] ein neues Paradigma in der Durchführung von Multi-TaskTraining. Jede Aufgabe wird in eine Frage- und Antwortaufgabe umformuliert, und ein einziges Modell (MQAN) wird gelehrt, 10 verschiedene Aufgaben, die in diesem Beitrag diskutiert werden, gemeinsam zu beantworten. MQAN erzielt State-of-the-Art-Ergebnisse in mehreren Aufgaben, wie z.B. WikiSQL, einer semantischen Parsing-Aufgabe. Grundsätzlich werden in diesem Beitrag die Grenzen des Monotask-Lernens und die Beziehung zwischen Multi-Task-Learning und Transfer Learning diskutiert.

Verbesserung des State-of-the-Arts bei semantischen Aufgaben: Hierarchisches Multi-Task Learning (HMTL)-Modell

Wir haben bereits über das Ausbildungsprogramm gesprochen, jetzt lohnt es sich, die Frage zu beantworten, wie wir das Modell schaffen können, das von diesem vielseitigen Ausbildungsprogramm am meisten profitieren wird.

In einem kürzlich auf der AAAI im Januar vorgestellten Beitrag wurde vorgeschlagen, ein solches Modell in Form einer Hierarchie zu konstruieren. Eine ausführliche Hierarchie wird zwischen einer Reihe genau abgestimmter semantischer Aufgaben aufgebaut, um die linguistischen Hierarchien zwischen den verschiedenen Aufgaben widerzuspiegeln (siehe auch Hashimoto et al.).

Hinter der hierarchischen Struktur des Modells verbirgt sich die folgende Bedeutung. Einige Aufgaben können einfach sein und erfordern begrenzte Änderungen an den Quelldaten, während andere mehr Wissen und eine komplexere Verarbeitung der Eingangsdaten erfordern.

Wir betrachten eine Reihe, die aus folgenden semantischen Aufgaben besteht:

  • Named Entity Recognition;
  • Entity Mention Detection;
  • Relation Extraction;
  • Coreference Resolution.

Das Modell ist hierarchisch organisiert, wie in der Grafik dargestellt. Einfache Aufgaben werden auf den unteren Ebenen des neuronalen Netzwerks und komplexere Aufgaben in den tieferen Schichten gelöst.

Wir haben festgestellt, dass diese Aufgaben vom Multi-Task-Training profitieren können:

  • Die Kombination dieser 4 Aufgaben führt zu state-of-the-art Ergebnissen bei 3 von ihnen (Named Entity Recognition, Relation Extraction und Entity Mention Detection);
  • Das MTL-Framework beschleunigt wesentlich das Lernen im Vergleich zu Mono-Task-Frameworks.

Wie kann man HTML in Ihrem Umfeld einsetzen?

Möchten Sie mehr über KI erfahren und wie Sie es in Ihrem Unternehmen einsetzen können?

Diese und weitere Fragen beantwortet gerne das AI United Team per Email oder in dem Q&A Bereich.

Quelle

AI-United-Redaktion

Kommentar hinzufügen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.