【NLP】容納衆多優秀模型的自然語言處理庫PyTorch-Transformers

參考網站
公衆號:深度學習視覺
NLP

前言

Github:Pytorch-transformers
該工具追求着這樣的一個目標,幾行代碼調用最先進的模型,加載訓練好的模型參數,來完成自然語言項目,比如機器翻譯、文本摘要、問答系統等。Transformers 同時支持 PyTorch 和TensorFlow2.0,用戶可以將這些工具放在一起使用。

支持模型

transformers目前提供以下NLU / NLG體系結構:
BERT、GPT、GPT-2、Transformer-XL、XLNet、XLM、RoBERTa、DistilBERT、CTRL、CamemBERT、ALBERT、T5、XLM-RoBERTa、MMBT、FlauBERT、其他社區的模型

安裝PyTorch-Transformers

pip install pytorch-transformers

使用GPT-2預測下一個單詞

GPT-2是一種於基於transformer的生成語言模型,其語言生成能力優秀到被討論禁止開源。該模型是在40GB的文本下進行無監督訓練。

# 導入必要的庫
import torch
from pytorch_transformers import GPT2Tokenizer, GPT2LMHeadModel

# 加載預訓練模型tokenizer (vocabulary)
tokenizer = GPT2Tokenizer.from_pretrained('gpt2')

# 對文本輸入進行編碼
text = "What is the fastest car in the"
indexed_tokens = tokenizer.encode(text)

# 在PyTorch張量中轉換indexed_tokens
tokens_tensor = torch.tensor([indexed_tokens])

# 加載預訓練模型 (weights)
model = GPT2LMHeadModel.from_pretrained('gpt2')

#將模型設置爲evaluation模式,關閉DropOut模塊
model.eval()

# 如果你有GPU,把所有東西都放在cuda上
tokens_tensor = tokens_tensor.to('cuda')
model.to('cuda')

# 預測所有的tokens
with torch.no_grad():
    outputs = model(tokens_tensor)
    predictions = outputs[0]

# 得到預測的單詞
predicted_index = torch.argmax(predictions[0, -1, :]).item()
predicted_text = tokenizer.decode(indexed_tokens + [predicted_index])

# 打印預測單詞
print(predicted_text)

預測長文本

!git clone https://github.com/huggingface/pytorch-transformers.git
# 啓動模型
!python pytorch-transformers/examples/run_generation.py \
    --model_type=gpt2 \
    --length=100 \
    --model_name_or_path=gpt2 \
  1. 輸入(本來是英文)

在一個令人震驚的發現中,科學家發現了一羣獨角獸,它們生活在安第斯山脈一個偏遠的,以前未被開發的山谷中。對於研究人員而言,更令人驚訝的是,獨角獸會說完美的英語。

  1. 輸出(本來是英文)

獨角獸似乎和普通人一樣瞭解彼此。該研究於5月6日發表在《科學轉化醫學》上。此外,研究人員發現,百分之五的獨角獸彼此之間具有很好的識別性。研究團隊認爲,這可能會轉化爲未來,使人類能夠與稱爲超級獨角獸的人進行更清晰的交流。如果我們要朝着那個未來前進,我們至少必須做到

除了GPT-2以外,還有諸如XLNet,一個在包括問答、自然語言推理、情感分析和文檔排序等18項任務上取得了最先進結果的模型。

!python pytorch-transformers/examples/run_generation.py \
    --model_type=xlnet \
    --length=50 \
    --model_name_or_path=xlnet-base-cased \

還有能夠學習長期依賴的Transformer-XL,比標準Transformer快1800倍。

!python pytorch-transformers/examples/run_generation.py \
    --model_type=transfo-xl \
    --length=100 \
    --model_name_or_path=transfo-xl-wt103 \

Transformers API調用

import torch
from transformers import *

# transformer有一個統一的API
# 有10個Transformer結構和30個預訓練權重模型。
#模型|分詞|預訓練權重
MODELS = [(BertModel,       BertTokenizer,       'bert-base-uncased'),
          (OpenAIGPTModel,  OpenAIGPTTokenizer,  'openai-gpt'),
          (GPT2Model,       GPT2Tokenizer,       'gpt2'),
          (CTRLModel,       CTRLTokenizer,       'ctrl'),
          (TransfoXLModel,  TransfoXLTokenizer,  'transfo-xl-wt103'),
          (XLNetModel,      XLNetTokenizer,      'xlnet-base-cased'),
          (XLMModel,        XLMTokenizer,        'xlm-mlm-enfr-1024'),
          (DistilBertModel, DistilBertTokenizer, 'distilbert-base-cased'),
          (RobertaModel,    RobertaTokenizer,    'roberta-base'),
          (XLMRobertaModel, XLMRobertaTokenizer, 'xlm-roberta-base'),
         ]

