BERT met à jour SOTA pour diverses tâches de traitement du langage naturel, mais celle publiée par la famille principale de Google sur Github est basée sur Tensorflow Il est mis en œuvre. Les personnes qui utilisent PyTorch veulent utiliser la version PyTorch, mais comme nous n'avons pas fait la version PyTorch, utilisez celle faite par HuggingFace, mais nous développons Demandez-leur plus d'informations car ils ne sont pas impliqués! Et QA.
BERT fabriqué par HuggingFace, mais il n'y avait pas de modèles pré-entraînés japonais avant décembre 2019. Par conséquent, je pouvais facilement l'essayer en anglais, mais en japonais, je devais préparer moi-même des modèles pré-entraînés. Cependant, en décembre 2019, des modèles pré-entraînés japonais ont finalement été ajoutés. https://huggingface.co/transformers/pretrained_models.html
Quatre modèles peuvent être utilisés dans Créé par le laboratoire Inui de l'Université de Tohoku. Sauf circonstances particulières, il est préférable d'utiliser le deuxième "bert-base-japanese-whole-word-masking". Dans la version normale et la version Whole Word Masking, la version Whole Word Masking semble avoir tendance à avoir une précision légèrement supérieure des tâches affinées [^ 1].
Cela permet d'essayer facilement la version PyTorch de BERT en japonais.
Le mécanisme de BERT a déjà été introduit dans divers blogs et livres, je vais donc omettre une explication détaillée. Tout simplement
--Créer des modèles pré-entraînés à partir d'un grand nombre de corpus non supervisés
Ce sera le flux du traitement. La création de modèles pré-entraînés nécessite beaucoup de ressources informatiques et de temps, mais l'un des points forts de BERT est qu'il peut améliorer la précision des tâches.
Tout d'abord, vérifiez l'exactitude des modèles pré-entraînés japonais pré-entraînés. Cette fois, nous vérifierons l'exactitude du modèle de langage masqué. Une explication simple du modèle de langage masqué consiste à masquer un mot dans une phrase et à prédire le mot masqué.
En utilisant BertJapaneseTokenizer et BertForMaskedLM, vous pouvez écrire: Prédisez le mot en masquant «football» dans la phrase «regarder un match de football à la télévision».
import torch
from transformers import BertJapaneseTokenizer, BertForMaskedLM
# Load pre-trained tokenizer
tokenizer = BertJapaneseTokenizer.from_pretrained('bert-base-japanese-whole-word-masking')
# Tokenize input
text = 'Regardez un match de football à la télévision.'
tokenized_text = tokenizer.tokenize(text)
# ['poste de télévision', 'alors', 'Football', 'de', 'rencontre', 'À', 'à voir', '。']
# Mask a token that we will try to predict back with `BertForMaskedLM`
masked_index = 2
tokenized_text[masked_index] = '[MASK]'
# ['poste de télévision', 'alors', '[MASK]', 'de', 'rencontre', 'À', 'à voir', '。']
# Convert token to vocabulary indices
indexed_tokens = tokenizer.convert_tokens_to_ids(tokenized_text)
# [571, 12, 4, 5, 608, 11, 2867, 8]
# Convert inputs to PyTorch tensors
tokens_tensor = torch.tensor([indexed_tokens])
# tensor([[ 571, 12, 4, 5, 608, 11, 2867, 8]])
# Load pre-trained model
model = BertForMaskedLM.from_pretrained('bert-base-japanese-whole-word-masking')
model.eval()
# Predict
with torch.no_grad():
outputs = model(tokens_tensor)
predictions = outputs[0][0, masked_index].topk(5) #Extraire les 5 meilleurs résultats de prédiction
# Show results
for i, index_t in enumerate(predictions.indices):
index = index_t.item()
token = tokenizer.convert_ids_to_tokens([index])[0]
print(i, token)
Le résultat de l'exécution du programme ci-dessus est le suivant. "Soccer" est apparu à la 3e place, et d'autres mots sont probablement corrects en japonais. On pense que la raison pour laquelle les noms des équipes de "cricket" et des ligues majeures, qui ne sont pas si familiers au Japon, apparaissent est parce qu'ils ont appris à l'avance des données de Wikipedia.
0 cricket
1 tigres
2 football
3 mets
4 petits
D'après ce qui précède, il a été confirmé que les modèles pré-entraînés étaient correctement pré-formés. Ensuite, affinez et résolvez la tâche en fonction de ces modèles pré-entraînés.
Fine tuning with BERT
Hugging Face GitHub a quelques exemples de réglages fins pour résoudre des tâches. Cependant, il s'agit des ensembles de données anglais et aucun ne concerne les ensembles de données japonais [^ 2].
Par conséquent, nous modifierons le code source existant afin qu'il fonctionne avec les données japonaises d'origine. En supposant la classification de texte, qui est une tâche de base dans le traitement du langage naturel, le code source utilisé pour la classification de texte GLUE est ciblé. Et
Modifiez les deux programmes dans.
Mise en garde
Notez que ce n'est pas un fichier téléchargé par git clone
etc., mais vous devez changer le fichier dans le répertoire d'installation.
Par exemple, si vous utilisez venv, le répertoire d'installation sera [répertoire venv] / lib / python3.7 / site-packages / transformers
.
à
glue_tasks_num_labels,
glue_processors,
glue_output_modes, puis ajoutez la classe ʻOriginalProcessor
comme suit:glue_tasks_num_labels = {
"cola": 2,
"mnli": 3,
"mrpc": 2,
"sst-2": 2,
"sts-b": 1,
"qqp": 2,
"qnli": 2,
"rte": 2,
"wnli": 2,
"original": 2, #ajouter à
}
glue_processors = {
"cola": ColaProcessor,
"mnli": MnliProcessor,
"mnli-mm": MnliMismatchedProcessor,
"mrpc": MrpcProcessor,
"sst-2": Sst2Processor,
"sts-b": StsbProcessor,
"qqp": QqpProcessor,
"qnli": QnliProcessor,
"rte": RteProcessor,
"wnli": WnliProcessor,
"original": OriginalProcessor, #ajouter à
}
glue_output_modes = {
"cola": "classification",
"mnli": "classification",
"mnli-mm": "classification",
"mrpc": "classification",
"sst-2": "classification",
"sts-b": "regression",
"qqp": "classification",
"qnli": "classification",
"rte": "classification",
"wnli": "classification",
"original": "classification", #ajouter à
}
class OriginalProcessor(DataProcessor):
"""Processor for the original data set."""
def get_example_from_tensor_dict(self, tensor_dict):
"""See base class."""
return InputExample(
tensor_dict["idx"].numpy(),
tensor_dict["sentence"].numpy().decode("utf-8"),
None,
str(tensor_dict["label"].numpy()),
)
def get_train_examples(self, data_dir):
"""See base class."""
return self._create_examples(self._read_tsv(os.path.join(data_dir, "train.tsv")), "train")
def get_dev_examples(self, data_dir):
"""See base class."""
return self._create_examples(self._read_tsv(os.path.join(data_dir, "dev.tsv")), "dev")
def get_labels(self):
"""See base class."""
return ["0", "1"]
def _create_examples(self, lines, set_type):
"""Creates examples for the training and dev sets."""
examples = []
for (i, line) in enumerate(lines):
#Décommenter si le fichier TSV a une ligne d'en-tête
# if i == 0:
# continue
guid = "%s-%s" % (set_type, i)
text_a = line[0]
label = line[1]
examples.append(InputExample(guid=guid, text_a=text_a, text_b=None, label=label))
return examples
Données de formation et données de vérification
Je suppose un fichier TSV composé de deux colonnes.
train.tsv
C'était intéressant 0
C'était amusant 0
Était ennuyeux 1
J'étais triste 1
dev.tsv
Apprécié 0
C'était douloureux 1
Le programme ci-dessus suppose une classification binaire, mais en cas de classification à valeurs multiples, veuillez modifier le nombre et la valeur des étiquettes comme il convient.
nom_tâche ==" original "
dans l'expression conditionnelle comme suit: def glue_compute_metrics(task_name, preds, labels):
assert len(preds) == len(labels)
if task_name == "cola":
return {"mcc": matthews_corrcoef(labels, preds)}
elif task_name == "sst-2":
return {"acc": simple_accuracy(preds, labels)}
elif task_name == "mrpc":
return acc_and_f1(preds, labels)
elif task_name == "sts-b":
return pearson_and_spearman(preds, labels)
elif task_name == "qqp":
return acc_and_f1(preds, labels)
elif task_name == "mnli":
return {"acc": simple_accuracy(preds, labels)}
elif task_name == "mnli-mm":
return {"acc": simple_accuracy(preds, labels)}
elif task_name == "qnli":
return {"acc": simple_accuracy(preds, labels)}
elif task_name == "rte":
return {"acc": simple_accuracy(preds, labels)}
elif task_name == "wnli":
return {"acc": simple_accuracy(preds, labels)}
#ajouter à
elif task_name == "original":
return {"acc": simple_accuracy(preds, labels)}
else:
raise KeyError(task_name)
Maintenant que les données originales en japonais fonctionnent, tout ce que vous avez à faire est de peaufiner et de résoudre le problème de classification.
Il exécute uniquement la commande suivante: Placez les données d'entraînement et les fichiers de données de vérification sous data / original /
.
$ python examples/run_glue.py \
--data_dir=data/original/ \
--model_type=bert \
--model_name_or_path=bert-base-japanese-whole-word-masking \
--task_name=original \
--do_train \
--do_eval \
--output_dir=output/original
Si vous exécutez la commande ci-dessus et terminez sans aucun problème, le journal suivant sera généré. La valeur de acc est «1.0», et vous pouvez voir que les deux données de vérification peuvent être classées correctement.
01/18/2020 17:08:39 - INFO - __main__ - Saving features into cached file data/original/cached_dev_bert-base-japanese-whole-word-masking_128_original
01/18/2020 17:08:39 - INFO - __main__ - ***** Running evaluation *****
01/18/2020 17:08:39 - INFO - __main__ - Num examples = 2
01/18/2020 17:08:39 - INFO - __main__ - Batch size = 8
Evaluating: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 2.59it/s]
01/18/2020 17:08:40 - INFO - __main__ - ***** Eval results *****
01/18/2020 17:08:40 - INFO - __main__ - acc = 1.0
Et vous pouvez voir que le fichier modèle est créé sous ʻoutput / original / `.
$ find output/original
output/original
output/original/added_tokens.json
output/original/tokenizer_config.json
output/original/special_tokens_map.json
output/original/config.json
output/original/training_args.bin
output/original/vocab.txt
output/original/pytorch_model.bin
output/original/eval_results.txt
J'ai présenté comment classer les textes japonais en utilisant la version PyTorch de BERT. En modifiant un autre code source, vous pouvez effectuer des tâches telles que la génération de texte et la réponse aux questions ainsi que la classification de texte.
Jusqu'à présent, exécuter BERT en japonais avec PyTorch posait un gros problème, mais je pense que cet obstacle est devenu très bas avec la sortie de modèles pré-entraînés en japonais. Bien sûr, essayez la version PyTorch de BERT avec des tâches japonaises.
https://techlife.cookpad.com/entry/2018/12/04/093000 http://kento1109.hatenablog.com/entry/2019/08/23/092944
Recommended Posts