PL-Marker (ACL 2022) – Informationsextraktion (NER+RE) Neues SOTA, Papieranalyse und Code-Browsing

Motivation: Frühere Arbeiten zur Extraktion von Entitäten und Beziehungen konzentrierten sich darauf, wie man bessere Span-Darstellungen von vorab trainierten Encodern erhält. Es ignoriert jedoch die Wechselbeziehung zwischen Bereichen (Paaren).
Beitrag: Es wird eine neue Spannendarstellungsmethode namens Packed Levitated Markers (PL-Marker) vorgeschlagen.

  • Berücksichtigen Sie die Wechselbeziehungen zwischen Bereichen (Paaren), indem Sie die Markierungen im Encoder strategisch packen.
  • Es wird eine nachbarschaftsorientierte Packstrategie vorgeschlagen , die die Nachbarschaftsspanne umfassend berücksichtigt, um die Informationen über die Entitätsgrenzen besser zu modellieren.
  • Für diese komplexeren Span-Paar-Klassifizierungsaufgaben entwerfen die Autoren eine subjektorientierte Packstrategie , die jedes Subjekt und alle seine Objekte packt, um die Wechselbeziehung zwischen Span-Paaren desselben Subjekts zu simulieren.

„Packed Levitated Marker for Entity and Relation Extraction“ – ACL 2022 ( Code )

Vorwort: Einführung in verwandte Arbeiten

  • Der aktuelle Beziehungsextraktionsalgorithmus wird nach der Verarbeitungsmethode klassifiziert:
    • Pipeline-Ansatz: Zuerst die Entität extrahieren und dann die Beziehung beurteilen
      • z. B.: „Ein frustrierend einfacher Ansatz zur Extraktion gemeinsamer Entitäten und Beziehungen“ von Chen Danqi (im Folgenden als PURE bezeichnet)
    • Gemeinsame Entitäts- und Realtionsextraktion: Das gemeinsame Modell, indem die gemeinsame Aufgabe in das folgende Problem umgewandelt wird:
      • Fragen zum Ausfüllen von Formularen, z. B.: Tabellensequenz, TPlinker
      • Probleme mit der Sequenzkennzeichnung, wie zum Beispiel: ETL Span, PRGC
      • seq2seq-Probleme, wie zum Beispiel: SPN4RE

Derzeit gibt es drei Hauptmethoden zur Extraktion der Spannendarstellung: T-Concat, Solid Marker und Levitated Marker.

  1. T-Concat
    T-Concat verbindet die Einbettungen von Span-Grenztoken (Anfang und Ende), um Span-Einbettungen darzustellen. Diese Methode bleibt auf der Token-Ebene, um relevante Informationen zu erhalten, und ignoriert die Beziehung zwischen Grenz-Token. Dies ist die Methode, die das NER-Modell in „A Frustratingly Easy Approach for Joint Entity and Relation Extraction“ (im Folgenden als PURE bezeichnet) von Herrn Chen Danqi verwendet.

  2. Durchgezogene Markierung (feste Markierung)
    Diese Methode fügt explizit eine feste Markierung am Anfang und am Ende des Abschnitts ein, um den Abschnitt im Eingabetext hervorzuheben. Für das Objekt-Subjekt-Abschnittspaar wird er vor und nach dem Betreff-Abschnitt platziert und Objektspanne Fügen Sie jeweils ein Paar durchgezogener Markierungen ein. Es ist schwierig, mit dieser Methode den Fall mehrerer Objekt-Subjekt- Paare zu handhaben, da sie weder zwischen verschiedenen Objekten und Subjekten im selben Satz unterscheiden noch den Fall überlappender Spannen verarbeiten kann. Dies ist die Art und Weise, wie PURE-Full verwendet wird.

  3. Der schwebende Marker (Aufhängungsmarkierung)
    setzt zunächst ein Paar schwebender Markierungen so, dass sie dieselben Positionsinformationen wie das Grenztoken des Bereichs teilen, und bindet dann ein Paar schwebender Markierungen durch einen gerichteten Aufmerksamkeitsmechanismus zusammen. Konkret werden zwei Markierungen im Schwebemarker so eingestellt, dass sie in der Aufmerksamkeitsmaskenmatrix füreinander sichtbar, für den Texttoken und andere Markierungen des Schwebemarkers jedoch unsichtbar sind.
    Das RE-Modell in PURE verwendet diese Methode. Es ersetzt einfach feste Markierungen durch schwebende Markierungen mit Entitätstypinformationen. Derzeit wird diese Methode nur in PURE-Approx verwendet und der Effekt wird im Vergleich zu PURE-Full abgezinst. Das Papier geht davon aus, dass die Methode, einfach die Gleitmarkierung hinter dem Satz zu platzieren, die Beziehung zwischen mehreren Spannen nicht berücksichtigt;