# 要使用TensorFlow 2.0版本的模型,只需在類名前面加上“TF”,例如。“TFRobertaModel”是TF2.0版本的PyTorch模型“RobertaModel”

# 讓我們用每個模型將一些文本編碼成隱藏狀態序列:
for model_class, tokenizer_class, pretrained_weights in MODELS:
    # 加載pretrained模型/分詞器
    tokenizer = tokenizer_class.from_pretrained(pretrained_weights)
    model = model_class.from_pretrained(pretrained_weights)

    # 編碼文本
    input_ids = torch.tensor([tokenizer.encode("Here is some text to encode", add_special_tokens=True)])  # 添加特殊標記
    with torch.no_grad():
        last_hidden_states = model(input_ids)[0]  # 模型輸出是元組

# 每個架構都提供了幾個類,用於對下游任務進行調優,例如。
BERT_MODEL_CLASSES = [BertModel, BertForPreTraining, BertForMaskedLM, BertForNextSentencePrediction,
                      BertForSequenceClassification, BertForTokenClassification, BertForQuestionAnswering]

# 體系結構的所有類都可以從該體系結構的預訓練權重開始
#注意,爲微調添加的額外權重只在需要接受下游任務的訓練時初始化

pretrained_weights = 'bert-base-uncased'
tokenizer = BertTokenizer.from_pretrained(pretrained_weights)
for model_class in BERT_MODEL_CLASSES:
    # 載入模型/分詞器
    model = model_class.from_pretrained(pretrained_weights)

    # 模型可以在每一層返回隱藏狀態和帶有注意力機制的權值
    model = model_class.from_pretrained(pretrained_weights,
                                        output_hidden_states=True,
                                        output_attentions=True)
    input_ids = torch.tensor([tokenizer.encode("Let's see all hidden-states and attentions on this text")])
    all_hidden_states, all_attentions = model(input_ids)[-2:]

    #模型與Torchscript兼容
    model = model_class.from_pretrained(pretrained_weights, torchscript=True)
    traced_model = torch.jit.trace(model, (input_ids,))

    # 模型和分詞的簡單序列化
    model.save_pretrained('./directory/to/save/')  # 保存
    model = model_class.from_pretrained('./directory/to/save/')  # 重載
    tokenizer.save_pretrained('./directory/to/save/')  # 保存
    tokenizer = BertTokenizer.from_pretrained('./directory/to/save/')  # 重載
import tensorflow as tf
import tensorflow_datasets
from transformers import *

# 從預訓練模型/詞彙表中加載數據集、分詞器、模型
tokenizer = BertTokenizer.from_pretrained('bert-base-cased')
model = TFBertForSequenceClassification.from_pretrained('bert-base-cased')
data = tensorflow_datasets.load('glue/mrpc')

# 準備數據集作爲tf.data.Dataset的實例
train_dataset = glue_convert_examples_to_features(data['train'], tokenizer, max_length=128, task='mrpc')
valid_dataset = glue_convert_examples_to_features(data['validation'], tokenizer, max_length=128, task='mrpc')
train_dataset = train_dataset.shuffle(100).batch(32).repeat(2)
valid_dataset = valid_dataset.batch(64)

# 準備訓練:編寫tf.keras模型與優化,損失和學習率調度
optimizer = tf.keras.optimizers.Adam(learning_rate=3e-5, epsilon=1e-08, clipnorm=1.0)
loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
metric = tf.keras.metrics.SparseCategoricalAccuracy('accuracy')
model.compile(optimizer=optimizer, loss=loss, metrics=[metric])

# 用tf.keras.Model.fit進行測試和評估
history = model.fit(train_dataset, epochs=2, steps_per_epoch=115,
                    validation_data=valid_dataset, validation_steps=7)

# 在PyTorch中加載TensorFlow模型進行檢查
model.save_pretrained('./save/')
pytorch_model = BertForSequenceClassification.from_pretrained('./save/', from_tf=True)

#讓我們看看我們的模型是否學會了這個任務
sentence_0 = "This research was consistent with his findings."
sentence_1 = "His findings were compatible with this research."
sentence_2 = "His findings were not compatible with this research."
inputs_1 = tokenizer.encode_plus(sentence_0, sentence_1, add_special_tokens=True, return_tensors='pt')
inputs_2 = tokenizer.encode_plus(sentence_0, sentence_2, add_special_tokens=True, return_tensors='pt')

pred_1 = pytorch_model(inputs_1['input_ids'], token_type_ids=inputs_1['token_type_ids'])[0].argmax().item()
pred_2 = pytorch_model(inputs_2['input_ids'], token_type_ids=inputs_2['token_type_ids'])[0].argmax().item()

print("sentence_1 is", "a paraphrase" if pred_1 else "not a paraphrase", "of sentence_0")
print("sentence_2 is", "a paraphrase" if pred_2 else "not a paraphrase", "of sentence_0")
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章