https://zhuanlan.zhihu.com/p/87760325
https://zhuanlan.zhihu.com/p/89232880
一、前言
Simple Transformers是Hugging Face在的Transformers庫的基礎上構建的。 Hugging Face Transformers庫是供研究人員和其他需要全面控制操作方式的人員使用的庫。 當需要偏離常規,做不同的事情或完全做新的事情時,它也是最佳選擇。 比如NLP中得多分類任務,下面根據我的簡單測試,一起看看。
二、介紹
Simple Transformers專為一些特殊得NLP任務設計得。文本分類非常普遍,如今再NLP任務中也不算比較難的任務了。 Simple Transformers就是這么想的,在這里就是要做到這一點!
所有源代碼都可以在Github Repo上找到。
安裝
- 從這里安裝Anaconda或Miniconda Package Manager
- 創建一個新的虛擬環境並安裝所需的軟件包。
conda create -n transformers python pandas tqdm
conda activate transformers
如果使用cuda:
conda install pytorch cudatoolkit=10.0 -c pytorch
否則:
conda install pytorch cpuonly -c pytorch conda install -c anaconda scipy conda install -c anaconda scikit-learn pip install transformers pip install tensorboardx
安裝simpletransformers。
用法
讓我們看看如何對AGNews數據集執行多類分類。
下載並提取數據
- 從Fast.ai下載數據集。(國內用戶需要FQ下載)
- 提取train.csv和test.csv並將它們放在目錄data /中。
准備數據進行培訓
import pandas as pd train_df = pd.read_csv('data/train.csv', header=None) train_df['text'] = train_df.iloc[:, 1] + " " + train_df.iloc[:, 2] train_df = train_df.drop(train_df.columns[[1, 2]], axis=1) train_df.columns = ['label', 'text'] train_df = train_df[['text', 'label']] train_df['text'] = train_df['text'].apply(lambda x: x.replace('\\', ' ')) eval_df = pd.read_csv('data/test.csv', header=None) eval_df['text'] = eval_df.iloc[:, 1] + " " + eval_df.iloc[:, 2] eval_df = eval_df.drop(eval_df.columns[[1, 2]], axis=1) eval_df.columns = ['label', 'text'] eval_df = eval_df[['text', 'label']] eval_df['text'] = eval_df['text'].apply(lambda x: x.replace('\\', ' ')) eval_df['label'] = eval_df['label'].apply(lambda x:x-1)
Simple Transformers要求數據必須包含在至少兩列的Pandas DataFrames中。 只需為列的文本和標簽命名,SimpleTransformers就會處理數據。 或者可以遵循以下約定。
第一列包含文本,類型為str。
第二列包含標簽,類型為int。
對於多類分類,標簽應該是從0開始的整數。如果數據具有其他標簽,則可以使用python dict保留從原始標簽到整數標簽的映射。
使用模型:
from simpletransformers.model import TransformerModel # Create a TransformerModel model = TransformerModel('roberta', 'roberta-base', num_labels=4)
這將創建一個TransformerModel,用於訓練,評估和預測。 第一個參數是model_type,第二個參數是model_name,第三個參數是數據中的標簽數。
model_type可以是['bert','xlnet','xlm','roberta','distilbert']之一。
有關可用於model_name的預訓練模型的完整列表,請參閱“當前預訓練模型”。
要加載以前保存的模型而不是默認模型的模型,可以將model_name更改為包含已保存模型的目錄的路徑。
model = TransformerModel('xlnet', 'path_to_model/', num_labels=4)
TransformerModel具有dict args,其中包含許多屬性,這些屬性可提供對超參數的控制。 有關每個屬性的詳細說明, 默認值如下所示。
self.args = { 'output_dir': 'outputs/', 'cache_dir': 'cache_dir', 'fp16': True, 'fp16_opt_level': 'O1', 'max_seq_length': 128, 'train_batch_size': 8, 'gradient_accumulation_steps': 1, 'eval_batch_size': 8, 'num_train_epochs': 1, 'weight_decay': 0, 'learning_rate': 4e-5, 'adam_epsilon': 1e-8, 'warmup_ratio': 0.06, 'warmup_steps': 0, 'max_grad_norm': 1.0, 'logging_steps': 50, 'save_steps': 2000, 'overwrite_output_dir': False, 'reprocess_input_data': False, 'process_count': cpu_count() - 2 if cpu_count() > 2 else 1, }
在創建TransformerModel或調用其train_model方法時,只要簡單地傳遞包含要更新的鍵值對的字典,就可以修改這些屬性中的任何一個。 下面給出一個例子。
# Create a TransformerModel with modified attributes
model = TransformerModel('roberta', 'roberta-base',
num_labels=4, args={'learning_rate':1e-5, 'num_train_epochs': 2, 'reprocess_input_data': True, 'overwrite_output_dir': True})
開始訓練:
# Train the model
model.train_model(train_df)
train_model方法將在第n個步驟(其中n為self.args ['save_steps'])的第n個步驟創建模型的檢查點(保存)。 訓練完成后,最終模型將保存到self.args ['output_dir']。
驗證:
result, model_outputs, wrong_predictions = model.eval_model(eval_df)
要評估模型,只需調用eval_model。 此方法具有三個返回值。
結果:dict形式的評估結果。 默認情況下,僅對多類分類計算馬修斯相關系數(MCC)。
model_outputs:評估數據集中每個項目的模型輸出列表。 如果需要每個類別的概率而不是單個預測,這很有用。 通過對輸出應用softmax函數來計算預測。
錯誤的預測:每個錯誤預測的InputFeature列表。 可以從InputFeature.text_a屬性獲取文本。 (可以在存儲庫的utils.py文件中找到InputFeature類)
還可以包括要在評估中使用的其他指標。 只需將指標函數作為關鍵字參數傳遞給eval_model方法。 指標功能應包含兩個參數,第一個是真實標簽,第二個是預測。 這遵循sklearn標准。
對於任何需要附加參數的度量標准函數(在sklearn中為f1_score),我們可以在添加了附加參數的情況下將其包裝在自己的函數中,然后將函數傳遞給eval_model。
from sklearn.metrics import f1_score, accuracy_score
def f1_multiclass(labels, preds):
return f1_score(labels, preds, average='micro')
result, model_outputs, wrong_predictions = model.eval_model(eval_df, f1=f1_multiclass, acc=accuracy_score)
作為參考,我使用這些超參數獲得的結果如下:
{'mcc': 0.937104098029913, 'f1': 0.9527631578947369, 'acc': 0.9527631578947369}
這個結果是我沒有做任務超參的調整。。。。
預測/測試
在實際應用中,我們通常不知道什么是真正的標簽。 要對任意示例執行預測,可以使用predict方法。 此方法與eval_model方法非常相似,不同之處在於,該方法采用簡單的文本列表並返回預測列表和模型輸出列表。
predictions, raw_outputs = model.predict(['Some arbitary sentence'])
結論
在許多實際應用中,多類分類是常見的NLP任務。 Simple Transformers是將Transformers的功能應用於現實世界任務的一種輕松方法,建議大家開始嘗試。