Hier konzentrieren wir uns auf PURE. PL-Marker ist eine Art Pipeline-Methode und auf dieser Grundlage auch innovativ. Hier können Sie sich auf die entsprechende Analyse des Papiers beziehen, um diesen Blog anzuzeigen. Die Erklärung ist relativ klar .
REIN

  • Ideen:
  1. Zuerst Entitäten extrahieren: Senden Sie den Text an PLM, um die kontextuelle Darstellung jedes Tokens zu erhalten, fügen Sie dann das Start-Token jedes Spans , die kontextuelle Darstellung des End-Tokens und die Einbettung der Span-Länge zusammen, um die Span-Darstellung zu erhalten, und senden Sie ihn dann Es wird in zwei Schichten des neuronalen Feedforward-Netzwerks umgewandelt und schließlich der Entitätstyp vorhergesagt.
  2. Neubeurteilungsbeziehung: Die Methode zum Einfügen von „ typisierten Markierungen “ vor und nach der Subjektspanne und der Objektspanne im Satz wird übernommen . Diese typisierte Markierung ist ein Markierungspaar. Die typisierten Markierungen der Objektspanne sind Startmarkierungen [O: Entitätstyp] und Endmarkierung [ /O: Entitätstyp], [S: Entitätstyp] und [/S: Entitätstyp] des Subjektbereichs. Nachdem der Satz auf diese Weise transformiert wurde, wird der transformierte Satz an das PLM gesendet. Anschließend werden die Kontextdarstellung der Subjektspanne und die Startmarkierung des Objekts als Darstellung der Spanne zusammengefügt und anschließend die Beziehung hergestellt Der Typ der Spanne wird durch lineare Transformation und Softmax vorhergesagt. (im Folgenden PURE-Full genannt)
  • Es gibt ein Problem: Da für jede Trainings- und Vorhersagestichprobe nur ein Paar aus Subjektspanne und Objektspanne eingefügt werden kann, ist die Berechnung sehr aufwändig
  • Die spezifische Analyse von PURE kann unter https://github.com/km1994/nlp_paper_study_information_extraction/tree/main/information_extraction/ERE_study/PURE eingesehen werden

Ideen für Abschlussarbeiten

  • PL-Marker schlägt einige Optimierungsmethoden vor
    • Optimierungsmethode eins:
      • Motivation: Rechenproblem in PURE
      • Ideen:
        • Platzieren Sie zunächst alle getippten Markierungen am Ende des Satzes.
        • Lassen Sie dann die eingegebene Markierung die Position teilen, die mit dem Starttoken und dem Endtoken im entsprechenden Subjektbereich oder Objektbereich eingebettet ist, und verwenden Sie die Aufmerksamkeitsmaskenmatrix, um einige Einschränkungen zu vervollständigen.
        • Die typisierte Markierung kann nur mit dem Text und der typisierten Markierung im aktuellen Span-Paar berücksichtigt werden, und der Text kann nur mit dem Text berücksichtigt werden
      • Vorteile: Mehrere Span-Paare können parallel in einem Satz verarbeitet werden. Die von ihnen vorgeschlagene Beschleunigungsmethode verbessert die Geschwindigkeit der Beziehungsextraktion.
      • Nachteile: Die Wirkung wird leicht reduziert
    • Optimierungsmethode zwei:
      • Motivation: Leistungseinbußen durch Optimierungsmethode 1
      • In früheren Arbeiten gibt es drei Span-Darstellungen ( Einzelheiten finden Sie im Vorwort ):
      • Methode zur Darstellung der Papierspanne:
        • Kombination von Solid Marker (feste Markierung) und schwebendem Marker (hängende Markierung)

        • Fügen Sie hier eine Bildbeschreibung ein

        • Es werden zwei Möglichkeiten zum Verpacken der Marker vorgeschlagen:

          • Bei der Durchführung von NER wurde Folgendes vorgeschlagen: Nachbarschaftsorientiertes Packen für Spannweiten, bei dem die hängenden Markierungen benachbarter Spannweiten in dieselbe Stichprobe eingefügt werden ;
          • Bei RE habe ich Folgendes vorgeschlagen: Subjektorientiertes Packen für Span-Paare, bei dem der Subjekt-Span mit festen Markierungen in den Satz eingefügt wird und die entsprechenden Objekt-Spannungen am Ende des Satzes mit Gleitmarkierungen gespleißt und eingefügt werden eine Probe ;

