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.
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.
[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.
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.)
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()
#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}
])
Ähnlich wie bei Last time wird die Titelklassifizierung des Livedoor-Nachrichtenkorpus übernommen.
BERT-base
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()
#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
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 ...
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.
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()
#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()
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
Ende
Recommended Posts