作爲近些年來深度學習的兩個應用思路,預訓練和模型微調爲後面的任務提供了良好的基礎。所以,我們先來介紹一下預訓練和模型微調的概念。
我們從一個例子開始,假設我們接到的是一個文本分類的任務,需要對數據集A中的文本進行文本分類,我們的首先要做的是對於A中的文本進行分詞,生成詞向量。然後採用某一個深度學習的模型。訓練分類的參數。現在,我們將目光聚焦在詞向量生成的過程中,假設我們同時有一個超大的文本數據集B,B中的文檔的數量要遠遠大於A中文檔的數量,換句話說,如果我們採用某一種詞向量的計算方法對數據集A和數據集B中的詞彙計算詞向量,那麼由B生成的某個詞的詞向量所蘊含的特徵信息要比由A生成的相同詞所蘊含的特徵信息要高很多,因爲B中的詞能夠綜合更多的文本特徵信息。那麼很自然的,我們就可以想到,我們可以利用B中的詞彙來訓練詞向量,然後利用這些詞向量完成對於A的文本分類任務。我們用一個圖來展示這個過程:
如果你對遷移學習有一些基本的瞭解,那你一定會明白,這不就是遷移學習嘛,沒錯,所謂的預訓練過程,實際上就是遷移學習的一種形式,我們通過一個特別大的訓練集來訓練一些參數,詞向量等等,然後利用生成的參數或者詞向量來完成下游的任務,我們將上游預訓練參數,詞向量等等的過程稱爲預訓練過程。比較著名的預訓練模型就是我們接下來將會介紹的ELMO模型等等。
上面我們介紹了預訓練的概念,我們接着上面的例子,假設我們從B中通過預訓練獲得了一組參數W,然後利用這組參數來對於A中的文本進行分類,這裏有一個小問題,雖然我們通過大量的文本獲得了參數組W,但是這組參數能夠完全契合我們的數據集A嗎?換句話來說,假設我們的樣本集B是維基百科中的全部文本集,數據集A爲一個關於醫療的文本集合,那麼我們從維基百科文本中獲得的參數可以完全擬合醫療文本嗎?這顯然是不行的,因爲對於醫療文本而言,其本身具有的一些文本特性。例如醫學名稱,藥物名詞等等這些都是和其他類型的文本是不同的,所以,我們不能直接使用參數W,但是由於W是基於大規模文本來的,所以我們只需要在參數W的基礎上進行一些調整,使其能夠更加的滿足我們醫療文本的特徵就可以了,這個調整的過程被稱爲fine-tunning。
總結一下,所謂的模型微調,是指我們在大規模數據中獲得了參數W,爲了能更好的使用小規模數據的特性,我們對參數W進行稍微的調整,而不是重新的進行訓練。這樣,我們可節省大量的訓練時間,同時還能夠從大規模的數據中獲得有用的特徵,同時還不會影響到我們對於小規模數據的特徵計算。fine-tuning中比較知名的模型是Bert,我們會在之後的文章中進行講解。
在瞭解了模型的預訓練和模型的微調的過程之後,我們首先來介紹一個經典的預訓練模型——ELMO。我們之前多次講述過,在NLP任務中,最爲基礎,同時也最爲重要的過程就是詞向量的獲取,而對於詞向量的獲取,目前來看,大多數的模型都是使用到了語言模型的思想,這種思想的核心在於利用前面的n-1個詞來預測當前的第n個詞,也就是:
這種利用前面詞彙的形式,在深度學習中,我們有一類很好的模型可以對其進行模擬,那就是RNN類的深度學習模型。進一步,爲了解決語言模型中只考慮前面的詞侷限性,我們可以使用雙向的RNN類模型來同時綜合上下文環境。而ELMO就是基於上面描述的這些點的一個預訓練模型。下面我們來具體介紹一下。
在深度學習中,RNN類模型在基於序列建模的任務上有着很好的擬合情況,同時也產生的非常好的效果。我們首先來回顧一下RNN類模型的基本架構和其中最爲經典的LSTM模型。
這是一個RNN的總體結構圖,對於RNN類的模型而言,其輸入包括兩種,第一種基於當前時刻的輸入X,第二種是基於前一個時刻的狀態來作爲輸入,通過一個權重,模型可以決定這兩個部分在當前時刻的佔比,然後在融合之前的信息和當前信息的基礎上產生當前時刻的輸出。其基本的計算公式爲:
其中W和U都是用來調節佔比的權重矩陣,b表示偏置項。f表示激活函數。
這種機制存在存在以下兩個問題:
爲了解決上面所提出來的問題,於是就提出了對於簡單的RNN改進的一種算法——LSTM。
首先,我們給出LSTM的基本結構:
可以看出,在整體結構上,LSTM的依舊使用了RNN的基本結構,但是爲了解決我們上面提到的問題,LSTM在每一個時刻的單元內部做出一些改進。
首先,LSTM中採用了不同的門控方式,對於最左側的門控,我們稱其爲遺忘門,其主要的作用是用於判斷從前一個時刻傳遞過來的信息。其基本的計算公式如下:
中間的門控被稱爲輸入門,用於控制輸入信息:
最右側的門被稱爲輸出門,用於控制輸出信息:
同時,我們在維護一個負責控制當前輸入的候選細胞狀態,由這個候選狀態來控制輸入門結果的輸入:
然後我們更新細胞狀態爲:
最後產生隱狀態輸出:
通過LSTM的各個門控結構,儘量降低了梯度爆炸或者梯度消失的可能性,同時儘量解決了長距離依賴的問題。由於我們只是對於LSTM進行回顧,有興趣的讀者可以仔細的去對LSTM進行深入的瞭解。
老規矩,我們也先給出ELMO的模型結構,在進行具體的敘述:
在上面的結構中,我們可以看到,採用的是雙層雙向的LSTM得結構,我們首先來分析第一層的雙向LSTM結構。
對於前向的LSTM中的第t個時刻而言,由於其模擬的是語言模型,那麼也就是說,第t個時刻的輸出爲:
所以,對於整個序列的輸出有:
同理對於後向的LSTM而言,其計算結果就是:
綜上所述,對於第一層的BI-LSTM,我們可以綜合前向和後向的兩個LSTM得到輸出的似然函數爲:
其中三個θ表示的輸入X的參數,lstm的參數和softmax參數。參數的意義我的最後會提到
如果瞭解了第一層的BI-LSTM,那麼下面的就很好理解了,我們上第一層BI-LSTM的每個時刻的輸出作爲下一層的BI-LSTM的每個時刻的輸入,在將第一層的BI-LSTM的計算過程重複一遍即可。可能有的讀者會有一些疑惑,簡單的複製這個過程的意義在哪裏?這裏我們可以這樣理解,從輸入到第一層的BI-LSTM,是建立在詞彙級別的特徵抽取,第二層的BI-LSTM的是站在句法級別的特徵抽取。
最終,我們可以獲得整個模型的極大似然函數爲:
這裏我們需要對參數進行一下解釋,對於第一個參數 ,其表示的是從輸入到第一層LSTM的相關參數, 分別表示雙向的LSTM中的參數(兩層的LSTM參數是不共享的,但是某一層中的單元對於LSTM是共享的), 表示詞彙softmax的參數,也就是我們要預測輸出的參數。
對於EMLO而言,如果我們調節LSTM有L層,那麼我們根據前向後向以及最初的輸入,可以得到對於每一個詞彙有2L+1個詞向量。有下面的公式表示就是:
這樣,我們就確定了最終的每一個詞彙的表示。
對於ELMO模型最簡單的使用方式是單獨使用整個模型最終的輸出,而不去考慮其他的層的輸出和最開始的輸入:
但是爲了更多的特徵信息,我們通常也會綜合其所有的輸出信息,這個時候將不同層的輸出進行拼接,在通過參數對維度進行調節,以及γ的縮放和s的正則化調節。
如果我們通過預訓練的方式獲得了ELMO中的參數,那麼當我們想要獲得某一個詞的向量的時候,這種詞向量的形式是否固定呢?答案是否定的,由於LSTM的形式,我們每次的輸入一個句子,那麼在獲取輸出的時候,LSTM的網絡結構會考慮單詞的不同的上下文信息,換句話來說,當詞彙處於不同的上下文中,那麼其獲得上下文信息是不同的,那麼其輸出也就是不同的。這也就是ELMO能夠產生動態詞向量的原因。在產生動態詞向量之後,就可以去完成下游的不同任務了。
作爲一種經典的預訓練模型,ELMO的整體思想是很簡單的,同時也可以看出語言模型在NLP中的重要性。其動態,基於語境的詞向量生成方式,爲下游的任務帶來了很多的便捷。