Gesamtrahmen

Zwei Etikettenverpackungsstrategien von PL-Marker

Das von PL-Marker verwendete Modell ist PLM, das PURE-Approx ähnelt:

  • Der Startmarker im schwebenden Markerpaar, das am Ende des Satzes gespleißt ist, teilt die Positionseinbettung mit dem Starttoken des entsprechenden Bereichs im Satz, und der Endmarker teilt die Positionseinbettung mit dem Endtoken des entsprechenden Bereichs.
  • Verwenden Sie die gerichtete Aufmerksamkeit, um schwebende Markierungen zu binden, sodass der Hover seine Partnermarkierung und den Text davor sehen kann, nicht jedoch andere Paare von Hover-Markierungen, und der Text kann nur den Text sehen

Fügen Sie hier eine Bildbeschreibung ein

1. NER-Stadium

Das in diesem Teil verwendete Suspendierungszeichen levitated markerssetzt alle möglichen Entity-Span-Suspendierungszeichenpaare am Ende des Satzes. Dabei gibt es jedoch ein Problem, da alle möglichen Abschnitte im Satz durchlaufen werden müssen und die Länge des Satzes, die PLM verarbeiten kann, begrenzt ist.

Daher schlägt der Autor eine Packstrategie vor. Während des Packens werden ähnliche Spans zusammengestellt, um die Grenzen von Spannen besser unterscheiden zu können (und, was noch wichtiger ist, den Unterschied zwischen Spannen zu unterscheiden, die mit demselben Wort beginnen). gleiche oder ähnliche Anfänge in einer Stichprobe.

Für einen Satz _ _ _ _ _ _

  1. Zunächst werden alle Hover-Tag-Paare (ein Start-Tag, ein End-Tag) sortiert. Sortieren Sie zunächst die Start-Token der durch jedes Paar schwebender Markierungen dargestellten Bereiche in aufsteigender Reihenfolge und dann in aufsteigender Reihenfolge entsprechend der Position der End-Token, um nach dem Sortieren eine Liste der Kandidaten-Bereiche zu erhalten.
  2. Anschließend werden alle schwebenden Markierungen in K Gruppen aufgeteilt und gespleißt, sodass die aufgehängten Markierungen benachbarter Spannen in dieselbe Gruppe unterteilt (dh zusammengespleißt) werden und die K aufgehängten Markierungssequenzen nach dem Spleißen gespleißt werden Generieren Sie nach der Satz-Token-Sequenz separat K Trainingsbeispiele (wie in der obigen Abbildung dargestellt, [ O ] , [ / O ] repräsentieren levitated markers). Dies ist die nachbarschaftsorientierte Packstrategie ( neighborhood-oriented packing strategy). Tatsächlich ist es erschöpfend, alle Bereiche zu durchlaufen
  3. Senden Sie abschließend die Trainingsinstanz an das PLM (z. B. Bert) und setzen Sie für jedes Paar schwebender Marker s_i=(a,b) jeweils ihre Startmarker ( ), Darstellung h_a^{(s)} undstart token marker Endmarker ( ) Die Darstellung h_b^{(e)} wird als Darstellung ihrer entsprechenden Spanne zusammengefügt: ϕ ( si ) = [ ha ( s ) ; hb ( e ) ] \phi (s_{i})=[h_a^ {( s)} ;h_b^{(e)}]end token markerϕ ( sich)=[ hA( s );HB( e )]
  4. Bei der Durchführung von NER werden die in den obigen Schritten erhaltene Spannendarstellung (d. h. das von PL-Marker extrahierte Spannenmerkmal) und die von der T-Concat-Methode extrahierte Spannendarstellung kombiniert, um den Entitätstyp vorherzusagen. Was für eine Fusion? Schauen Sie sich den Code an!

