LUSE: 無監督資料預訓練短文字編碼模型

infgrad發表於2021-07-31

LUSE: 無監督資料預訓練短文字編碼模型

1 前言

本博文字應寫之前立的Flag:基於加密技術編譯一個自己的Python直譯器,經過半個多月嘗試已經成功,但考慮到安全性問題就不公開了,有興趣的朋友私聊討論吧。
從本篇部落格開始,本人將轉化寫作模式,由話癆模式轉為極簡模式,力求三言兩語讓各位看的明白。

2 工作簡介

受到MOCO和SimCSE的啟發, 基於自監督,使用海量無監督資料(nlp_chinese_corpus)預訓練了一個專門用於短文字表徵的編碼器。該編碼器在分類任務尤其是短文字相似度任務上效果超過同級別BERT模型。該預訓練模型暫且叫LUSE.

本次實驗結果是僅在預訓練0.1輪(10萬步)情況下得到的,完全訓練後會得到更強的效果。

三層預訓練模型(torch)下載地址

程式碼地址: https://github.com/DunZhang/LUSE

預處理後的nlp_chinese_corpus下載地址: https://pan.baidu.com/s/11ddgvZ7QAbIlliJgUiau9g 提取碼:luse

使用方法:和正常BERT一樣載入使用,使用CLS作為句表徵。text_vec = transformers.BertModel()(input_id,attention_mask,token_type_ids)[1]

3 演算法詳情

演算法虛擬碼如下:


Input: sens: List[str], sen_encoder: torch.nn.Module
Output: None
    
aug_sens = data_augment(sens) # 資料增強, 每個句子均會增強固定數量相似句做為正例,剩餘所有句子則為負例
sens_vecs = sen_encoder.forward(sens+aug_sens) # 將所有句子編碼為句向量
scores = compute_score(sens_vecs) # 計算所有向量間的相似度值
loss = multi_positive_multi_negative_func(scores) # 基於相似度值計算loss
update(sen_encoder,loss) # 更新模型權重

3.1 資料增強

本人將資料增強分為兩類, text-level和vector-level.

text-level:字詞句層面的資料增強, 本演算法使用EDA

vector-level:句編碼層面的資料增強,可參考影像, 本演算法只使用隨機裁剪,對應NLP操作為置0,即dropout操作, SimCSE就是該方法. CV與NLP的完美融合!!!

3.2 損失函式

對於一個句子,自身和其增強而來的句子為正例,其他句子及其增強為負例. 優化目標為讓這些正例的概率最高,如果有n個正例,那麼希望這n個正例概率都很高,那就索性平分概率值1得了,讓其他負例概率都為0, 這其實就是均值不等式. 詳細推導公式和程式碼實現見本人部落格:一種基於均值不等式的Listwise損失函式

3.3 預訓練資料

預訓練資料為brightmart開源的nlp_chinese_corpus. 本人只做簡單分句去除空白字元兩種清洗操作.然後將所有語料庫所有句子完全打散作為訓練集.最終約有1.1億個句子

3.4 訓練細節

batch_size為128, 每個句子增強8個相似問(4個EDA, 4個dropout),因此每個句子有9(8+1)個正例和(9*128-9)個負例,這變相擴大了batch_size, 也正是此原因, 本人未使用MOCO的負例佇列來增大batch_size. 忍不住再誇一波MOCO負例佇列的精巧設計,何凱明yyds.

優化器為Adam, 學習率5e-5,最大長度64(本模型只考慮短文字),短文字表徵的pooling_mode為CLS向量,有興趣的可以使用SentenceBERT, BERT-Whitening 和 SimCSE的pooling方式, 本開源專案已經提供程式碼.

GPU是租了一塊RTX3090,訓練了兩天兩夜,約12萬步,即1500萬個句子,離1.1億差的遠了,更別提多epoch了. 中途還遇上伺服器當機,不得不載入以前的模型重新訓練, 真是倒了血黴. 共花了約150塊大洋,要是訓練完一輪非得傾家蕩產不可,這就是隻預訓練三層模型且0.1輪的原因.

3.5 小技巧:同義詞搜尋加速

EDA裡最耗時操作為選取同義詞, 本人使用騰訊800萬詞向量, 使用gensim選取同義詞速度比訓練還慢, 對於窮逼是無法接受.

解決方案: 預快取同義詞詞典, 計算同義詞時不要用gensim庫, 使用faiss或milvus向量加速庫, 本人在不使用GPU的情況下僅耗時一夜就完成了快取. 句向量加速指南可以看我的部落格:[milvus和faiss安裝及其使用教程]. 或者直接用我計算好的也行,本人能開源的都開源了,就是希望有算力的同志把我的方法跑一波.

4 微調驗證

作為預訓練模型,總需要微調來證明效果的.

4.1 資料集

4個分類資料集:

資料集 #Trian #Dev 任務型別 參考連結
NLPCC情感分類 8000 2000 2分類 https://www.luge.ai/
微博情感分類 99988 20000 2分類 https://github.com/SophonPlus/ChineseNlpCorpus
購物網站評論情感分類 52774 10000 2分類 https://github.com/SophonPlus/ChineseNlpCorpus
今日頭條新聞分類 53360 10000 15分類 https://github.com/CLUEbenchmark/CLUE

6個相似度資料集:

