本文(部份內容)翻譯自文章A Visual Guide to Using BERT for the First Time,其做者爲Jay Alammar,訪問網址爲:http://jalammar.github.io/a-visual-guide-to-using-bert-for-the-first-time/ ,能夠做爲那些不熟悉BERT的讀者首次閱讀。文章中若有翻譯不當之處,還請批評指正。html
本文是關於如何使用BERT的變異版原本進行句子分類的簡單教程。該例子足夠簡單,所以能夠做爲首次使用BERT的介紹,固然,它也包含了一些關鍵性的概念。python
本文中使用的數據集爲SST2,它包含了電影評論的句子,每一句帶有一個標籤,或者標註爲正面情感
(取值爲1),或者標註爲負面情感
(取值爲0)。
git
咱們的目標是建立一個模型,它可以處理一個句子(就行咱們數據集中的句子那樣)而且輸出1(代表該句子具備正面情感)或者0(代表該句子具備負面情感)。咱們設想它長這樣:
事實上,該模型包含兩個模型:github
DistillBERT
會處理句子並把它提取後的信息傳遞給下一個模型。DistillBERT
是BERT
的變異版本,由HuggingFace
小組開發和開源。它是BERT
的更輕量、更快速的版本,同時它的表現基本與BERT
相近。邏輯迴歸模型
(Logistic Regression model),它會利用 DistillBERT
的處理結果,而後將句子進行分類成正面情感
或者負面情感
(分別爲1或者0)。在兩個模型之間傳遞的數據爲1個768維的向量。咱們能夠把這個向量理解爲這個句子的嵌入向量(Embedding Vector),用於分類。
ide
儘管咱們用了兩個模型,可是咱們只會訓練邏輯迴歸模型
。對於DistillBERT
,咱們會使用已經預訓練好的英語模型。該模型,既不會被訓練也不會作微調(fine-tuned)
,直接進行句子分類。這是由於,咱們能夠從BERT
中得到句子分類的能力。這尤爲適合BERT
輸出的第一個位置(跟[CLS]標誌相關)。我相信這是因爲BERT
的第二個訓練模型——下一句分類(Next sentence classification)
。該模型的目標在於封裝句子級別的語料進行訓練,並輸出第一個位置。transformers
庫已經提供了DistillBERT
的操做,做爲其預訓練模型版本。
gitlab
如下是該教程的計劃安排。首先咱們會使用DistillBERT
來產生2000個句子的句子向量。
這一步以後咱們不會接觸DistillBERT
。接下去只是Scikit Learn的操做。咱們將數據集分爲訓練集和測試集。
接下來咱們在訓練集上使用邏輯迴歸模型
進行訓練。
測試
在咱們講解代碼和解釋如何訓練模型以前,讓咱們看一下已預訓練好的模型如何進行預測。
咱們嘗試着預測句子「a visually stunning rumination on love」。第一步是使用BERT tokenizer 將句子劃分紅tokens。而後加上句子分類的特殊tokens([CLS]在開始位置,[SEP]在句子結尾)。
第三步是經過已預訓練好的模型的嵌入表(embedding table)將每個tokens映射成各自的id。這一步能夠參考word embedding
,參考閱讀文章The Illustrated Word2vec。
咱們注意到,tokenizer僅須要一行代碼就能完成以上步驟。ui
tokenizer.encode("a visually stunning rumination on love", add_special_tokens=True)
咱們的輸入句子如今已經處理成DistilBERT
能夠處理的格式了。
若是你已經讀過Illustrated BERT,那麼這一步的可視化以下:
翻譯
DistilBERT
處理輸入向量的流程相似於BERT
。輸出是每個token對應一個向量。每一個向量由768個浮點型數字組成。
由於這是一個句子分類任務,故咱們忽略其餘向量而只取第一個向量(跟[CLS]相關的那個)。這個向量咱們會做爲邏輯迴歸模型
的輸入。
從這裏開始,就是邏輯迴歸模型
的事兒了,它負責將輸入的向量進行分類。咱們設想一個預測的流程長這樣:
3d
文章中用到的數據集下載網址爲:https://github.com/clairett/pytorch-sentiment-classification/raw/master/data/SST2/train.tsv。下載DistillBERT
模型文件,網址爲:https://www.kaggle.com/abhishek/distilbertbaseuncased 。
原文中這部分的代碼講解比較多,我這邊忽略過去了,筆者想按本身的思路來處理,所以這部份內容會有調整。完整的思路以下:
下載數據集和模型文件,與代碼放在同一目錄下。創建jupyter腳本,先載入必要的模塊:
接着咱們利用pandas讀取訓練集數據,並統計標籤值的頻數:
讀取DistillBERT
模型文件並建立tokenizer:
經過tokenizer完成句子切分紅tokens,並映射到id:
因爲每一個句子的長度可能會不一樣,所以須要對句子進行填充(Padding),保持每一個句子的輸入維度一致,句子填充的長度爲該數據集中句子長度的最大值。
對句子進行填充後,而後再進行Masking。這是由於若是咱們直接將padded傳入BERT
,這會形成必定的困擾。咱們須要建立另外一個變量,來告訴模型去mask以前的填充結果。這就是attention_mask的做用:
咱們的輸入已經準備完畢,接下來咱們嘗試着用DistillBERT
來獲取向量,也就是以前說的第一步。這一步的處理結果會返回last_hidden_states
,而咱們的分類模型只須要獲取[CLS]
這個token對應的輸出向量。
可視化的操做說明以下圖:
這樣,咱們就把以前的每個句子映射成了1個768維的句子向量,而後就利用邏輯迴歸模型
直接進行訓練就能夠了。
最後,咱們來看一下這個模型在測試集上的效果:
本文主要介紹瞭如何利用DistillBERT
和已經封裝好的transformers
模塊,結合邏輯迴歸模型
對英文句子進行文本二分類。後續筆者還會研究在中文上的文本分類以及如何進行微調(Fine_tuning)。
本項目的Gitlab地址爲:https://gitlab.com/jclian91/sentence_classify_using_distillBERT_LR,原文章做者的Github地址爲https://github.com/jalammar/jalammar.github.io/blob/master/notebooks/bert/A_Visual_Notebook_to_Using_BERT_for_the_First_Time.ipynb 。 感謝你們閱讀~