如何讓文本也像圖片一樣經(jīng)過預(yù)訓(xùn)練?這是一份通用句子編碼器的神秘指南。
簡介
遷移學(xué)習(xí)是一個令人興奮的概念,我們試圖利用先驗知識從一個領(lǐng)域和任務(wù)到另一個領(lǐng)域和任務(wù)。靈感來自我們?nèi)祟惐旧?,我們有一種與生俱來的能力,即不從零開始學(xué)習(xí)所有東西。我們從過去學(xué)到的知識中轉(zhuǎn)移和利用我們的知識來處理各種各樣的任務(wù)。有了計算機視覺,我們就有了優(yōu)秀的大型數(shù)據(jù)集,比如ImageNet,在它之上我們可以獲得一套世界級的、最先進(jìn)的預(yù)訓(xùn)練模型來利用遷移學(xué)習(xí)。但是自然語言處理呢?考慮到文本數(shù)據(jù)是如此的多樣化、充斥著噪音以及非結(jié)構(gòu)化的特點,這是一個嚴(yán)峻的挑戰(zhàn)。我們最近在文本嵌入方面取得了一些成功,包括Word2vec、GloVe 和 FastText 等方法,我在關(guān)于“文本數(shù)據(jù)的特征工程”[1]的文章中介紹了所有這些方法。
在這篇文章中,我們將展示幾種最先進(jìn)的通用句子嵌入編碼器,特別是在遷移學(xué)習(xí)任務(wù)的少量數(shù)據(jù)上與 Word embedding 模型相比的情況下,它們往往會給出令人驚訝的良好性能。
我們將嘗試涵蓋基本概念,并展示一些利用python和TensorFlow的手工操作示例,在文本分類問題中側(cè)重于情感分析的案例。
為什么我們對嵌入(embedding)如此瘋狂?
嵌入是一個固定長度的向量,通常用于編碼和表示一個實體(文檔、句子、單詞、圖形)
我在前一篇文章[2]中談到了在文本數(shù)據(jù)和NLP上下文中嵌入的必要性。但為了方便起見,我將在這里簡短地重復(fù)一下。在語音或圖像識別系統(tǒng)方面,我們已經(jīng)以豐富的密集特征向量的形式獲得信息,這些特征向量嵌入在高維數(shù)據(jù)集中,如音頻譜圖和圖像像素強度。然而,當(dāng)涉及到原始文本數(shù)據(jù)時,特別是基于計數(shù)的模型,比如詞袋模型(Bag of words),我們處理的是單個單詞,它們可能有自己的標(biāo)識符,并且不捕獲單詞之間的語義關(guān)系。這就導(dǎo)致了文本數(shù)據(jù)的大量稀疏詞向量,因此如果我們沒有足夠的數(shù)據(jù),我們可能會因為維度詛咒而得到很糟糕的模型,甚至過擬合數(shù)據(jù)。
對比圖片、音頻、文本的特征表示
預(yù)測方法(predictive methods),比如基于神經(jīng)網(wǎng)絡(luò)的語言模型,試圖從其相鄰的單詞中預(yù)測單詞,觀察語料庫中的單詞序列,在學(xué)習(xí)分布式表示的過程中,給我們提供稠密的單詞嵌入表示。
現(xiàn)在你可能在想,我們從文本中得到了一堆向量,現(xiàn)在怎么辦?如果我們有一個很好的文本數(shù)據(jù)的數(shù)字表示,它甚至捕捉到上下文和語義,我們可以將它用于各種各樣的下游現(xiàn)實世界任務(wù),比如情感分析、文本分類、聚類、摘要、翻譯等等。事實上,機器學(xué)習(xí)或深度學(xué)習(xí)模型能在這些數(shù)字和嵌入表示上運行,是編碼這些模型使用的文本數(shù)據(jù)的關(guān)鍵。
文本嵌入
這里的一個大趨勢是找出所謂的“通用嵌入(universal embeddings)”,它基本上是通過在一個龐大的語料庫上訓(xùn)練深度學(xué)習(xí)模型而獲得的預(yù)訓(xùn)練的嵌入表示。這使我們能夠在各種各樣的任務(wù)中使用這些經(jīng)過預(yù)訓(xùn)練的(一般的)嵌入表示,包括缺乏足夠數(shù)據(jù)等約束的場景。這是遷移學(xué)習(xí)的一個完美例子,利用預(yù)訓(xùn)練嵌入表示的先驗知識來解決一個全新的任務(wù)!下圖顯示了通用詞嵌入(word embedding)和句子嵌入(sentence embedding)的一些最新趨勢。
最近在通用詞&句子嵌入的趨勢
來源:https://medium.com/huggingface/universal-word-sentence-embeddings-ce48ddc8fc3a)
上圖中有一些有趣的趨勢,包括谷歌的通用句子編碼器,我們將在本文中詳細(xì)探討。現(xiàn)在,讓我們在深入研究通用句子編碼器之前,簡要介紹單詞和句子嵌入模型的趨勢和發(fā)展。
詞嵌入模型的發(fā)展趨勢
詞嵌入模型(Word Embedding Models)是一些比較成熟的模型,這些模型是從2013年的Word2vec開始發(fā)展的。基于語義和上下文相似性的連續(xù)向量空間嵌入詞向量的三種最常見的利用深度學(xué)習(xí)(無監(jiān)督方法)的模型是:
Word2Vec
GloVe
FastText
這些模型是基于分布語義學(xué)領(lǐng)域中的分布假設(shè)原理而建立的,它告訴我們,在相同的語境中發(fā)生和使用的詞在語義上是相似的,具有相似的意義。
最近發(fā)展起來的這一領(lǐng)域的另一個有趣的模型是由Allen人工智能研究所(Allen Institute for Artificial Intelligence)開發(fā)的ELMo(Embeddings from Language Models)模型。
基本上,ELMo給我們提供了從深度雙向語言模型(biLM)中學(xué)習(xí)的單詞嵌入,該模型通常是在大型文本語料庫上進(jìn)行預(yù)訓(xùn)練,從而使遷移學(xué)習(xí)和這些嵌入能夠跨不同的NLP任務(wù)使用。Allen AI告訴我們,ELMo表示是上下文感知的、深度的和基于字符的,它使用形態(tài)學(xué)線索來形成表示,甚至對于OOV(out-of-vocabulary)標(biāo)記也是如此。
通用句子嵌入模型的發(fā)展趨勢
句子嵌入(Sentence Embedding)的概念并不是一個非常新的概念,因為在構(gòu)建詞嵌入時,最簡單的方法之一就是用平均法構(gòu)建baseline句子嵌入模型。
一個baseline句子嵌入模型可以通過平均每個句子的單個詞嵌入(有點類似于我們失去了句子中固有的語境和單詞序列的bag of words)來建立。下圖顯示了實現(xiàn)此功能的方法。
當(dāng)然,還有一些更復(fù)雜的方法,比如對句子中的詞嵌入表示進(jìn)行線性加權(quán)組合。
Doc2Vec也是 mikolov 等人提出的一種非常流行的方法。他們提出了段落向量,這是一種無監(jiān)督的算法,它從可變長度的文本 (如句子、段落和文檔) 中學(xué)習(xí)固定長度的特征嵌入。
Word2Vec vs. Doc2Vec (Source:https://arxiv.org/abs/1405.4053)
在上述描述的基礎(chǔ)上,該模型用一個稠密向量表示每個文檔,該向量訓(xùn)練用于預(yù)測文檔中的單詞,唯一的區(qū)別是使用段落或文檔id與常規(guī)單詞tokens一起構(gòu)建嵌入表示。這樣的設(shè)計使這種模型克服了詞袋模型的缺點。
神經(jīng)網(wǎng)絡(luò)語言模型(NNLM)是 Bengio 等人在2003年提出的。他們討論學(xué)習(xí)單詞的分布式表示,允許每個訓(xùn)練句子向模型提供關(guān)于語義相鄰句子的信息。該模型同時學(xué)習(xí)每個單詞的分布式表示,同時學(xué)習(xí)詞序列的概率函數(shù),并以這些形式表示出來。泛化是因為一個以前從未見過的單詞序列,如果它是由類似于構(gòu)成一個已經(jīng)出現(xiàn)過的句子的單詞構(gòu)成的詞構(gòu)成的,那么它就具有很高的概率。
Google已經(jīng)建立了一個通用的句子嵌入模型nnlm-en-dim128[3],這是一種基于標(biāo)記的文本嵌入,使用三層前饋神經(jīng)網(wǎng)絡(luò)語言模型在英語google新聞200B語料庫上進(jìn)行訓(xùn)練。該模型將任意文本映射為128維嵌入。我們很快就會在接下來演示中用到這個。
Skip-Thought Vectors也是基于非監(jiān)督學(xué)習(xí)的句子編碼器領(lǐng)域中最早的模型之一。在他們提議的論文中,利用文本的連續(xù)性,他們訓(xùn)練了一個編碼器-解碼器模型,試圖重建編碼段落的周圍句子。共享語義和句法屬性的句子被映射到類似的向量表示。
Skip-Thought Vectors (Source:https://arxiv.org/abs/1506.06726)
這就像skip-gram模型,但是是針對于句子而言的,即我們試圖預(yù)測給定源句子的周圍句子。
Quick Thought Vectors是最近用來學(xué)習(xí)句子表達(dá)的一種較新的方法。原論文中詳細(xì)介紹了學(xué)習(xí)句子表示的有效框架。有趣的是,他們通過在常規(guī)的編解碼結(jié)構(gòu)中用分類器替換解碼器,把預(yù)測句子出現(xiàn)的上下文的問題重新定義為分類問題。
Quick Thought Vectors (Source:https://openreview.net/forum?id=rJvJXZb0W)
因此,給定一個句子及其出現(xiàn)的上下文,分類器根據(jù)它們的嵌入表示來區(qū)分上下文句子和其他對比句子。給定一個輸入語句,它首先使用某種函數(shù)進(jìn)行編碼,但是模型沒有生成目標(biāo)句子,而是從一組候選句子中選擇正確的目標(biāo)句子。將生成看作是從所有可能的句子中選擇一個句子,這可以看作是對生成問題的一種判別近似。
InferSet是一種基于自然語言推理數(shù)據(jù)學(xué)習(xí)通用句子嵌入的有監(jiān)督學(xué)習(xí)方法。這是硬核監(jiān)督遷移學(xué)習(xí),就像我們在ImageNet數(shù)據(jù)集上接受計算機視覺訓(xùn)練一樣,他們使用斯坦福自然語言推理數(shù)據(jù)集的監(jiān)督數(shù)據(jù)來訓(xùn)練通用句子表示。該模型使用的數(shù)據(jù)集是由570 k人工生成的英語句子對組成的SNLI數(shù)據(jù)集,它捕捉到了理解句子語義的自然語言推理。
InferSent training scheme (Source:https://arxiv.org/abs/1705.02364)
基于上圖所描述的體系結(jié)構(gòu),我們可以看到,它使用了一個共享語句編碼器,它為前提u和假設(shè)V輸出一個表示。一旦生成句子向量,就可以使用3種匹配方法來提取u和v之間的關(guān)系:
Concatenation (u, v)
Element-wise product u ? v
Absolute element-wise difference |u ? v|
生成的向量隨后被輸入由多個全連接的層組成的三分類器。
Google的通用句子編碼器Universal Sentence Encoder是最新的、最好的通用句子嵌入模型之一,于2018年初發(fā)布。通用句子編碼器將任意文本編碼成512維嵌入,可用于各種NLP任務(wù),包括文本分類、語義相似性和聚類。它針對各種數(shù)據(jù)源和各種任務(wù)進(jìn)行訓(xùn)練,目的是動態(tài)地容納各種各樣的自然語言理解任務(wù),這些任務(wù)需要對單詞序列的含義進(jìn)行建模,而不僅僅是單個單詞。他們的主要發(fā)現(xiàn)是,使用句子嵌入的遷移學(xué)習(xí)往往優(yōu)于詞嵌入級別的遷移學(xué)習(xí)。
理解我們的文本分類問題
現(xiàn)在是時候把這些通用的句子編碼器付諸行動了,接下來我們進(jìn)行演示。我們今天演示集中于一個非常流行的NLP任務(wù),即在情感分析的背景下對文本進(jìn)行分類。下文演示中所用的數(shù)據(jù)集可以在[4]或[5]中下載。
這個數(shù)據(jù)集共有50000部電影評論,其中25k有正面情緒,25k有負(fù)面情緒。我們將在總共30000次評論上訓(xùn)練我們的模型,在5000個評論上進(jìn)行交叉驗證,并使用15000次評論作為我們的測試數(shù)據(jù)集。主要目的是正確預(yù)測每一次評價的積極或消極情緒。
通用句子嵌入in action
現(xiàn)在我們已經(jīng)明確了我們的主要目標(biāo),讓我們把通用的句子編碼器付諸行動!我的設(shè)置是一個8CPU,30 GB,250 GB的SSD和一個Nvidia Quadro P4000。
加載包
我們從安裝tensorflow-hub開始,它使我們能夠輕松地使用這些句子編碼器。
Ok,接下來加載本教程要用到的模塊:
importtensorflowastfimporttensorflow_hubashubimportnumpyasnpimportpandasaspd
下面的命令幫助你檢查TensorFlow是否將使用GPU(如果您已經(jīng)設(shè)置了一個GPU):
In [12]: tf.test.is_gpu_available()Out[12]: TrueIn [13]: tf.test.gpu_device_name()Out[13]: '/device:GPU:0'
加載和查看數(shù)據(jù)集
我們現(xiàn)在可以加載數(shù)據(jù)集并使用pandas查看它。
我們將情感表示的列編碼為1和0。
我們的電影評論數(shù)據(jù)集
構(gòu)建訓(xùn)練、驗證和測試數(shù)據(jù)集
在開始建模之前,我們將創(chuàng)建訓(xùn)練、驗證和測試數(shù)據(jù)集。我們將使用30000條評論用于訓(xùn)練,5000條用于驗證,15000條用于測試。你可以使用train_test_split() from scikit-learn。我只是很懶,用簡單的列表切片對數(shù)據(jù)集進(jìn)行了細(xì)分。
((30000,), (5000,), (15000,))
基本文本處理
我們有一些基本的文本預(yù)處理需要做,以從我們的文本消除一些噪音,如不必要的特殊字符,html標(biāo)簽的清除等。
下面的代碼幫助我們構(gòu)建一個簡單而有效的文本系統(tǒng)。
現(xiàn)在讓我們使用上面實現(xiàn)的函數(shù)對數(shù)據(jù)集進(jìn)行預(yù)處理。
構(gòu)建數(shù)據(jù)攝取函數(shù)
由于我們將使用tf.estimator API在TensorFlow中實現(xiàn)我們的模型,因此我們需要定義一些函數(shù)來構(gòu)建數(shù)據(jù)和特性工程pipline,以便在訓(xùn)練期間將數(shù)據(jù)輸入到我們的模型中。我們利用numpy_put_fn(),這有助于將大量的numpy數(shù)組輸入到模型中。
我們現(xiàn)在已經(jīng)準(zhǔn)備好建立我們的模型了!
用通用句子編碼器建立深度學(xué)習(xí)模型
在建立模型之前,首先要定義利用通用句子編碼器的語句嵌入特征。我們可以使用下面的代碼來實現(xiàn)這一點。
INFO:tensorflow:Using /tmp/tfhub_modules tocache modules.
我們將建立一個簡單只有兩個隱層的前饋DNN,現(xiàn)在只是一個標(biāo)準(zhǔn)的模型,沒有太復(fù)雜,因為我們想看看這些嵌入在一個簡單的模型上執(zhí)行得有多好。在這里,我們正在利用預(yù)訓(xùn)練嵌入形式的遷移學(xué)習(xí)方法。
模型訓(xùn)練
在我們的驗證數(shù)據(jù)集上,我們獲得了接近87%的總體精度,在這樣一個簡單的模型上,AUC達(dá)到了94%,這是相當(dāng)好的!
模型評估
現(xiàn)在,讓我們評估我們的模型在訓(xùn)練和測試數(shù)據(jù)集上的總體性能。
我們在測試數(shù)據(jù)上獲得了接近87%的總體準(zhǔn)確率,與我們之前在驗證數(shù)據(jù)集上觀察到的結(jié)果一致。因此,這應(yīng)該讓你了解利用經(jīng)過預(yù)訓(xùn)練的通用語句嵌入是多么容易,而不必?fù)?dān)心特征工程或復(fù)雜建模的麻煩。
獎勵:不同通用句子嵌入的遷移學(xué)習(xí)
現(xiàn)在讓我們嘗試根據(jù)不同的句子嵌入構(gòu)建不同的深度學(xué)習(xí)分類器。我們將嘗試以下幾點:
NNLM-128
USE-512
我們還將在這里討論兩種最突出的遷移學(xué)習(xí)方法:
使用freezed預(yù)訓(xùn)練語句嵌入建立模型
建立一個模型,在這個模型中,我們微調(diào)并更新訓(xùn)練期間預(yù)先訓(xùn)練過的句子嵌入
我們現(xiàn)在可以使用上述定義的方法來訓(xùn)練我們的模型。
我在上面的輸出中描述了重要的評估指標(biāo),可以看到,我們的模型得到了一些好的結(jié)果。下表以一種很好的方式總結(jié)了這些比較結(jié)果。
對比不同的通用句子編碼器
看起來像谷歌的通用句子編碼器微調(diào)給我們的測試數(shù)據(jù)最好的結(jié)果。讓我們加載這個保存的模型并對測試數(shù)據(jù)進(jìn)行評估。
[0, 1, 0, 1, 1, 0, 1, 1, 1, 1]
評估模型性能的最佳方法之一是以混淆矩陣的形式可視化模型預(yù)測。
從我們最好的模型預(yù)測中的混淆矩陣
我們也可以輸出其他重要的指標(biāo)包括準(zhǔn)確率,召回率和F1。
我們獲得了一個整體模型的準(zhǔn)確性和F1-分?jǐn)?shù)90%的測試數(shù)據(jù),很好。
結(jié)論
對于不同的NLP任務(wù),通用句子嵌入無疑是在支持遷移學(xué)習(xí)方面向前邁出的一大步。事實上,我們已經(jīng)看到像ELMo這樣的模型,通用句子編碼器,ULMFiT確實成為頭條新聞,因為它展示了預(yù)先訓(xùn)練過的模型可以用來在NLP任務(wù)上實現(xiàn)最先進(jìn)的結(jié)果。著名的研究科學(xué)家和博客作者塞巴斯蒂安·魯?shù)?SebastianRuder)在推特上提到了同樣的問題。
我對NLP的進(jìn)一步推廣和使我們能夠輕松地解決復(fù)雜任務(wù)的未來感到非常興奮!
-
深度學(xué)習(xí)
+關(guān)注
關(guān)注
73文章
5561瀏覽量
122799 -
nlp
+關(guān)注
關(guān)注
1文章
490瀏覽量
22625
原文標(biāo)題:自然語言處理中的深度遷移學(xué)習(xí)——文本預(yù)訓(xùn)練
文章出處:【微信號:CAAI-1981,微信公眾號:中國人工智能學(xué)會】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
python自然語言
語義理解和研究資源是自然語言處理的兩大難題
什么是人工智能、機器學(xué)習(xí)、深度學(xué)習(xí)和自然語言處理?
從語言學(xué)到深度學(xué)習(xí)NLP,一文概述自然語言處理
閑談深度學(xué)習(xí)在自然語言處理領(lǐng)域的5大關(guān)鍵優(yōu)勢
深入機器學(xué)習(xí)之自然語言處理
面向自然語言處理的神經(jīng)網(wǎng)絡(luò)遷移學(xué)習(xí)的答辯PPT
斯坦福AI Lab主任、NLP大師Manning:將深度學(xué)習(xí)應(yīng)用于自然語言處理領(lǐng)域的領(lǐng)軍者
基于深度學(xué)習(xí)的自然語言處理對抗樣本模型

評論