【NLP】語言模型和遷移學習

10.13 Update:最近新出了一個state-of-the-art預訓練模型,傳送門:

李入魔:【NLP】Google BERT詳解?zhuanlan.zhihu.com

1. 簡介

長期以來,詞向量一直是NLP任務中的主要表征技術。隨著2017年底以及2018年初的一系列技術突破,研究證實預訓練的語言表征經過精調后可以在眾多NLP任務中達到更好的表現。目前預訓練有兩種方法:

  1. Feature-based:將訓練出的representation作為feature用于任務,從詞向量、句向量、段向量、文本向量都是這樣的。新的ELMo也屬于這類,但遷移后需要重新計算出輸入的表征。
  2. Fine-tuning:這個主要借鑒于CV,就是在預訓練好的模型上加些針對任務的層,再對后幾層進行精調。新的ULMFit和OpenAI GPT屬于這一類。

本文主要對ELMo、ULMFiT以及OpenAI GPT三種預訓練語言模型作簡要介紹。

2. ELMo

2.1 模型原理與架構

原文鏈接:Deep contextualized word representations

ELMo是從雙向語言模型(BiLM)中提取出的Embedding。訓練時使用BiLSTM,給定N個tokens (t1, t2,...,tN), 目標為最大化:

ELMo對于每個token , 通過一個L層的biLM計算出2L+1個表示:

其中 是對token進行直接編碼的結果(這里是字符通過CNN編碼), 是每個biLSTM層輸出的結果。

應用中將ELMo中所有層的輸出R壓縮為單個向量, , 最簡單的壓縮方法是取最上層的結果做為token的表示: , 更通用的做法是通過一些參數來聯合所有層的信息:

其中 是softmax出來的權重, 是一個任務相關的scale參數,在優化過程中很重要,同時因為每層BiLM的輸出分布不同, 可以對層起到normalisation的作用。

論文中使用的預訓練BiLM在Jozefowicz et al.中的CNN-BIG-LSTM基礎上做了修改,最終模型為2層biLSTM(4096 units, 512 dimension projections),并在第一層和第二層之間增加了殘差連接。同時使用CNN和兩層Highway對token進行字符級的上下文無關編碼。使得模型最終對每個token輸出三層向量表示。

2.2 模型訓練注意事項

- 正則化

1. Dropout

2. 在loss中添加權重的懲罰項 (實驗結果顯示ELMo適合較小的 )

- TF版源碼解析

1. 模型架構的代碼主要在training模塊的LanguageModel類中,分為兩步:第一步創建word或character的Embedding層(CNN+Highway);第二步創建BiLSTM層。

2. 加載所需的預訓練模型為model模塊中的BidirectionalLanguageModel類。

2.3 模型的使用

  1. 將ELMo向量 與傳統的詞向量 拼接成 后,輸入到對應具體任務的RNN中。
  2. 將ELMo向量放到模型輸出部分,與具體任務RNN輸出的 拼接成 。
  3. Keras代碼示例
import tensorflow as tf
from keras import backend as K
import keras.layers as layers
from keras.models import Model# Initialize session
sess = tf.Session()
K.set_session(sess)# Instantiate the elmo model
elmo_model = hub.Module("https://tfhub.dev/google/elmo/1", trainable=True)
sess.run(tf.global_variables_initializer())
sess.run(tf.tables_initializer())# We create a function to integrate the tensorflow model with a Keras model
# This requires explicitly casting the tensor to a string, because of a Keras quirk
def ElmoEmbedding(x):return elmo_model(tf.squeeze(tf.cast(x, tf.string)), signature="default", as_dict=True)["default"]input_text = layers.Input(shape=(1,), dtype=tf.string)
embedding = layers.Lambda(ElmoEmbedding, output_shape=(1024,))(input_text)
dense = layers.Dense(256, activation='relu')(embedding)
pred = layers.Dense(1, activation='sigmoid')(dense)model = Model(inputs=[input_text], outputs=pred)model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
model.summary()復制代碼

2.4 模型的優缺點

優點

  1. 效果好,在大部分任務上都較傳統模型有提升。實驗正式ELMo相比于詞向量,可以更好地捕捉到語法和語義層面的信息。
  2. 傳統的預訓練詞向量只能提供一層表征,而且詞匯量受到限制。ELMo所提供的是character-level的表征,對詞匯量沒有限制。

缺點

速度較慢,對每個token編碼都要通過language model計算得出。