資料集 #Train #Dev 參考連結
LCQMC(哈工大通用聊天資料集) 238766 8802 http://icrc.hitsz.edu.cn/Article/show/171.html
ADAT(基於Adversarial Attack的問題等價性判別比賽資料集) 36210 9027 /
ATEC(螞蟻金服相似度資料集) 81981 20496 /
CHIP(平安醫療中文的疾病問答資料) 16000 4000 /
COVID(新冠句對) 8747 2001 https://aistudio.baidu.com/aistudio/datasetdetail/48492
CCKS(微眾銀行智慧客服問句匹配大賽) 80000 20000 /

沒有連結的資料集可以自行搜尋, 由於微調資料集可能設計到一些版權問題, 開源專案裡就不再放出.

為了簡化操作只使用dev評估.

4.2 微調方法

對於分類資料集,使用交叉熵微調

對於相似度資料集,由於預訓練模型為短文字編碼器, 將兩個句子一起輸入做0/1分類是不合適的. 做法是單獨對兩個句子進行編碼,計算餘弦相似度並歸一化至0-1之間作為概率值, 然後最大似然求解.

同時考慮到低計算資源情況, 訓練又分為全部微調和固定bert訓練上層神經網路兩種.

4.3 評價指標

分類資料集使用ACC和F1

相似度資料集使用Spearman相關係數

4.4 基線模型

哈工大的RBT3

4.4 實驗結果

分類實驗結果(ACC / F1):

NLPCC情感分類 微博情感分類 購物網站評論情感分類 今日頭條新聞分類
ACC / F1 ACC / F1 ACC / F1 ACC / F1
RBT3-TrainBERT 0.786 / 0.784 0.979 / 0.979 0.945 / 0.945 0.554 / 0.538
LUSE-TrainBERT 0.791 / 0.789 0.979 / 0.979 0.944 / 0.944 0.556 / 0.541
RBT3-FreezeBERT 0.720 / 0.720 0.864 / 0.864 0.873 / 0.873 0.445 / 0.416
LUSE-FreezeBERT 0.740 / 0.740 0.804 / 0.804 0.888 / 0.888 0.482 / 0.460

文字相似度實驗結果(Spearman):

ADAT ATEC CCKS微眾銀行 CHIP COVID LCQMC
RBT3-TrainBERT 0.633 0.086 0.785 0.624 0.703 0.642
LUSE-TrainBERT 0.636 0.210 0.796 0.634 0.692 0.650
RBT3-FreezeBERT 0498 0.070 0.432 0.308 0.507 0.280
LUSE-FreezeBERT 0.556 0.200 0.675 0.527 0.653 0.497

行名解釋, RBT3代表使用的是哈工大的RBT3模型,LUSE代表本人預訓練的模型.

TrainBERT代表微調時整體訓練耗時但效果好, FreezeBERT代表凍結BERT訓練上層神經網路,省時省力但效果差些.

實驗結論: 專門針對短文字編碼預訓練的模型確實可以取得更好的效果, 尤其是在短文字相似度任務上

5 總結

LUSE模型是一個優缺點非常明顯的模型, 成也預訓練任務敗也預訓練任務.

LUSE模型在需要進行短文字編碼的任務上能取得較好的效果,即便只訓練了0.1輪,效果也很明顯.

但是缺點同樣突出, 由於其預訓練任務, 使其適用場景變得很小, 在其他任務上LUSE怕是無能為力了, 估計在二分類的短文字相似度任務上,LUSE都未必效果好,後續可以做實驗看下.

即便如此, 本人構想還是對的,基於無監督資料, 藉助對比學習, 還是可以預訓練出優質文字編碼模型的, 挺好奇為什麼SimCSE的作者不預訓練一個文字編碼模型.

影像的好多東西都可以借鑑到NLP中,NLPer需要定期關注影像領域的最新進展.

6 TODOList

  • MOCO負例佇列或許可以一試
  • 能否基於GAN做vector-level的資料增強
  • 使用百GB級別資料預訓練一次大模型
  • 和MLM-Loss做交叉訓練
  • 文字相似度微調模型可以嘗試Sentence-BERT的方式
  • alignment和uniformity驗證無監督句向量效果

7 FAQ

Q: 為什麼就放出了一個沒完全訓練的小模型?
A:

Q: 後續還會放出新的預訓練模型嗎?
A: 會的, 一定會的. 該預訓練任務本人會一直嘗試下去的, 但是要等到顯示卡回落到正常價格之後(萬惡的虛擬貨幣)

Q:simbert以及RoFormer-sim相比如何?
A: 沒有可比性,有監督對無監督就是降維打擊. 中文資料任務完全可以用SimBERT替代LUSE預訓練模型.

Q:接上一問題,那LUSE預訓練模型的意義何在呢?
A:如果沒有有監督資料怎麼辦?如果資料脫敏了怎麼辦? 本文主要探索無監督資料預訓練短文字編碼模型的可能性.

Q:EDA和dropout資料增強,那個更有用?
A:沒錢做消融實驗了,中庸了, 兩個都用. 個人猜測兩個都起正面作用, dropout可能會更強些, 畢竟simcse論文效果很好

Q:為什麼實驗結果的好多F1和ACC一樣了?
A:其實不一樣,只是取了前三位恰好一樣罷了

8 致謝

特別感謝 資料集nlp_chinese_corpus, 沒有資料集一切免談.

還要感謝SimCSE和MOCO,正是這兩篇論文激發本人嘗試LUSE的興致.

相關文章