[PYTHON] Ich habe versucht, die Genauigkeit der japanischen BERT- und der japanischen Distil-BERT-Satzklassifizierung mit PyTorch & Einführung der BERT-Technik zur Verbesserung der Genauigkeit zu vergleichen

Einführung

Ich habe versucht, japanisches BERT mit Huggingface / Transformatoren in vorheriger Artikel zu verwenden, aber wenn Sie Huggingface / Transformatoren verwenden, haben andere vorgelernte Das BERT-Modell von ist auch einfach zu handhaben.

In Liste der verwendbaren Modelle scheint es andere Modelle wie Distil BERT und ALBERT zu geben, die japanisch zu sein scheinen. Beide sind als leichtes BERT positioniert.

Diesmal wird kurz [DistilBERT von Namco Bandai] vorgestellt (https://github.com/BandaiNamcoResearchInc/DistilBERT-base-jp/blob/master/docs/GUIDE.md), das auch zum Umarmen des Gesichts verwendet werden kann Ich habe versucht, die Genauigkeit mit normalem BERT zu vergleichen. Abschließend werde ich eine der Techniken vorstellen, um die Genauigkeit bei der Klassifizierung von Sätzen mit BERT zu verbessern.

Was ist DistilBERT?

Ich werde die README von Namco Bandais Github so wie sie ist ausleihen.

DistilBERT ist ein Modell, das Huggingface auf der NeurIPS 2019 veröffentlicht hat und dessen Name für "Distilated-BERT" steht. Die eingereichten Unterlagen entnehmen Sie bitte hier.

Distil BERT ist ein kleines, schnelles und leichtes Transformer-Modell, das auf der BERT-Architektur basiert. DistilBERT soll 40% weniger Parameter als die BERT-Basis haben, 60% schneller laufen und 97% der BERT-Leistung beibehalten, gemessen am GLUE Benchmark.

DistilBERT wird mithilfe der Wissensdestillation trainiert, einer Technik, die ein großes Modell, das als Lehrer bezeichnet wird, in ein kleineres Modell, das als Schüler bezeichnet wird, komprimiert. Durch Destillieren von BERT erhalten Sie ein Transformer-Modell, das leichter ist und schneller läuft, während es viele Ähnlichkeiten mit dem ursprünglichen BERT-Modell aufweist.

Kurz gesagt, es fühlt sich wie eine leichte Version der BERT-Basis an, die eine hohe Geschwindigkeit erreicht (daher ist die Genauigkeit der der BERT-Basis etwas unterlegen). Lassen Sie uns tatsächlich sehen, wie schnell es ist und wie ungenau es ist.

Verwendung von DistilBERT

[Offizieller Github](https://github.com/BandaiNamcoResearchInc/DistilBERT-base-jp/blob/master/docs/GUIDE.md#transformers-%E3%83%A9%E3%82%A4%E3%83% 96% E3% 83% A9% E3% 83% AA% E3% 83% BC% E3% 81% 8B% E3% 82% 89% E8% AA% AD% E8% BE% BC% E3% 81% BF) Sie können es leicht von umarmenden Gesicht / Transformatoren auf der Straße nennen.

-Für Tokenizer tritt ein Fehler auf, wenn Sie dem Namen nicht wie unten gezeigt "cl-tohoku /" hinzufügen.

from transformers import AutoModel, AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("cl-tohoku/bert-base-japanese-whole-word-masking")
distil_model = AutoModel.from_pretrained("bandainamco-mirai/distilbert-base-japanese")  

Grundsätzlich kann es auf die gleiche Weise verwendet werden wie die japanische BERT-Basis, die in Letzter Artikel eingeführt wurde, aber aufgrund des Unterschieds in der internen Netzwerkstruktur ist die Feinabstimmung ein wenig. Es sieht so aus, als müsste es geändert werden.

Lassen Sie uns vorerst die Struktur des Inhalts von Distil BERT überprüfen.

print(distil_model)

Es ist lang, also halte es geschlossen.

DistilBERT-Modellstruktur
DistilBertModel(
  (embeddings): Embeddings(
    (word_embeddings): Embedding(32000, 768, padding_idx=0)
    (position_embeddings): Embedding(512, 768)
    (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)
    (dropout): Dropout(p=0.1, inplace=False)
  )
  (transformer): Transformer(
    (layer): ModuleList(
      (0): TransformerBlock(
        (attention): MultiHeadSelfAttention(
          (dropout): Dropout(p=0.1, inplace=False)
          (q_lin): Linear(in_features=768, out_features=768, bias=True)
          (k_lin): Linear(in_features=768, out_features=768, bias=True)
          (v_lin): Linear(in_features=768, out_features=768, bias=True)
          (out_lin): Linear(in_features=768, out_features=768, bias=True)
        )
        (sa_layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)
        (ffn): FFN(
          (dropout): Dropout(p=0.1, inplace=False)
          (lin1): Linear(in_features=768, out_features=3072, bias=True)
          (lin2): Linear(in_features=3072, out_features=768, bias=True)
        )
        (output_layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)
      )
      (1): TransformerBlock(
        (attention): MultiHeadSelfAttention(
          (dropout): Dropout(p=0.1, inplace=False)
          (q_lin): Linear(in_features=768, out_features=768, bias=True)
          (k_lin): Linear(in_features=768, out_features=768, bias=True)
          (v_lin): Linear(in_features=768, out_features=768, bias=True)
          (out_lin): Linear(in_features=768, out_features=768, bias=True)
        )
        (sa_layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)
        (ffn): FFN(
          (dropout): Dropout(p=0.1, inplace=False)
          (lin1): Linear(in_features=768, out_features=3072, bias=True)
          (lin2): Linear(in_features=3072, out_features=768, bias=True)
        )
        (output_layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)
      )
      (2): TransformerBlock(
        (attention): MultiHeadSelfAttention(
          (dropout): Dropout(p=0.1, inplace=False)
          (q_lin): Linear(in_features=768, out_features=768, bias=True)
          (k_lin): Linear(in_features=768, out_features=768, bias=True)
          (v_lin): Linear(in_features=768, out_features=768, bias=True)
          (out_lin): Linear(in_features=768, out_features=768, bias=True)
        )
        (sa_layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)
        (ffn): FFN(
          (dropout): Dropout(p=0.1, inplace=False)
          (lin1): Linear(in_features=768, out_features=3072, bias=True)
          (lin2): Linear(in_features=3072, out_features=768, bias=True)
        )
        (output_layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)
      )
      (3): TransformerBlock(
        (attention): MultiHeadSelfAttention(
          (dropout): Dropout(p=0.1, inplace=False)
          (q_lin): Linear(in_features=768, out_features=768, bias=True)
          (k_lin): Linear(in_features=768, out_features=768, bias=True)
          (v_lin): Linear(in_features=768, out_features=768, bias=True)
          (out_lin): Linear(in_features=768, out_features=768, bias=True)
        )
        (sa_layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)
        (ffn): FFN(
          (dropout): Dropout(p=0.1, inplace=False)
          (lin1): Linear(in_features=768, out_features=3072, bias=True)
          (lin2): Linear(in_features=3072, out_features=768, bias=True)
        )
        (output_layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)
      )
      (4): TransformerBlock(
        (attention): MultiHeadSelfAttention(
          (dropout): Dropout(p=0.1, inplace=False)
          (q_lin): Linear(in_features=768, out_features=768, bias=True)
          (k_lin): Linear(in_features=768, out_features=768, bias=True)
          (v_lin): Linear(in_features=768, out_features=768, bias=True)
          (out_lin): Linear(in_features=768, out_features=768, bias=True)
        )
        (sa_layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)
        (ffn): FFN(
          (dropout): Dropout(p=0.1, inplace=False)
          (lin1): Linear(in_features=768, out_features=3072, bias=True)
          (lin2): Linear(in_features=3072, out_features=768, bias=True)
        )
        (output_layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)
      )
      (5): TransformerBlock(
        (attention): MultiHeadSelfAttention(
          (dropout): Dropout(p=0.1, inplace=False)
          (q_lin): Linear(in_features=768, out_features=768, bias=True)
          (k_lin): Linear(in_features=768, out_features=768, bias=True)
          (v_lin): Linear(in_features=768, out_features=768, bias=True)
          (out_lin): Linear(in_features=768, out_features=768, bias=True)
        )
        (sa_layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)
        (ffn): FFN(
          (dropout): Dropout(p=0.1, inplace=False)
          (lin1): Linear(in_features=768, out_features=3072, bias=True)
          (lin2): Linear(in_features=3072, out_features=768, bias=True)
        )
        (output_layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)
      )
    )
  )
)

Der Unterschied zur BERT-Basis besteht darin, dass es in der BERT-Basis 12 Transformatorblöcke gibt, in Distil BERT jedoch nur 6. Sie können auch sehen, dass sich die Benennung der Inhaltsschicht ein wenig von der BERT-Basis unterscheidet.

Schreiben Sie daher bei der Feinabstimmung wie folgt. Ein Beispiel für eine Klassifizierungsmodelldeklaration wird ebenfalls beschrieben.

Diesmal gibt es keinen besonderen Effekt, aber lassen Sie uns auch die DistilBERT-Referenz überprüfen. Die Modellrendite ist ebenfalls etwas anders.

(Wie beim vorherigen Artikel wird die Titelklassifizierung des Livedoor News Corpus angenommen.)

Modelldeklaration

import torch
from torch import nn
import torch.nn.functional as F
from transformers import *

class DistilBertClassifier(nn.Module):
  def __init__(self):
    super(DistilBertClassifier, self).__init__()
    # BERT-Dies ist der einzige Ort, der sich von der Basis unterscheidet.
    self.distil_bert = AutoModel.from_pretrained("bandainamco-mirai/distilbert-base-japanese")
    #Die Anzahl der Dimensionen der verborgenen Schicht von DistilBERT beträgt 768,9 Livedoor News Kategorien
    self.linear = nn.Linear(768, 9)
    #Verarbeitung der Gewichtsinitialisierung
    nn.init.normal_(self.linear.weight, std=0.02)
    nn.init.normal_(self.linear.bias, 0)

  def forward(self, input_ids):
    vec, _ = self.distil_bert(input_ids)
    #Holen Sie sich nur den Vektor der ersten Token-Cls
    vec = vec[:,0,:]
    vec = vec.view(-1, 768)
    #Konvertieren Sie die Abmessungen für die Klassifizierung in vollständig verbundene Ebenen
    out = self.linear(vec)
    return F.log_softmax(out)

#Instanz des Klassifizierungsmodells
distil_classifier = DistilBertClassifier()

Feintuning

#Zunächst einmal AUS
for param in distil_classifier.parameters():
    param.requires_grad = False

#Aktualisieren Sie nur die letzte Ebene von DistilBERT ON
# BERT-Basis ist.encoder.layer[-1]Es war,
#Im Fall von DistilBERT, wie die obige Struktur bestätigt, wie folgt.transfomer.layer[-1]Es wird sein.
for param in distil_classifier.distil_bert.transformer.layer[-1].parameters():
    param.requires_grad = True

#Die Klassenklassifizierung ist ebenfalls aktiviert
for param in distil_classifier.linear.parameters():
    param.requires_grad = True

import torch.optim as optim

#Die Lernrate ist für den vorgelernten Teil klein und für die letzte vollständig verbundene Schicht groß.
#Vergessen Sie nicht, dies für Distil BERT zu ändern
optimizer = optim.Adam([
    {'params': distil_classifier.distil_bert.transformer.layer[-1].parameters(), 'lr': 5e-5},
    {'params': distil_classifier.linear.parameters(), 'lr': 1e-4}
])

Vergleich von BERT-Base und Distil BERT

Ähnlich wie bei Last time wird die Titelklassifizierung des Livedoor-Nachrichtenkorpus übernommen.

BERT-base

Modelldefinition & Feinabstimmung

class BertClassifier(nn.Module):
  def __init__(self):
    super(BertClassifier, self).__init__()
    self.bert = BertModel.from_pretrained('cl-tohoku/bert-base-japanese-whole-word-masking')
    #Die versteckte Ebene von BERT hat 768 Dimensionen,9 Livedoor News Kategorien
    self.linear = nn.Linear(768, 9)
    #Verarbeitung der Gewichtsinitialisierung
    nn.init.normal_(self.linear.weight, std=0.02)
    nn.init.normal_(self.linear.bias, 0)

  def forward(self, input_ids):
    # last_Empfange nur versteckt
    vec, _ = self.bert(input_ids)
    #Holen Sie sich nur den Vektor der ersten Token-Cls
    vec = vec[:,0,:]
    vec = vec.view(-1, 768)
    #Konvertieren Sie die Abmessungen für die Klassifizierung in vollständig verbundene Ebenen
    out = self.linear(vec)
    return F.log_softmax(out)

#Instanzdeklaration des Klassifizierungsmodells
bert_classifier = BertClassifier()

#Feinabstimmung der Einstellungen
#Zunächst einmal AUS
for param in bert_classifier.parameters():
    param.requires_grad = False

#Aktualisieren Sie nur die letzte Ebene von BERT ON
for param in bert_classifier.bert.encoder.layer[-1].parameters():
    param.requires_grad = True

#Die Klassenklassifizierung ist ebenfalls aktiviert
for param in bert_classifier.linear.parameters():
    param.requires_grad = True

import torch.optim as optim

#Die Lernrate ist für den vorgelernten Teil klein und für die letzte vollständig verbundene Schicht groß.
optimizer = optim.Adam([
    {'params': bert_classifier.bert.encoder.layer[-1].parameters(), 'lr': 5e-5},
    {'params': bert_classifier.linear.parameters(), 'lr': 1e-4}
])

#Einstellungen der Verlustfunktion
loss_function = nn.NLLLoss()

Lernen & Denken

#Messen Sie die Lernzeit.
import time

start = time.time()
#GPU-Einstellungen
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
#Netzwerk an GPU senden
bert_classifier.to(device)
losses = []

#Die Anzahl der Epochen beträgt 10
for epoch in range(10):
  all_loss = 0
  for idx, batch in enumerate(train_iter):
    batch_loss = 0
    bert_classifier.zero_grad()
    input_ids = batch.Text[0].to(device)
    label_ids = batch.Label.to(device)
    out = bert_classifier(input_ids)
    batch_loss = loss_function(out, label_ids)
    batch_loss.backward()
    optimizer.step()
    all_loss += batch_loss.item()
  print("epoch", epoch, "\t" , "loss", all_loss)

end = time.time()

print ("time : ", end - start)
#epoch 0 	 loss 251.19750046730042
#epoch 1 	 loss 110.7038831859827
#epoch 2 	 loss 82.88570280373096
#epoch 3 	 loss 67.0771074667573
#epoch 4 	 loss 56.24497305601835
#epoch 5 	 loss 42.61423560976982
#epoch 6 	 loss 35.98485875874758
#epoch 7 	 loss 25.728398952633142
#epoch 8 	 loss 20.40780107676983
#epoch 9 	 loss 16.567239843308926
#time :  101.97362518310547

#Inferenz
answer = []
prediction = []
with torch.no_grad():
    for batch in test_iter:

        text_tensor = batch.Text[0].to(device)
        label_tensor = batch.Label.to(device)

        score = bert_classifier(text_tensor)
        _, pred = torch.max(score, 1)

        prediction += list(pred.cpu().numpy())
        answer += list(label_tensor.cpu().numpy())
print(classification_report(prediction, answer, target_names=categories))
#                precision    recall  f1-score   support

# kaden-channel       0.94      0.92      0.93       172
#dokujo-tsushin       0.75      0.86      0.80       156
#        peachy       0.81      0.68      0.74       211
#   movie-enter       0.78      0.81      0.80       171
#          smax       0.98      0.91      0.94       176
#livedoor-homme       0.68      0.83      0.75        83
#  it-life-hack       0.79      0.94      0.86       150
#    topic-news       0.81      0.76      0.78       172
#  sports-watch       0.89      0.82      0.85       185

#      accuracy                           0.83      1476
#     macro avg       0.83      0.84      0.83      1476
#  weighted avg       0.84      0.83      0.83      1476

Die Lernzeit von 10 Epochen betrug etwa 102 Sekunden und die Genauigkeit betrug 0,83 (F-Punktzahl).

DistilBERT

Lernen & Denken

import time

#GPU-Einstellungen
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
#Netzwerk an GPU senden
distil_classifier.to(device)
losses = []

start = time.time()
#Die Anzahl der Epochen beträgt 10
for epoch in range(10):
  all_loss = 0
  for idx, batch in enumerate(train_iter):
    batch_loss = 0
    distil_classifier.zero_grad()
    input_ids = batch.Text[0].to(device)
    label_ids = batch.Label.to(device)
    out = distil_classifier(input_ids)
    batch_loss = loss_function(out, label_ids)
    batch_loss.backward()
    optimizer.step()
    all_loss += batch_loss.item()
  print("epoch", epoch, "\t" , "loss", all_loss)

end = time.time()
print ("time : ", end - start)
#/usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:26: UserWarning: Implicit dimension choice for log_softmax has been deprecated. Change the call to include dim=X as an argument.
#epoch 0 	 loss 450.1027842760086
#epoch 1 	 loss 317.39041769504547
#epoch 2 	 loss 211.34138756990433
#epoch 3 	 loss 144.4813650548458
#epoch 4 	 loss 106.24609130620956
#epoch 5 	 loss 83.87273170053959
#epoch 6 	 loss 68.9661111086607
#epoch 7 	 loss 59.31868125498295
#epoch 8 	 loss 49.874382212758064
#epoch 9 	 loss 41.56027300283313
#time :  60.22182369232178


from sklearn.metrics import classification_report

answer = []
prediction = []
with torch.no_grad():
    for batch in test_iter:

        text_tensor = batch.Text[0].to(device)
        label_tensor = batch.Label.to(device)

        score = distil_classifier(text_tensor)
        _, pred = torch.max(score, 1)

        prediction += list(pred.cpu().numpy())
        answer += list(label_tensor.cpu().numpy())
print(classification_report(prediction, answer, target_names=categories))

#/usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:26: UserWarning: Implicit dimension choice for log_softmax has been deprecated. Change the call to include dim=X as an argument.
#                precision    recall  f1-score   support

# kaden-channel       0.93      0.96      0.95       163
#dokujo-tsushin       0.88      0.88      0.88       178
#        peachy       0.86      0.75      0.80       202
#   movie-enter       0.86      0.84      0.85       183
#          smax       0.96      0.95      0.95       165
#livedoor-homme       0.67      0.71      0.69        96
#  it-life-hack       0.91      0.91      0.91       178
#    topic-news       0.80      0.86      0.83       148
#  sports-watch       0.88      0.91      0.89       163

#      accuracy                           0.87      1476
#     macro avg       0.86      0.86      0.86      1476
#  weighted avg       0.87      0.87      0.87      1476

――Die Lernzeit von 10 Epochen betrug etwa 60 Sekunden und die Genauigkeit betrug 0,87 (F-Punktzahl). ――Es ist schön, dass die Lernzeit schneller ist, aber die Genauigkeit hat sich verbessert. ―― Ursprünglich sollte es etwas weniger genau sein als die BERT-Basis, aber es scheint, dass es höher sein könnte. »Irgendwie ist die Aufgabe, die Titel des Live-News-Korpus zu klassifizieren, die ich immer als Experiment versuche, möglicherweise nicht sehr gut ...

Versuchen Sie, die Genauigkeit der BERT-Basis zu verbessern

Von hier aus werde ich eine Technik einführen, um die Genauigkeit bei der Klassifizierung von Sätzen in japanischem BERT zu verbessern, nicht im Vergleich zu Distil BERT.

(Ursprünglich sollten Sie zunächst gründlich über die Vorverarbeitung gemäß der Aufgabe nachdenken, aber es scheint sich um eine Technik zur Verbesserung der Präzision zu handeln, die nicht stark von der Aufgabe abhängt. Deshalb werde ich sie hier vorstellen.)

Obwohl es sich um eine Technik handelt, wird sie auch in 5.3 Feature-based Approach mit BERT von BERT's Paper und dem NLP-Wettbewerb vorgestellt, der zuvor bei kaggle Jigsaw Unintended Bias in der Toxizitätsklassifizierung scheint die erste Methode zu sein.

Weitere Informationen zur Technik finden Sie im folgenden Artikel.

Der Punkt ist, dass es von den 12 Encoder-Schichten der BERT-Basis besser ist, die Vektoren der CLS-Token der letzten 4 Schichten zu kombinieren, als nur die Vektoren der CLS-Token der letzten Schicht zu verwenden. Es scheint. (Ich weiß nicht warum ...)

Die Idee ist so einfach, dass ich sie in dieser Aufgabe zur Klassifizierung von Titeln des Livedoor News Corpus ausprobieren werde.

Implementierung

Modelldeklaration

class BertClassifierRevised(nn.Module):
  def __init__(self):
    super(BertClassifierRevised, self).__init__()
    self.bert = BertModel.from_pretrained('cl-tohoku/bert-base-japanese-whole-word-masking')
    #Die Anzahl der Dimensionen der verborgenen Schicht von BERT beträgt 768, aber da es sich um die Kombination der Vektoren der letzten vier Schichten handelt, wird sie auf 768 x 4 Dimensionen eingestellt.
    self.linear = nn.Linear(768*4, 9)
    #Verarbeitung der Gewichtsinitialisierung
    nn.init.normal_(self.linear.weight, std=0.02)
    nn.init.normal_(self.linear.bias, 0)
  
  #Bereiten Sie eine Funktion vor, um den Vektor des cls-Tokens abzurufen
  def _get_cls_vec(self, vec):
    return vec[:,0,:].view(-1, 768)

  def forward(self, input_ids):
    #1. Rückgabewert zuletzt_hidden_Im Zustand kann also nur die letzte Schicht erhalten werden
    # output_hidden_states=Deklarieren Sie True, um alle verborgenen Ebenenvektoren zu erhalten.
    #Dritter Rückgabewert(Zustand aller versteckten Schichten)Bekommen.
    _, _,  hidden_states = self.bert(input_ids, output_hidden_states=True)

    #Holen Sie sich den cls-Token-Vektor aus jeder der letzten 4 ausgeblendeten Ebenen
    vec1 = self._get_cls_vec(hidden_states[-1])
    vec2 = self._get_cls_vec(hidden_states[-2])
    vec3 = self._get_cls_vec(hidden_states[-3])
    vec4 = self._get_cls_vec(hidden_states[-4])

    #Kombinieren Sie vier cls-Token zu einem Vektor.
    vec = torch.cat([vec1, vec2, vec3, vec4], dim=1)

    #Konvertieren Sie die Abmessungen für die Klassifizierung in vollständig verbundene Ebenen
    out = self.linear(vec)
    return F.log_softmax(out)

#Instanzdeklaration
bert_classifier_revised = BertClassifierRevised()

Feintuning

#Zunächst einmal AUS
for param in bert_classifier_revised.parameters():
    param.requires_grad = False

#Schalten Sie die letzten 4 Schichten von BERT ein
for param in bert_classifier_revised.bert.encoder.layer[-1].parameters():
    param.requires_grad = True

for param in bert_classifier_revised.bert.encoder.layer[-2].parameters():
    param.requires_grad = True

for param in bert_classifier_revised.bert.encoder.layer[-3].parameters():
    param.requires_grad = True

for param in bert_classifier_revised.bert.encoder.layer[-4].parameters():
    param.requires_grad = True

#Die Klassenklassifizierung ist ebenfalls aktiviert
for param in bert_classifier_revised.linear.parameters():
    param.requires_grad = True

import torch.optim as optim

#Die Lernrate ist für den vorgelernten Teil klein und für die letzte vollständig verbundene Schicht groß.
optimizer = optim.Adam([
    {'params': bert_classifier_revised.bert.encoder.layer[-1].parameters(), 'lr': 5e-5},
    {'params': bert_classifier_revised.bert.encoder.layer[-2].parameters(), 'lr': 5e-5},
    {'params': bert_classifier_revised.bert.encoder.layer[-3].parameters(), 'lr': 5e-5},
    {'params': bert_classifier_revised.bert.encoder.layer[-4].parameters(), 'lr': 5e-5},
    {'params': bert_classifier_revised.linear.parameters(), 'lr': 1e-4}
])

#Einstellungen der Verlustfunktion
loss_function = nn.NLLLoss()

Lernen & Denken


import time

start = time.time()
#GPU-Einstellungen
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
#Netzwerk an GPU senden
bert_classifier_revised.to(device)
losses = []

#Die Anzahl der Epochen beträgt 5
for epoch in range(10):
  all_loss = 0
  for idx, batch in enumerate(train_iter):
    batch_loss = 0
    bert_classifier_revised.zero_grad()
    input_ids = batch.Text[0].to(device)
    label_ids = batch.Label.to(device)
    out = bert_classifier_revised(input_ids)
    batch_loss = loss_function(out, label_ids)
    batch_loss.backward()
    optimizer.step()
    all_loss += batch_loss.item()
  print("epoch", epoch, "\t" , "loss", all_loss)

end = time.time()

print ("time : ", end - start)
#epoch 0 	 loss 196.0047192275524
#epoch 1 	 loss 75.8067753687501
#epoch 2 	 loss 42.30751228891313
#epoch 3 	 loss 16.470114511903375
#epoch 4 	 loss 7.427484432584606
#epoch 5 	 loss 2.9392087209271267
#epoch 6 	 loss 1.5984382012393326
#epoch 7 	 loss 1.7370687873335555
#epoch 8 	 loss 0.9278695838729618
#epoch 9 	 loss 1.499190401067608
#time :  149.01919651031494

#Inferenz
answer = []
prediction = []
with torch.no_grad():
    for batch in test_iter:

        text_tensor = batch.Text[0].to(device)
        label_tensor = batch.Label.to(device)

        score = bert_classifier_revised(text_tensor)
        _, pred = torch.max(score, 1)

        prediction += list(pred.cpu().numpy())
        answer += list(label_tensor.cpu().numpy())
print(classification_report(prediction, answer, target_names=categories))
#                precision    recall  f1-score   support

# kaden-channel       0.80      0.99      0.89       137
#dokujo-tsushin       0.89      0.86      0.88       183
#        peachy       0.78      0.82      0.80       168
#   movie-enter       0.87      0.88      0.87       176
#          smax       0.95      0.93      0.94       168
#livedoor-homme       0.72      0.83      0.77        88
#  it-life-hack       0.95      0.79      0.86       215
#    topic-news       0.83      0.84      0.83       159
#  sports-watch       0.92      0.86      0.89       182

#      accuracy                           0.86      1476
#     macro avg       0.86      0.87      0.86      1476
#  weighted avg       0.87      0.86      0.86      1476

abschließend

Ende

Recommended Posts

Ich habe versucht, die Genauigkeit der japanischen BERT- und der japanischen Distil-BERT-Satzklassifizierung mit PyTorch & Einführung der BERT-Technik zur Verbesserung der Genauigkeit zu vergleichen
Ich habe versucht, Satzklassifizierung und Aufmerksamkeitsvisualisierung durch das japanische BERT mit PyTorch zu implementieren
Ich habe versucht, die Verarbeitungsgeschwindigkeit mit dplyr von R und pandas von Python zu vergleichen
Ich habe versucht, die Satzklassifizierung durch Self Attention mit PyTorch zu implementieren
Ich habe versucht, die Negativität von Nono Morikubo zu analysieren. [Vergleiche mit Posipa]
[PyTorch] Einführung in die Klassifizierung japanischer Dokumente mit BERT
[Einführung in AWS] Ich habe versucht, eine Konversations-App zu portieren und mit text2speech @ AWS playing zu spielen
Ich habe versucht, DCGAN mit PyTorch zu implementieren und zu lernen
[Einführung in Pytorch] Ich habe versucht, Cifar10 mit VGG16 ♬ zu kategorisieren
Ich habe versucht, das Artikel-Update des Livedoor-Blogs mit Python und Selen zu automatisieren.
Ich habe versucht, die Entropie des Bildes mit Python zu finden
Ich habe versucht, mit TensorFlow den Durchschnitt mehrerer Spalten zu ermitteln
Ich habe versucht, zum Zeitpunkt der Bereitstellung mit Fabric und ChatWork Api automatisch in ChatWork zu posten
Ich habe versucht, die Genauigkeit von Modellen für maschinelles Lernen mit Kaggle als Thema zu vergleichen.
Ich habe versucht, die Yin- und Yang-Klassifikation hololiver Mitglieder durch maschinelles Lernen zu überprüfen
Ich habe versucht, die Bewässerung des Pflanzgefäßes mit Raspberry Pi zu automatisieren
[Einführung in Python] Ich habe die Namenskonventionen von C # und Python verglichen.
[Einführung in StyleGAN] Ich habe mit "The Life of a Man" ♬ gespielt
Ich habe versucht, die Größe des logischen Volumes mit LVM zu erweitern
Von der Einführung von JUMAN ++ bis zur morphologischen Analyse von Japanisch mit Python
Ich habe versucht, die Effizienz der täglichen Arbeit mit Python zu verbessern
Ich habe versucht, Othello AI mit Tensorflow zu machen, ohne die Theorie des maschinellen Lernens zu verstehen ~ Einführung ~
Ich habe versucht, die Altersgruppe und die Ratenverteilung von Atcoder zu visualisieren
10 Methoden zur Verbesserung der Genauigkeit von BERT
Ich versuchte, Trauer und Freude über das Problem der stabilen Ehe auszudrücken.
Ich habe versucht, den Unterschied zwischen Config vor und nach der Arbeit mit pyATS / Genie selbst erstelltem Skript zu berücksichtigen
Ich habe versucht, die Genauigkeit meines eigenen neuronalen Netzwerks zu verbessern
[PyTorch] Einführung in die Dokumentklassifizierung mit BERT
Ich habe versucht, den Authentifizierungscode der Qiita-API mit Python abzurufen.
Ich habe versucht, die Bewegungen von Wiire-Playern automatisch mit Software zu extrahieren
[Einführung in Pytorch] Ich habe mit sinGAN ♬ gespielt
Ich habe versucht, den Winkel von Sin und Cos mit Chainer zu lernen
Ich habe versucht, die Phase der Geschichte mit COTOHA zu extrahieren und zu veranschaulichen
Ich habe versucht, die Beschleunigung von Python durch Cython zu verifizieren und zu analysieren
Ich habe versucht, CVAE mit PyTorch zu implementieren
Ich habe versucht, die statistischen Daten der neuen Corona mit Python abzurufen und zu analysieren: Daten der Johns Hopkins University
Ich habe versucht, die Standardrolle neuer Mitarbeiter mit Python zu optimieren
Ich habe versucht, den Text des Romans "Wetterkind" mit Word Cloud zu visualisieren
Ich habe versucht, die Filminformationen der TMDb-API mit Python abzurufen
Ich habe versucht, das Verhalten des neuen Koronavirus mit dem SEIR-Modell vorherzusagen.
Ich habe versucht, die Netzwerkbandbreite und -verzögerung mit dem Befehl tc zu steuern
Ich habe mit Pytorch versucht, Bilder von "Moon and Suppon" zu erkennen (mit torchvision.datasets.ImageFolder, das from_from_directry of keras entspricht).
Ich habe versucht, das Update von "Hameln" mit "Beautiful Soup" und "IFTTT" zu benachrichtigen.
Ich habe versucht, die Tweets von JAWS DAYS 2017 mit Python + ELK einfach zu visualisieren
Ich habe das TensorFlow-Tutorial mit Kommentaren ausgeführt (Textklassifizierung von Filmkritiken).
Die Geschichte von soracom_exporter (Ich habe versucht, SORACOM Air mit Prometheus zu überwachen)
Ich habe versucht, ein Modell mit dem Beispiel von Amazon SageMaker Autopilot zu erstellen
Ich habe versucht, die Literatur des neuen Corona-Virus mit Python automatisch an LINE zu senden
Ich habe versucht, das Lesen von Dataset mit PyTorch zu implementieren
Ich habe versucht, die Daten mit Zwietracht zu speichern
Ich habe versucht, die Trapezform des Bildes zu korrigieren
[Einführung in PID] Ich habe versucht, ♬ zu steuern und zu spielen
Ich habe versucht, die Texte von Hinatazaka 46 zu vektorisieren!
Einführung in Deep Learning zum ersten Mal (Chainer) Japanische Zeichenerkennung Kapitel 4 [Verbesserung der Erkennungsgenauigkeit durch Erweiterung der Daten]
Ich habe versucht, mit dem Seq2Seq-Modell von TensorFlow so etwas wie einen Chatbot zu erstellen
Ich habe versucht, das Update von "Werde ein Romanautor" mit "IFTTT" und "Werde ein Romanautor API" zu benachrichtigen.