2.5 適用任務

  • Question Answering
  • Textual entailment
  • Semantic role labeling
  • Coreference resolution
  • Named entity extraction
  • Sentiment analysis

3. ULMFiT

3.1 模型原理與架構

原文鏈接:Universal Language Model Fine-tuning for Text Classification

ULMFiT是一種有效的NLP遷移學習方法,核心思想是通過精調預訓練的語言模型完成其他NLP任務。文中所用的語言模型參考了Merity et al. 2017a的AWD-LSTM模型,即沒有attention或shortcut的三層LSTM模型。

ULMFiT的過程分為三步:


1. General-domain LM pre-train

  • 在Wikitext-103上進行語言模型的預訓練。
  • 預訓練的語料要求:large & capture general properties of language
  • 預訓練對小數據集十分有效,之后僅有少量樣本就可以使模型泛化。

2. Target task LM fine-tuning

文中介紹了兩種fine-tuning方法:

  • Discriminative fine-tuning

因為網絡中不同層可以捕獲不同類型的信息,因此在精調時也應該使用不同的learning rate。作者為每一層賦予一個學習率 ,實驗后發現,首先通過精調模型的最后一層L確定學習率 ,再遞推地選擇上一層學習率進行精調的效果最好,遞推公式為:

  • Slanted triangular learning rates (STLR)

為了針對特定任務選擇參數,理想情況下需要在訓練開始時讓參數快速收斂到一個合適的區域,之后進行精調。為了達到這種效果,作者提出STLR方法,即讓LR在訓練初期短暫遞增,在之后下降。如圖b的右上角所示。具體的公式為:

    • T: number of training iterations
    • cut_frac: fraction of iterations we increase the LR
    • cut: the iteration when we switch from increasing to decreasing the LR
    • p: the fraction of the number of iterations we have increased or will decrease the LR respectively
    • ratio: specifies how much smaller the lowest LR is from thr max LR
    • : the LR at iteration t

文中作者使用的

3. Target task classifier fine-tuning

為了完成分類任務的精調,作者在最后一層添加了兩個線性block,每個都有batch-norm和dropout,使用ReLU作為中間層激活函數,最后經過softmax輸出分類的概率分布。最后的精調涉及的環節如下:

  • Concat pooling
    第一個線性層的輸入是最后一個隱層狀態的池化。因為文本分類的關鍵信息可能在文本的任何地方,所以只是用最后時間步的輸出是不夠的。作者將最后時間步 與盡可能多的時間步 池化后拼接起來,以 作為輸入。
  • Gradual unfreezing
    由于過度精調會導致模型遺忘之前預訓練得到的信息,作者提出逐漸unfreez網絡層的方法,從最后一層開始unfreez和精調,由后向前地unfreez并精調所有層。
  • BPTT for Text Classification (BPT3C)
    為了在large documents上進行模型精調,作者將文檔分為固定長度為b的batches,并在每個batch訓練時記錄mean和max池化,梯度會被反向傳播到對最終預測有貢獻的batches。
  • Bidirectional language model
    在作者的實驗中,分別獨立地對前向和后向LM做了精調,并將兩者的預測結果平均。兩者結合后結果有0.5-0.7的提升。

3.2 模型訓練注意事項

- PyTorch版源碼解析 (FastAI第10課)

