1、背景java
天然語言處理就是要讓計算機理解人類的語言,至於到目前爲止,計算機是否真的理解的人類的語言,這是一個未知之數,個人理解是目前爲止並無懂得人類語言,只是查表給出一個最大機率的迴應而已。那麼天然語言處理(NLP)包括哪些領域的東西呢?文本分類(如:垃圾郵件分類、情感分析)、機器翻譯、摘要、文法分析、分詞、詞性標註、實體識別(NER)、語音識別等等,都是NLP要解的問題。那麼這些解了這些問題,計算機是否真的懂得人類語言的含義,如今還未知,本片文章不過多的展開討論。語言的單位是詞,那麼計算機是如何來表示詞的,用什麼技術來表示一個詞,就可讓計算機理解詞的含義呢?本篇博客將進行詳細的討論,從bool模型,到向量空間模型、到各類word embedding(word2vec、elmo、GPT、BERT)網絡
2、原始時代函數
在Deeplearning以前,表示一個詞,並無一個約定俗成的辦法,如何表示,取決於想解決的任務。學習
一、Bool模型ui
下面有兩句話,求文本類似度。google
我喜歡張國榮編碼
你喜歡劉德華spa
那麼,布爾模型比較簡單粗暴,出現了詞所在維度爲1,沒出現的所在維度爲0,以下圖:翻譯
而後求兩個向量的cosine便可。3d
在bool模型中,因爲特徵值只有1和0兩個取值,不能很好的反應特徵項在文本中的重要程度。
二、VSM(向量空間模型)
Bool模型其實能夠看作是VSM的特例,只不過VSM每一個維度填進去的值是用了一些特殊的規則處理罷了,VSM以下圖:
t表示特徵項,d表示一個Document,那麼D可表示爲D={t1,t2,t3……tN}的N維向量,w的值怎麼填呢?只好的作法是TF*IDF,TF表示詞頻、IDF表示反詞頻,公式以下:
TF(t)=特徵詞在文檔中出現次數/文檔總詞數
IDF(t)=log(N/(n+1)),其中N爲文本集文本總數,n爲包含特徵詞t的文檔數量
固然TF*IDF也有他的缺陷,忽略了類中分佈狀況和忽略了類間分佈狀況,那麼也有一些改進,例如:TF*IDF*IG,IG表示信息增益。
這些詞/文檔的表示方法,很是機械,反映不出詞與詞之間的上下文之間的關係、類似的關係等等。
3、深度學習時代
首先不得不提語言模型,語言模型在估測一個句子出現的機率,機率越大,越合理。
P(w1,w2,w3,……wn)=P(w1)*P(w2|w1)*P(w3|w1,w2)...P(wn|w1,w2....wn-1)
一般上面的式子沒辦法估測,因而會作一個馬爾科夫假設,假設後面的詞只和前面的一個詞有關,那麼就簡化爲下面的式子:
P(w1,w2,w3,……wn)=P(w1)*P(w2|w1)*P(w3|w2)...P(wn|wn-1)
固然也能夠假設後面的詞和前面的N個詞有關,這就是常說的N-gram。語言模型在elmo和gpt中有大用處。
一、word2vec
word2vec,實際上是一個單隱層的神經網絡,的思想很簡單,請看下圖
上圖中李雷和韓梅梅,都跟着「在教室」這個詞,當向神經網絡輸入李雷或者韓梅梅,但願神經網絡output「在教室」這個詞的概率越高越好,那麼神經網絡的權重進行調節,把兩個不一樣的詞映射到了相同的空間,那麼說明李雷和韓梅梅存在某種聯繫,這就是word2vec的思想。word2vec有兩種,cbow和skip-gram,cbow是由上下文推出一個詞,skip-gram是由一個詞推出上下文,以下圖所示。我實踐的結果是cbow效果要更好一點。
這個代碼怎麼實現呢?其實本身實現一個單隱層的神經網絡就搞定了,output層激活函數爲softmax,用cross entropy Loss,梯度降低便可。事實上,咱們徹底不用這麼麻煩,DL4J已經提供了全套解決方案,幾行代碼就搞定了,代碼以下:
Word2Vec vec = new Word2Vec.Builder() .minWordFrequency(5) .iterations(1) .layerSize(100) .seed(42) .windowSize(5) .iterate(iter) .tokenizerFactory(t) .build(); vec.fit();
二、ELMO
ELMO取至Embeddings from Language Model的首寫字母,論文地址:https://arxiv.org/abs/1802.05365
Embeddings 是從語言模型中獲得的。在講ELMO以前,先來講說word2vec有什麼問題,word2vec當然能夠表示詞與詞之間的語義以及相互之間的關係,可是word2vec是一個徹底靜態的,也就是把全部信息都壓縮到一個固定維度的向量裏。那麼對於一詞多意,是表現力是比較有限的。請看下面的例子,
在 「欲信大義於天下」中 ,「信」是動詞,「伸張」的意思
在 「信義著於四海"中,「信」是名詞,「信用」的意思
若是「信」字壓縮成一個100維的向量,將很難區分這兩種意思的差異,那麼這就須要Contextualized Word Embedding,根據不一樣的語境,對詞進行編碼,因而ELMO來了。
EMLO的結構很簡單,用了雙向的LSTM來訓練一個語言模型。以下圖(圖片來至於臺大李宏毅的ppt)
模型training的過程很簡單,讀入一個詞,一詞下一個詞,反向讀一個詞,預測上一個詞,以此訓練下去,直到收斂。中間紅框處的藍色和橙色的向量就是Embedding的向量,最後接起來就是咱們所要的向量了,固然這個bi-lstm也能夠疊不少層。每一層都獲得一個Embedding向量。
那麼,使用的時候怎麼用這個編碼值呢?這取決於下游任務,比方說能夠把每一層的Embedding向量求和取平均,或者加權求和等等,這個權重能夠跟着任務一塊兒train出來。
三、GPT
ELMO實現了對word進行動態編碼,可是他用了LSTM,LSTM並不能記住很長的信息,且不利於並行計算。GPT用self attention改變這一結果,固然這一切得益於google神做《Attention Is All You Need》論文地址:https://arxiv.org/pdf/1706.03762.pdf
GPT是怎麼樣的運做流程呢?其實就是用self attention訓練一個語言模型,請看下圖:
每一個詞之和前面的詞作attention,預測下一個詞,例如讀入開始標記BOS,而後本身和本身作attention,預測「潮水」,讀入BOS、潮水,而後和BOS、潮水作attention,預測「退了」,類推下去,直到結束。在不少語料上train下去,就獲得了一個很是強大的語言模型,能夠動態的進行編碼。使用的時候能夠固定住這些attention層的參數,而後訓練其餘的下游任務,例如作情感分類問題,能夠把這些attention層放在幾個全鏈接層前面,固定參數,只訓練後面的全鏈接層,經過softmax或者sigmoid進行分類。
四、Bidirectional Encoder Representations from Transformers (BERT)
GPT有個缺陷,就是編碼只依賴上文信息,沒有加入下文信息,那麼BERT很好的解決了這個問題。BERT實際上是transformer的encoder部分,以下圖
train BERT有兩種方法,Masked LM和Next Sentence Prediction,Masked LM是隨機掩蓋住一些詞,讓BERT猜想蓋住的詞什麼。Next Sentence Prediction是讓BERT推斷兩個句子是否是有上下文關係。
BERT充分考慮了上下文,對word進行編碼,因而很好的體現語義和上下文的關係,在不少比賽中遙遙領先。
4、總結
天然語言處理從原始的布爾模型,到向量空間模型,再到word2vec,再到ELMO,再到GPT,再到BERT,一路走來,技術的更替。目前爲止,BERT依然是比較領先的word Embedding方法,在大部分天然語言處理任務中,做爲預訓練任務,是咱們首先應該嘗試的辦法。也許,用不了多久,又會有新的技術出來,刷新成績,咱們拭目以待。但即使是如今爲止,機器是否真的理解了人類的語言,這仍是一個尚待論證的問題。路漫漫其修遠兮,吾將上下而求索。
快樂源於分享。
此博客乃做者原創, 轉載請註明出處
P(1 ,每