2. RE-Stufe

solid markersWie oben erwähnt, verwendet dieser Artikel eine gemischte levitated markersMethode in der RE-Phase und verwendet solid markersMarker subject spanund levitated markersMarkerkandidaten object.

Angenommen, die Eingabesequenz ist X, subject spans_i=(a,b) und ihre Kandidaten object spans: ( c 1, d 1),( c 2, d 2),⋯,( cm , d m). Die spezifische Methode ist wie folgt:

  • subject spanFügen Sie jeweils den Anfang und das Ende des Satzes ein solid marker([ S ] und [/S]) und verbinden Sie dann die entsprechenden Kandidaten object spanhinter dem Text in Form von Gleitzeichen ([ O ] und [ / O ]) (wie in der Abbildung gezeigt). Abbildung oben). Der Satz X = { x 1 , ⋯ , xn } wird umgewandelt in (das Symbol ∪ bedeutet Teilen position embedding):
    Fügen Sie hier eine Bildbeschreibung ein

  • Senden Sie die Trainingsinstanz an PLM, für jedes Span-Paar im Beispiel-Span-Paar ={s_{subject}, s_{object}}={(a,b),(c,d)}, das Subjekt-Span vor und nach solid markerdem Darstellungen von h_{ a-1 } und h_{ b+1 } und ein Paar schwebender Marker h_c^{(s)} und h_d^{(e)} werden als Darstellung des Paares zusammengefügt : ϕ ( si , sj ) = [ ha − 1 ; hb + 1 ; hc ( s ); hd ( e ) ] \phi (s_{i},s_{j})=[h_{a-1};h_{b+ 1 };h_c^{(s)} ;h_d^{(e)}] object spanlevitated markersspan pairϕ ( sich,Sj)=[ ha 1;Hb + 1;HC( s );HD( e )]

  • Um die Beziehung zwischen Entitätstypen und Beziehungstypen zu modellieren, fügten sie außerdem eine zusätzliche Verlustfunktion zur Vorhersage von Objekttypen hinzu.

  • Um einige zusätzliche Informationen hinzuzufügen, fügten sie die Vorhersage der umgekehrten Beziehung von Objekt zu Subjekt hinzu und realisierten so die Vorhersage einer bidirektionalen Beziehung. Tatsächlich implementierten sie eine objektorientierte Packstrategie (eine bidirektionale vorhergesagte umgekehrte Beziehung). Das Inverse-Relation-Modell ohne dieses Modell verursachte einen Leistungsabfall von 0,9 % bis 1,1 %. objectDies zeigt die Bedeutung der Modellierung und subjectzwischen Informationen in einem asymmetrischen Rahmen .

Zug

1.1 ACEDatasetNER