# location: fastai/lm_rnn.pydef get_language_model(n_tok, emb_sz, n_hid, n_layers, pad_token,dropout=0.4, dropouth=0.3, dropouti=0.5, dropoute=0.1, wdrop=0.5, tie_weights=True, qrnn=False, bias=False):"""Returns a SequentialRNN model.A RNN_Encoder layer is instantiated using the parameters provided.This is followed by the creation of a LinearDecoder layer.Also by default (i.e. tie_weights = True), the embedding matrix used in the RNN_Encoderis used to  instantiate the weights for the LinearDecoder layer.The SequentialRNN layer is the native torch's Sequential wrapper that puts the RNN_Encoder andLinearDecoder layers sequentially in the model.Args:n_tok (int): number of unique vocabulary words (or tokens) in the source datasetemb_sz (int): the embedding size to use to encode each tokenn_hid (int): number of hidden activation per LSTM layern_layers (int): number of LSTM layers to use in the architecturepad_token (int): the int value used for padding text.dropouth (float): dropout to apply to the activations going from one LSTM layer to anotherdropouti (float): dropout to apply to the input layer.dropoute (float): dropout to apply to the embedding layer.wdrop (float): dropout used for a LSTM's internal (or hidden) recurrent weights.tie_weights (bool): decide if the weights of the embedding matrix in the RNN encoder should be tied to theweights of the LinearDecoder layer.qrnn (bool): decide if the model is composed of LSTMS (False) or QRNNs (True).bias (bool): decide if the decoder should have a bias layer or not.Returns:A SequentialRNN model"""rnn_enc = RNN_Encoder(n_tok, emb_sz, n_hid=n_hid, n_layers=n_layers, pad_token=pad_token,dropouth=dropouth, dropouti=dropouti, dropoute=dropoute, wdrop=wdrop, qrnn=qrnn)enc = rnn_enc.encoder if tie_weights else Nonereturn SequentialRNN(rnn_enc, LinearDecoder(n_tok, emb_sz, dropout, tie_encoder=enc, bias=bias))def get_rnn_classifier(bptt, max_seq, n_class, n_tok, emb_sz, n_hid, n_layers, pad_token, layers, drops, bidir=False,dropouth=0.3, dropouti=0.5, dropoute=0.1, wdrop=0.5, qrnn=False):rnn_enc = MultiBatchRNN(bptt, max_seq, n_tok, emb_sz, n_hid, n_layers, pad_token=pad_token, bidir=bidir,dropouth=dropouth, dropouti=dropouti, dropoute=dropoute, wdrop=wdrop, qrnn=qrnn)return SequentialRNN(rnn_enc, PoolingLinearClassifier(layers, drops))復制代碼

3.3 模型的優缺點

優點

對比其他遷移學習方法(ELMo)更適合以下任務:

- 非英語語言,有標簽訓練數據很少

- 沒有state-of-the-art模型的新NLP任務

- 只有部分有標簽數據的任務

缺點

對于分類和序列標注任務比較容易遷移,對于復雜任務(問答等)需要新的精調方法。

3.4 適用任務

  • Classification
  • Sequence labeling

4. OpenAI GPT

4.1 模型原理與架構

原文鏈接:Improving Language Understanding by Generative Pre-Training (未出版)

OpenAI Transformer是一類可遷移到多種NLP任務的,基于Transformer的語言模型。它的基本思想同ULMFiT相同,都是在盡量不改變模型結構的情況下將預訓練的語言模型應用到各種任務。不同的是,OpenAI Transformer主張用Transformer結構,而ULMFiT中使用的是基于RNN的語言模型。文中所用的網絡結構如下:


模型的訓練過程分為兩步:

1. Unsupervised pre-training

第一階段的目標是預訓練語言模型,給定tokens的語料 ,目標函數為最大化似然函數:

該模型中應用multi-headed self-attention,并在之后增加position-wise的前向傳播層,最后輸出一個分布:

2. Supervised fine-tuning

有了預訓練的語言模型之后,對于有標簽的訓練集 ,給定輸入序列 和標簽 ,可以通過語言模型得到 ,經過輸出層后對 進行預測:

則目標函數為:

整個任務的目標函數為:

4.2 模型訓練注意事項

- TF版源碼解析

# location: finetune-transformer-lm/train.pydef model(X, M, Y, train=False, reuse=False):with tf.variable_scope('model', reuse=reuse):# n_special=3,作者把數據集分為三份# n_ctx 應該是 n_contextwe = tf.get_variable("we", [n_vocab+n_special+n_ctx, n_embd], initializer=tf.random_normal_initializer(stddev=0.02))we = dropout(we, embd_pdrop, train)X = tf.reshape(X, [-1, n_ctx, 2])M = tf.reshape(M, [-1, n_ctx])# 1. Embeddingh = embed(X, we)# 2. transformer blockfor layer in range(n_layer):h = block(h, 'h%d'%layer, train=train, scale=True)# 3. 計算語言模型losslm_h = tf.reshape(h[:, :-1], [-1, n_embd])lm_logits = tf.matmul(lm_h, we, transpose_b=True)lm_losses = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=lm_logits, labels=tf.reshape(X[:, 1:, 0], [-1]))lm_losses = tf.reshape(lm_losses, [shape_list(X)[0], shape_list(X)[1]-1])lm_losses = tf.reduce_sum(lm_losses*M[:, 1:], 1)/tf.reduce_sum(M[:, 1:], 1)# 4. 計算classifier lossclf_h = tf.reshape(h, [-1, n_embd])pool_idx = tf.cast(tf.argmax(tf.cast(tf.equal(X[:, :, 0], clf_token), tf.float32), 1), tf.int32)clf_h = tf.gather(clf_h, tf.range(shape_list(X)[0], dtype=tf.int32)*n_ctx+pool_idx)clf_h = tf.reshape(clf_h, [-1, 2, n_embd])if train and clf_pdrop > 0:shape = shape_list(clf_h)shape[1] = 1clf_h = tf.nn.dropout(clf_h, 1-clf_pdrop, shape)clf_h = tf.reshape(clf_h, [-1, n_embd])clf_logits = clf(clf_h, 1, train=train)clf_logits = tf.reshape(clf_logits, [-1, 2])clf_losses = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=clf_logits, labels=Y)return clf_logits, clf_losses, lm_losses復制代碼

4.3 模型的優缺點

優點

  1. 循環神經網絡所捕捉到的信息較少,而Transformer可以捕捉到更長范圍的信息。
  2. 計算速度比循環神經網絡更快,易于并行化
  3. 實驗結果顯示Transformer的效果比ELMo和LSTM網絡更好

缺點

對于某些類型的任務需要對輸入數據的結構作調整

4.4 適用任務

  • Natural Language Inference
  • Question Answering and commonsense reasoning
  • Classification
  • Semantic Similarity

5. 總結

從Wrod Embedding到OpenAI Transformer,NLP中的遷移學習從最初使用word2vec、GLoVe進行字詞的向量表示,到ELMo可以提供前幾層的權重共享,再到ULMFiT和OpenAI Transformer的整個預訓練模型的精調,大大提高了NLP基本任務的效果。同時,多項研究也表明,以語言模型作為預訓練模型,不僅可以捕捉到文字間的語法信息,更可以捕捉到語義信息,為后續的網絡層提供高層次的抽象信息。另外,基于Transformer的模型在一些方面也展現出了優于RNN模型的效果。

最后,關于具體任務還是要進行多種嘗試,可以使用以上方法做出模型baseline,再調整網絡結構提升效果。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/389054.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/389054.shtml
英文地址,請注明出處:http://en.pswp.cn/news/389054.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

TCPIP傳送協議