Schalten Sie verschiedene Beschriftungslisten entsprechend unterschiedlichen Datensätzen um und self.max_entity_length = args.max_pair_length * 2.
def is_punctuation: ob es sich um ein Satzzeichen handelt
def get_original_token: Sonderzeichen in Klammern umwandeln
def tokenize_word: unterteilt in RobertaTokenizer (Header ist ', Länge > 1, keine Satzzeichen) und andere Tokenizer
def initialize: ner_label_map->for: data = json.loads(line), subword2token(index*len[li]), token2subword(len[li]++) dient dazu, zu überprüfen, ob die vorherige Wortsegmentierung gründlich ist. Etwas zurückgeblieben

1.2 für _ in train_iterator:

t_total = len(train_dataloader) // args.gradient_accumulation_steps * args.num_train_epochs
num_warmup_steps=int(0.1*t_total)

for _ in train_iterator: für Schritt, Batch in enumerate(epoch_iterator):
Hinweis: wenn 'span' in agrgs.model_type: unterschiedlicher Datensatz-Vorprozess und inputs['mention_pos'] = batch[4]
danachoutputs = model(**inputs)
loss = outputs[0] # model outputs are always tuple in pytorch-transformers (see doc)

2 BertForSpanMarkerNER (der Code wird standardmäßig aufgerufen)

self.ner_classifier = nn.Linear(config.hidden_size*4, self.num_labels)
self.alpha = torch.tensor([config.alpha] + [1.0] * (self.num_labels-1), dtype=torch.float32)

BertModel: Outputs=# sequence_output, pooled_output, (hidden_states), (attentions)#Die letzten beiden, falls vorhanden, fügen Sie sie hinzu; es gibt keine

    def forward(
        self,
        input_ids=None,
        attention_mask=None,
        mentions=None,
        token_type_ids=None,
        position_ids=None,
        head_mask=None,
        inputs_embeds=None,
        labels=None,
        mention_pos=None,
        full_attention_mask=None,
    ):
        
        outputs = self.bert(
            input_ids,
            attention_mask=attention_mask,
            token_type_ids=token_type_ids,
            position_ids=position_ids,
            head_mask=head_mask,
            inputs_embeds=inputs_embeds,
            full_attention_mask=full_attention_mask,
        )
        hidden_states = outputs[0] #=sequence_output
        if self.onedropout:
            hidden_states = self.dropout(hidden_states)

        seq_len = self.max_seq_length
        bsz, tot_seq_len = input_ids.shape
        ent_len = (tot_seq_len-seq_len) // 2 #(1024-512)//2

        e1_hidden_states = hidden_states[:, seq_len:seq_len+ent_len]#+m1=PL-Marker抽取到的span特征h_a^(s)
        e2_hidden_states = hidden_states[:, seq_len+ent_len: ] #h_b^(e)


        m1_start_states = hidden_states[torch.arange(bsz).unsqueeze(-1), mention_pos[:, :, 0]] #span的start token的上下文表征
        m1_end_states = hidden_states[torch.arange(bsz).unsqueeze(-1), mention_pos[:, :, 1]] #end token,len=ent_len,z这两者是T-concat方法抽取的span表征

        feature_vector = torch.cat([e1_hidden_states, e2_hidden_states, m1_start_states, m1_end_states], dim=2) #拼接方式与BiNER不同
        if not self.onedropout:
            feature_vector = self.dropout(feature_vector)
        ner_prediction_scores = self.ner_classifier(feature_vector)


        outputs = (ner_prediction_scores, ) + outputs[2:]  # Add hidden states and attention if they are here

        if labels is not None:
            loss_fct_ner = CrossEntropyLoss(ignore_index=-1,  weight=self.alpha.to(ner_prediction_scores))
            ner_loss = loss_fct_ner(ner_prediction_scores.view(-1, self.num_labels), labels.view(-1))
            outputs = (ner_loss, ) + outputs

        return outputs #  (ner_loss, ner_prediction_scores) + (hidden states , attention)

**VERGLEICH MIT PURE**

Fügen Sie hier eine Bildbeschreibung ein
Die Darstellung der Spannweite he (si), ϕ(si) stellt die Einbettung der erlernten Spannweitenmerkmale dar [die Lernmethode und die Spleißmethode der Spannweitendarstellung he(si) sind wie folgt]

def batchify(samples, batch_size):
    """
    Batchfy samples with a batch size
    """
    num_samples = len(samples)

    list_samples_batches = []
    
    # if a sentence is too long, make itself a batch to avoid GPU OOM
    to_single_batch = []
    for i in range(0, len(samples)):
        if len(samples[i]['tokens']) > 350:
            to_single_batch.append(i)
    
    for i in to_single_batch:
        logger.info('Single batch sample: %s-%d', samples[i]['doc_key'], samples[i]['sentence_ix'])
        list_samples_batches.append([samples[i]])
    samples = [sample for i, sample in enumerate(samples) if i not in to_single_batch]

    for i in range(0, len(samples), batch_size):
        list_samples_batches.append(samples[i:i+batch_size])

    assert(sum([len(batch) for batch in list_samples_batches]) == num_samples)

    return list_samples_batches

spans = list_samples_batches[“spans”]

def _get_input_tensors(self, tokens, spans, spans_ner_label):
        start2idx = []
        end2idx = []
        
        bert_tokens = []
        bert_tokens.append(self.tokenizer.cls_token)
        for token in tokens: #将start2end tokenizer
            start2idx.append(len(bert_tokens))
            sub_tokens = self.tokenizer.tokenize(token)
            bert_tokens += sub_tokens
            end2idx.append(len(bert_tokens)-1)
        bert_tokens.append(self.tokenizer.sep_token)

        indexed_tokens = self.tokenizer.convert_tokens_to_ids(bert_tokens)
        tokens_tensor = torch.tensor([indexed_tokens])

        bert_spans = [[start2idx[span[0]], end2idx[span[1]], span[2]] for span in spans]
        bert_spans_tensor = torch.tensor([bert_spans])

        spans_ner_label_tensor = torch.tensor([spans_ner_label])

        return tokens_tensor, bert_spans_tensor, spans_ner_label_tensor

spans = bert_spans_tensor

def _get_span_embeddings(self, input_ids, spans, token_type_ids=None, attention_mask=None):
        sequence_output, pooled_output = self.albert(input_ids=input_ids, token_type_ids=token_type_ids, attention_mask=attention_mask)
        
        sequence_output = self.hidden_dropout(sequence_output)

        """
        spans: [batch_size, num_spans, 3]; 0: left_ned, 1: right_end, 2: width
        spans_mask: (batch_size, num_spans, )
        """
        spans_start = spans[:, :, 0].view(spans.size(0), -1)
        spans_start_embedding = batched_index_select(sequence_output, spans_start)
        spans_end = spans[:, :, 1].view(spans.size(0), -1)
        spans_end_embedding = batched_index_select(sequence_output, spans_end)

        spans_width = spans[:, :, 2].view(spans.size(0), -1)
        spans_width_embedding = self.width_embedding(spans_width)

        spans_embedding = torch.cat((spans_start_embedding, spans_end_embedding, spans_width_embedding), dim=-1)
        """
        spans_embedding: (batch_size, num_spans, hidden_size*2+embedding_dim)
        """
        return spans_embedding

Denn wenn der ursprüngliche Satz dargestellt wird, sind die Kontextinformationen, die wir nach dem Hinzufügen des Markers erhalten, unterschiedlich, da der Marker die Satzstruktur ändert. Um die Informationsdarstellung von Wörtern wiederverwenden zu können, verfolgen wir die folgende Strategie: Wir binden die Standortinformationen des Markers an die Standortinformationen am Anfang und Ende der Spanne. Auf diese Weise wird die Einbettung der Positionsinformationen des ursprünglichen Satzes nicht geändert. Dann schränken wir die Aufmerksamkeitsebene ein. Wir zwingen das Text-Token dazu, nur auf das Text-Token und nicht auf das Markierungs-Token zu achten, und alle diese 4 Token entsprechen demselben Span-Paar. Diese Änderung ermöglicht es uns, Token wiederzuverwenden. In der Praxis fügen wir alle Markierungen am Ende von Sätzen hinzu.
————————————————
Copyright-Erklärung: Dieser Artikel ist ein Originalartikel des CSDN-Bloggers „alkaid_sjtu“. Gemäß der CC 4.0 BY-SA-Copyright-Vereinbarung fügen Sie bitte den Original-Quelllink und dies bei Erklärung zum Nachdruck.
Ursprünglicher Link: https://blog.csdn.net/weixin_44047857/article/details/122074084

3 BertForSpanMarkerBiNER (gemäß der Implementierung der Papierformel)

# ...表示省略不写,后同
    def forward(
        ...
    ):
        outputs = self.bert(
            ...
        )
        hidden_states = outputs[0]
        if self.onedropout:
            hidden_states = self.dropout(hidden_states)

        seq_len = self.max_seq_length
        bsz, tot_seq_len = input_ids.shape
        ent_len = (tot_seq_len-seq_len) // 2

        e1_hidden_states = hidden_states[:, seq_len:seq_len+ent_len]
        e2_hidden_states = hidden_states[:, seq_len+ent_len: ]


        m1_start_states = hidden_states[torch.arange(bsz).unsqueeze(-1), mention_pos[:, :, 0]]
        m1_end_states = hidden_states[torch.arange(bsz).unsqueeze(-1), mention_pos[:, :, 1]]

        m1 = torch.cat([e1_hidden_states, m1_start_states], dim=2) #h_a^s
        m2 = torch.cat([e2_hidden_states, m1_end_states], dim=2) #h_b^e
        
        feature_vector = torch.cat([m1, m2], dim=2)
        if not self.onedropout:
            feature_vector = self.dropout(feature_vector)
        ner_prediction_scores = self.ner_classifier(feature_vector)

        # m1 = self.dropout(self.reduce_dim(m1))
        # m2 = self.dropout(self.reduce_dim(m2))

        m1 = F.gelu(self.reduce_dim(m1))
        m2 = F.gelu(self.reduce_dim(m2))


        ner_prediction_scores_bilinear = self.blinear(m1, m2)

        ner_prediction_scores = ner_prediction_scores + ner_prediction_scores_bilinear

        outputs = (ner_prediction_scores, ) + outputs[2:]  # Add hidden states and attention if they are here

        if labels is not None:
            loss_fct_ner = CrossEntropyLoss(ignore_index=-1,  weight=self.alpha.to(ner_prediction_scores))
            ner_loss = loss_fct_ner(ner_prediction_scores.view(-1, self.num_labels), labels.view(-1))
            outputs = (ner_loss, ) + outputs

        return outputs

4 ACEDataset (RE-Modul)

Im Vergleich zu 1 mehr

        self.max_pair_length = max_pair_length #
        self.max_entity_length = self.max_pair_length*2 #
        self.use_typemarker = args.use_typemarker #
        self.no_sym = args.no_sym #label_list 多两个;self.sym_labels = ['NIL'];#无'PER-SOC'

5 BertForACEBothOneDropoutSub (Code-Standard-Re-Aufruf)

           inputs = {'input_ids':      batch[0],
                     'attention_mask': batch[1],
                     'position_ids':   batch[2],
                     'labels':         batch[5],
                     'ner_labels':     batch[6],
                     }
           inputs['sub_positions'] = batch[3]
           inputs['mention_pos'] = batch[4]
           inputs['sub_ner_labels'] = batch[7]
def forward(
    self,
    input_ids=None,
    attention_mask=None,
    mentions=None,
    token_type_ids=None,
    position_ids=None,
    head_mask=None,
    inputs_embeds=None,
    sub_positions=None,
    labels=None,
    ner_labels=None,
):
    
    outputs = self.bert(
        input_ids,
        attention_mask=attention_mask,
        token_type_ids=token_type_ids,
        position_ids=position_ids,
        head_mask=head_mask,
        inputs_embeds=inputs_embeds,
    )
    hidden_states = outputs[0]
    hidden_states = self.dropout(hidden_states)
    seq_len = self.max_seq_length
    bsz, tot_seq_len = input_ids.shape
    ent_len = (tot_seq_len-seq_len) // 2

    e1_hidden_states = hidden_states[:, seq_len:seq_len+ent_len]
    e2_hidden_states = hidden_states[:, seq_len+ent_len: ]

    feature_vector = torch.cat([e1_hidden_states, e2_hidden_states], dim=2)

    ner_prediction_scores = self.ner_classifier(feature_vector)


    m1_start_states = hidden_states[torch.arange(bsz), sub_positions[:, 0]]
    m1_end_states = hidden_states[torch.arange(bsz), sub_positions[:, 1]]
    m1_states = torch.cat([m1_start_states, m1_end_states], dim=-1)

    m1_scores = self.re_classifier_m1(m1_states)  # bsz, num_label
    m2_scores = self.re_classifier_m2(feature_vector) # bsz, ent_len, num_label
    re_prediction_scores = m1_scores.unsqueeze(1) + m2_scores

    outputs = (re_prediction_scores, ner_prediction_scores) + outputs[2:]  # Add hidden states and attention if they are here

    if labels is not None:
        loss_fct_re = CrossEntropyLoss(ignore_index=-1,  weight=self.alpha.to(re_prediction_scores))
        loss_fct_ner = CrossEntropyLoss(ignore_index=-1)
        re_loss = loss_fct_re(re_prediction_scores.view(-1, self.num_labels), labels.view(-1))
        ner_loss = loss_fct_ner(ner_prediction_scores.view(-1, self.num_ner_labels), ner_labels.view(-1))

        loss = re_loss + ner_loss
        outputs = (loss, re_loss, ner_loss) + outputs

    return outputs  # (masked_lm_loss), prediction_scores, (hidden_states), (attentions)

6 BertForACEBothOneDropoutLeviPair (im Einklang mit der Papier-Re-Formel)

# ...表示省略不写,后同
    def forward(
        ...
    ):
        outputs = self.bert(
            ...
        )
        hidden_states = outputs[0]
        hidden_states = self.dropout(hidden_states)
        seq_len = self.max_seq_length
        bsz, tot_seq_len = input_ids.shape
        ent_len = (tot_seq_len-seq_len) // 4

        e1_hidden_states = hidden_states[:, seq_len:seq_len+ent_len] #h_a-1
        e2_hidden_states = hidden_states[:, seq_len+ent_len*1: seq_len+ent_len*2] #h_b+1
        e3_hidden_states = hidden_states[:, seq_len+ent_len*2: seq_len+ent_len*3] #h_c^s
        e4_hidden_states = hidden_states[:, seq_len+ent_len*3: seq_len+ent_len*4] #h_d_e

        m1_feature_vector = torch.cat([e1_hidden_states, e2_hidden_states], dim=2)
        m2_feature_vector = torch.cat([e3_hidden_states, e4_hidden_states], dim=2)
        feature_vector = torch.cat([m1_feature_vector, m2_feature_vector], dim=2) #/phi

        m1_ner_prediction_scores = self.ner_classifier(m1_feature_vector)
        m2_ner_prediction_scores = self.ner_classifier(m2_feature_vector)


        re_prediction_scores = self.re_classifier(feature_vector) # bsz, ent_len, num_label

        outputs = (re_prediction_scores, m1_ner_prediction_scores, m2_ner_prediction_scores) + outputs[2:]  # Add hidden states and attention if they are here

        if labels is not None:
            loss_fct_re = CrossEntropyLoss(ignore_index=-1,  weight=self.alpha.to(re_prediction_scores))
            loss_fct_ner = CrossEntropyLoss(ignore_index=-1)
            re_loss = loss_fct_re(re_prediction_scores.view(-1, self.num_labels), labels.view(-1))
            m1_ner_loss = loss_fct_ner(m1_ner_prediction_scores.view(-1, self.num_ner_labels), m1_ner_labels.view(-1))
            m2_ner_loss = loss_fct_ner(m2_ner_prediction_scores.view(-1, self.num_ner_labels), m2_ner_labels.view(-1))

            loss = re_loss + m1_ner_loss + m2_ner_loss
            outputs = (loss, re_loss, m1_ner_loss+m2_ner_loss) + outputs

        return outputs  # (masked_lm_loss), prediction_scores, (hidden_states), (attentions)

Was die Beziehung betrifft, besteht PURE darin, die Ausgabe und Einbettung von Subjekt und Objekt zu verbinden [BertForRelation und BertForRelationApprox]

PL-Marker vs. PURE

Im Allgemeinen umfassen die Verbesserungen von PL-Marker gegenüber PURE hauptsächlich:

Mit Blick auf die schwebende Markermethode von PURE wird eine Packstrategie für gepackte schwebende Marker vorgeschlagen .
In der NER-Stufe verwendet PURE eine auf Spannen basierende Standardmethode (T-concat). In diesem Artikel wird auch die Methode der gepackten schwebenden Markierungen für NER-Aufgaben verwendet.
In der RE-Phase wird die umgekehrte Beziehung eingeführt , um die Leistung von RE weiter zu verbessern. Gleichzeitig wird der von PURE verwendete typisierte Marker gelöscht und stattdessen die Funktion zum Verlust des Entitätstyps verwendet

PS

  • In diesem Artikel wurde durch Experimente festgestellt, dass sich PUREdie Verwendung im Vergleich typed markerzu negativ auf die Leistung auswirkt. Persönlich denke ich, dass aus der Perspektive der Intuition die Entitätstypinformationen definitiv eine Rolle bei der inspirierenden Beziehungsklassifizierung spielen werden (insbesondere beispielsweise bei den beiden Kandidatenbeziehungstypen „Geburtsdatum“ und „Nationalität“, falls vorhanden). Typen Es handelt sich um zwei Entitäten: „Person“ und „Zeit“, und die Beziehung zwischen ihnen ist „Geburtsdatum“ usw., nicht „Nationalität“). Der Grund für die experimentellen Ergebnisse in diesem Artikel könnte in der verwendeten Methode liegen und Modellstruktur sind nicht anwendbar. Ja, dies kann in Zukunft verbessert werden.
  • NERDie Stufe reduziert die Trainingszeit durch Gruppierung, aber der Zeitaufwand ist immer noch höher als bei der vorherigen SOTA, schließlich zählt sie alle Möglichkeiten auf span. Gibt es außer der Gruppierung noch eine andere Möglichkeit, die Berechnungszeit zu verkürzen ?

Je suppose que tu aimes

Origine blog.csdn.net/weixin_42455006/article/details/125716619
conseillé
Classement