以下代碼實現在客戶端查詢成績(數據庫在服務器端): 客戶端: static void Main(string[] args) { string str null; while (str ! Convert.ToString(0)) { Console.WriteLine("…

sql優化技巧_使用這些查詢優化技巧成為SQL向導

sql優化技巧成為SQL向導! (Become an SQL Wizard!) It turns out storing data by rows and columns is convenient in a lot of situations, so relational databases have remained a cornerstone of data management in businesses across the globe. Structured…

Day 4:集合——迭代器與List接口

Collection-迭代方法 1、toArray() 返回Object類型數據,接收也需要Object對象! Object[] toArray(); Collection c new ArrayList(); Object[] arr c.toArray(); 2、iterator() Collection的方法,返回實現Iterator接口的對象,…

oem是代工還是貼牌_代加工和貼牌加工的區別是什么

展開全部代加工就是替別人加工,貼別人的牌子。貼牌加工即商家自己不生產,而是委托其他生產企e68a8462616964757a686964616f31333365663431業生產,而品牌是自己的。拓展資料:OEM(Original Equipment Manufacture)的基本含義是定牌生…

KNN 算法--圖像分類算法

KNN 算法–圖像分類算法 找到最近的K個鄰居,在前k個最近樣本中選擇最近的占比最高的類別作為預測類別。 給定測試對象,計算它與訓練集中每個對象的距離。圈定距離最近的k個訓練對象,作為測試對象的鄰居。根據這k個緊鄰對象所屬的類別&#xf…

java核心技術-NIO

1、reactor(反應器)模式 使用單線程模擬多線程,提高資源利用率和程序的效率,增加系統吞吐量。下面例子比較形象的說明了什么是反應器模式: 一個老板經營一個飯店, 傳統模式 - 來一個客人安排一個服務員招呼…

物種分布模型_減少物種分布建模中的空間自相關

物種分布模型Species distribution models (SDM; for review and definition see, e.g., Peterson et al., 2011) are a dominant paradigm to quantify the relationship between environmental dynamics and several manifestations of species biogeography. These statisti…

BZOJ1014: [JSOI2008]火星人prefix

BZOJ1014: [JSOI2008]火星人prefix Description 火星人最近研究了一種操作:求一個字串兩個后綴的公共前綴。 比方說,有這樣一個字符串:madamimadam,我們將這個字符串的各個字符予以標號: 序號: 1 2 3 4 5 6…

redis將散裂中某個值自增_這些Redis命令你都掌握了沒?

本章主要內容字符串命令、列表命令和集合命令散列命令和有序集合命令發布命令與訂閱命令其他命令本章將介紹一些沒有在第1章和第2章出現過的Redis命令,學習這些命令有助于讀者在已有示例的基礎上構建更為復雜的程序,并學會如何更好地去解決自己遇到的問題…

asp.net的MessageBox

public class MessageBox{ public enum MsgButton { /// <summary> /// 只是OK按鈕 /// </summary> OK 1, /// <summary> /// 提示是否確定 /// </summary> OKCancel 2 } publ…

深入理解激活函數

為什么需要非線性激活函數&#xff1f; 說起神經網絡肯定會降到神經函數&#xff0c;看了很多資料&#xff0c;也許你對激活函數這個名詞會感覺很困惑&#xff0c; 它為什么叫激活函數&#xff1f;它有什么作用呢&#xff1f; 看了很多書籍上的講解說會讓神經網絡變成很豐富的…

如何一鍵部署項目、代碼自動更新

為什么80%的碼農都做不了架構師&#xff1f;>>> 摘要&#xff1a;my-deploy:由nodejs寫的一個自動更新工具,理論支持所有語言(php、java、c#)的項目,支持所有git倉庫(bitbucket、github等)。github效果如何?如果你的后端項目放在github、bitbucket等git倉庫中管理…

Kettle7.1在window啟動報錯

實驗環境&#xff1a; window10 x64 kettle7.1 pdi-ce-7.1.0.0-12.zip 錯誤現象&#xff1a; a java exception has occurred 問題解決&#xff1a; 運行調試工具 data-integration\SpoonDebug.bat //調試錯誤的&#xff0c;根據錯誤明確知道為何啟動不了&#xff0c;Y--Y-…

opa847方波放大電路_電子管放大電路當中陰極電阻的作用和選擇

膽機制作知識視頻&#xff1a;6P14單端膽機用示波器方波測試輸出波形詳細步驟演示完整版自制膽機試聽視頻&#xff1a;膽機播放《猛士的士高》經典舞曲 熟悉的旋律震撼的效果首先看下面這一張300B電子管電路圖&#xff1a;300B單端膽機原理圖圖紙里面畫圓圈的電阻就是放大電路當…

鍵盤鉤子

C#鍵盤鉤子//*************************鍵盤鉤子********************** //定義變量 public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam); static int hKeyboardHook 0; HookProc KeyboardHookProcedure; /************************* * 聲明API函數 * ***…

matplotlib基礎函數函數 plot, figure

matplotlib.pyplot.plot(*args, scalexTrue, scaleyTrue,dataNone,**kwargs) 用線段和標記去繪制x和y。調用簽名&#xff1a; plot([x], y, [fmt], *, dataNone, **kwargs) plot([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs)點或線的坐標由x, y給出 操作參數 fmt 是為了…

清潔數據ploy n_清潔屋數據

清潔數據ploy nAs a bootcamp project, I was asked to analyze data about the sale prices of houses in King County, Washington, in 2014 and 2015. The dataset is well known to students of data science because it lends itself to linear regression modeling. You …

redis安裝redis集群

NoSql數據庫之Redis1、什么是nosql&#xff0c;nosql的應用場景2、Nonsql數據庫的類型a) Key-valueb) 文檔型&#xff08;類似于json&#xff09;c) 列式存儲d) 圖式3、redis的相關概念kv型的。4、Redis的安裝及部署5、Redis的使用方法及數據類型a) Redis啟動及關閉b) Redis的數…

聯想拯救者y7000p加內存條_內存、硬盤不夠用?手把手教你升級聯想拯救者Y7000P...

由于這兩年內存價格的高企&#xff0c;主流筆記本的內存容量被鎖定在 8GB 已經有了相當長的時間。作為近幾個月最熱門的游戲本產品&#xff0c;聯想拯救者 Y7000P 除頂配之外同樣使用的是 8GB 內存和 512GB 固態硬盤的配置。所以買到這款機器的玩家多數都會選擇進行內存和硬盤的…

機器學習實踐一 logistic regression regularize

Logistic regression 數據內容&#xff1a; 兩個參數 x1 x2 y值 0 或 1 Potting def read_file(file):data pd.read_csv(file, names[exam1, exam2, admitted])data np.array(data)return datadef plot_data(X, y):plt.figure(figsize(6, 4), dpi150)X1 X[y 1, :]X2 X[…