久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
    分享

    一文讀懂BERT(原理篇)...

     sidneyz1 2021-05-28

    一文讀懂BERT(原理篇)

    2018年的10月11日,Google發布的論文《Pre-training of Deep Bidirectional Transformers for Language Understanding》,成功在 11 項 NLP 任務中取得 state of the art 的結果,贏得自然語言處理學界的一片贊譽之聲。

    本文是對近期關于BERT論文、相關文章、代碼進行學習后的知識梳理,僅為自己學習交流之用。因筆者精力有限,如果文中因引用了某些文章觀點未標出處還望作者海涵,也希望各位一起學習的讀者對文中不恰當的地方進行批評指正。

    1)資源梳理

    • BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding

    • 論文原文:
      BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding

    • 官方代碼和預訓練模型
      Github: https://github.com/google-research/bert

    • Google AI Blog:
      Open Sourcing BERT: State-of-the-Art Pre-training for Natural Language Processing

    • 第三方代碼

      1. pytorch-pretrained-BERT
        Google官方推薦的PyTorch BERB版本實現,可加載Google預訓練的模型:PyTorch version of Google AI’s BERT model with script to load Google’s pre-trained models

      2. BERT-pytorch
        另一個Pytorch版本實現:Google AI 2018 BERT pytorch implementation

      3. BERT-tensorflow
        Tensorflow版本:BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding

      4. bert-chainer
        Chanier版本: Chainer implementation of “BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding”

      5. bert-as-service
        將不同長度的句子用BERT預訓練模型編碼,映射到一個固定長度的向量上:Mapping a variable-length sentence to a fixed-length vector using pretrained BERT model
        進一步是否可以做一個句子相似度計算服務?有沒有同學一試?

      6. bert_language_understanding
        BERT實戰:Pre-training of Deep Bidirectional Transformers for Language Understanding: pre-train TextCNN

      7. sentiment_analysis_fine_grain
        BERT實戰,多標簽文本分類,在 AI Challenger 2018 細粒度情感分析任務上的嘗試:Multi-label Classification with BERT; Fine Grained Sentiment Analysis from AI challenger

      8. BERT-NER
        BERT實戰,命名實體識別: Use google BERT to do CoNLL-2003 NER !

      9. BERT-keras
        Keras版: Keras implementation of BERT with pre-trained weights

      10. tbert
        PyTorch port of BERT ML model

    2)NLP發展史

    關于NLP發展史,特別推薦weizier大佬的NLP的巨人肩膀。學術性和文學性都很棒,縱覽NLP近幾年的重要發展,對各算法如數家珍,深入淺出,思路清晰,文不加點,一氣呵成。
    現對NLP發展脈絡簡要梳理如下:
    在這里插入圖片描述

    • 2001 - Neural language models(神經語言模型)
    • 2008 - Multi-task learning(多任務學習)
    • 2013 - Word embeddings(詞嵌入)
    • 2013 - Neural networks for NLP(NLP神經網絡)
    • 2014 - Sequence-to-sequence models
    • 2015 - Attention(注意力機制)
    • 2015 - Memory-based networks(基于記憶的網絡)
    • 2018 - Pretrained language models(預訓練語言模型)

    2001 - 神經語言模型

    第一個神經語言模型是Bengio等人在2001年提出的前饋神經網絡,如圖所示:
    在這里插入圖片描述這個模型將從表C中查找到的n個單詞作為輸入向量表征。這種向量被現在的學者們稱做“詞嵌入”。這些詞嵌入級聯后被輸入到一個隱藏層中,該隱藏層的輸出又被輸入到softmax層。更多關于模型的信息

    語言建模通常是應用RNN時的第一步,是一種非監督學習形式。盡管它很簡單,但卻是本文后面討論的許多技術發展的核心:

    • 詞嵌入:word2vec 的目標是簡化語言建模。

    • sequence-to-sequence 模型:這種模型通過一次預測一個單詞生成一個輸出序列。

    • 預訓練語言模型:這些方法使用來自語言模型的表述進行遷移學習。

    反過來講,這意味著近年來 NLP 的許多重要進展都可以歸結為某些形式的語言建模。為了“真正”理解自然語言,僅僅從文本的原始形式中學習是不夠的。我們需要新的方法和模型。

    2008- 多任務學習

    多任務學習是在多個任務上訓練的模型之間共享參數的一種通用方法。在神經網絡中,可以通過給不同層施以不同的權重,來很容易地實現多任務學習。多任務學習的概念最初由Rich Caruana 在1993年提出,并被應用于道路跟蹤和肺炎預測(Caruana,1998)。直觀地說,多任務學習鼓勵模型學習對許多任務有用的表述。這對于學習一般的、低級的表述形式、集中模型的注意力或在訓練數據有限的環境中特別有用。詳情請看這篇文章

    在2008年,Collobert 和 Weston 將多任務學習首次應用于 NLP 的神經網絡。在他們的模型中,查詢表(或單詞嵌入矩陣)在兩個接受不同任務訓練的模型之間共享,如下面的圖所示。
    在這里插入圖片描述

    2013- 詞嵌入

    用稀疏向量表示文本,即所謂的詞袋模型在 NLP 有著悠久的歷史。正如上文中介紹的,早在 2001年就開始使用密集向量表示詞或詞嵌入。Mikolov等人在2013年提出的創新技術是通過去除隱藏層,逼近目標,進而使這些單詞嵌入的訓練更加高效。雖然這些技術變更本質上很簡單,但它們與高效的word2vec配合使用,便能使大規模的詞嵌入訓練成為可能。

    Word2vec有兩種風格,如下面的圖所示:連續字袋 CBOW 和 skip-gram。不過他們的目標不同:一個是根據周圍的單詞預測中心單詞,而另一個則相反。
    在這里插入圖片描述雖然這些嵌入在概念上與使用前饋神經網絡學習的嵌入在概念上沒有區別,但是在一個非常大的語料庫上訓練之后,它們就能夠捕獲諸如性別、動詞時態和國家-首都關系等單詞之間的特定關系,如下圖所示。
    !

    2013 - NLP 神經網絡

    2013 年和 2014 年是 NLP 問題開始引入神經網絡模型的時期。使用最廣泛的三種主要的神經網絡是:循環神經網絡、卷積神經網絡和遞歸神經網絡。

    循環神經網絡(RNNs) 循環神經網絡是處理 NLP 中普遍存在的動態輸入序列的一個最佳的技術方案。Vanilla RNNs (Elman,1990)很快被經典的長-短期記憶網絡(Hochreiter & Schmidhuber,1997)所取代,它被證明對消失和爆炸梯度問題更有彈性。在 2013 年之前,RNN 仍被認為很難訓練;Ilya Sutskever 的博士論文為改變這種現狀提供了一個關鍵性的例子。下面的圖對 LSTM 單元進行了可視化顯示。雙向 LSTM(Graves等,2013)通常用于處理左右兩邊的上下文。
    在這里插入圖片描述卷積神經網絡(CNNs) 卷積神經網絡本來是廣泛應用于計算機視覺領域的技術,現在也開始應用于語言(Kalchbrenner等,2014;Kim等,2014)。文本的卷積神經網絡只在兩個維度上工作,其中濾波器(卷積核)只需要沿著時間維度移動。下面的圖顯示了NLP中使用的典型 CNN。
    在這里插入圖片描述卷積神經網絡的一個優點是它們比 RNN 更可并行化,因為其在每個時間步長的狀態只依賴于本地上下文(通過卷積運算),而不是像 RNN 那樣依賴過去所有的狀態。使用膨脹卷積,可以擴大 CNN 的感受野,使網絡有能力捕獲更長的上下文(Kalchbrenner等,2016)。CNN 和 LSTM 可以組合和疊加(Wang等,2016),卷積也可以用來加速 LSTM(Bradbury等, 2017)。

    遞歸神經網絡 RNN 和 CNN 都將語言視為一個序列。然而,從語言學的角度來看,語言本質上是層次化的:單詞被組合成高階短語和從句,這些短語和從句本身可以根據一組生產規則遞歸地組合。將句子視為樹而不是序列的語言學啟發思想產生了遞歸神經網絡(Socher 等人, 2013),如下圖所示
    在這里插入圖片描述遞歸神經網絡從下到上構建序列的表示,這一點不同于從左到右或從右到左處理句子的 RNN。在樹的每個節點上,通過組合子節點的結果來計算新的結果。由于樹也可以被視為在 RNN 上強加不同的處理順序,所以 LSTM 自然地也被擴展到樹上(Tai等,2015)。

    RNN 和 LSTM 可以擴展到使用層次結構。單詞嵌入不僅可以在本地學習,還可以在語法語境中學習(Levy & Goldberg等,2014);語言模型可以基于句法堆棧生成單詞(Dyer等,2016);圖卷積神經網絡可以基于樹結構運行(Bastings等,2017)。

    2014-sequence-to-sequence 模型

    2014 年,Sutskever 等人提出了 sequence-to-sequence 模型。這是一個使用神經網絡將一個序列映射到另一個序列的通用框架。在該框架中,編碼器神經網絡逐符號處理一個句子,并將其壓縮為一個向量表示;然后,一個解碼器神經網絡根據編碼器狀態逐符號輸出預測值,并將之前預測的符號作為每一步的輸入,如下圖所示。
    !
    機器翻譯是對這個框架比較成功的應用。2016 年,谷歌宣布將開始用神經 MT 模型取代基于單片短語的 MT 模型(Wu等,2016)。根據 Jeff Dean 的說法,這意味著用 500 行神經網絡模型替換 50 萬行基于短語的MT代碼。

    由于其靈活性,這個框架現在是自然語言生成任務的首選框架,其中不同的模型承擔了編碼器和解碼器的角色。重要的是,解碼器模型不僅可以解碼一個序列,而且可以解碼任意表征。例如,可以基于圖像生成標題(Vinyals等,2015)(如下圖所示)、基于表生成文本(Lebret等,2016)和基于應用程序中源代碼更改描述(Loyola等,2017)。
    在這里插入圖片描述sequence-to-sequence 學習甚至可以應用于 NLP 中輸出具有特定結構的結構化預測任務。為了簡單起見,輸出被線性化,如下面的圖所示,用于進行選區解析。神經網絡已經證明了在有足夠數量的訓練數據進行選區分析(Vinyals等,2015)和命名實體識別(Gillick等, 2016)的情況下,直接學習可以產生這種線性化輸出的能力。
    在這里插入圖片描述

    2015- 注意力機制

    注意力機制(Bahdanau 等,2015)是神經網絡機器翻譯(NMT)的核心創新之一,也是使 NMT模型勝過經典的基于短語的MT系統的關鍵思想。sequence-to-sequence模型的主要瓶頸是需要將源序列的全部內容壓縮為一個固定大小的向量。注意力機制通過允許解碼器回頭查看源序列隱藏狀態來緩解這一問題,然后將其加權平均作為額外輸入提供給解碼器,如下面的圖所示
    在這里插入圖片描述
    注意力機制有很多不同的形式(Luong等,2015)。這里有一個簡短的概述。注意力機制廣泛適用于任何需要根據輸入的特定部分做出決策的任務,并且效果不錯。它已被應用于一致性解析(Vinyals等,2015)、閱讀理解(Hermann等,2015)和一次性學習(Vinyals等,2016)等諸多領域。輸入甚至不需要是一個序列,即可以包含其他表示,如圖像字幕(Xu等,2015),如下圖所示。注意力機制的一個額外的功能是,它提供了一種少見的功能,我們可以通過檢查輸入的哪些部分與基于注意力權重的特定輸出相關來了解模型的內部工作方式。
    在這里插入圖片描述

    2015 - 基于記憶的網絡

    注意力機制可以看作是模糊記憶的一種形式。記憶由模型的隱藏狀態組成,模型選擇從記憶中檢索內容。研究者們提出了許多具有更明確記憶的模型。這些模型有不同的變體,如神經圖靈機(Graves等,2014)、記憶網絡(Weston等,2015)和端到端記憶網絡(Sukhbaatar等,2015)、動態記憶網絡(Kumar等,2015)、神經微分計算機(Graves等,2016)和循環實體網絡(Henaff等,2017)。

    記憶的訪問通常基于與當前狀態的相似度,類似于注意力,通常可以寫入和讀取。模型在如何實現和利用內存方面有所不同。例如,端到端記憶網絡多次處理輸入,并更新記憶以實現多個推理步驟。神經圖靈機也有一個基于位置的尋址,這允許他們學習簡單的計算機程序,如排序。基于記憶的模型通常應用于一些特定任務中,如語言建模和閱讀理解。在這些任務中,長時間保存信息應該很有用。記憶的概念是非常通用的:知識庫或表可以充當記憶,而記憶也可以根據整個輸入或它的特定部分填充。

    2018 - 預訓練語言模型

    預訓練的詞嵌入與上下文無關,僅用于初始化模型中的第一層。一系列監督型任務被用于神經網絡的預訓練。相反,語言模型只需要無標簽的文本;因此,訓練可以擴展到數十億個tokens, new domains, new languages。預訓練語言模型于 2015 年被首次提出(Dai & Le,2015);直到最近,它們才被證明在各種任務中效果還是不錯的。語言模型嵌入可以作為目標模型中的特征(Peters等,2018),或者使用語言模型對目標任務數據進行微調(Ramachandranden等,2017; Howard & Ruder,2018)。添加語言模型嵌入可以在許多不同的任務中提供比最先進的技術更大的改進,如下面的圖所示。

    在這里插入圖片描述
    預訓練的語言模型已經被證明可以用更少的數據進行學習。由于語言模型只需要無標記的數據,因此對于標記數據稀缺的低資源語言尤其有用。

    其他里程碑事件

    其他一些技術發展沒有上面提到的那樣流行,但仍然有廣泛的影響。

    • 基于字符的表示
      在字符上使用 CNN 或 LSTM 以獲得基于字符的詞表示的做法現在相當普遍,特別是對于形態信息重要或有許多未知單詞的豐富的語言和任務,效果更加明顯。據我所知,序列標簽使用基于字符的表示(Lample 等人,2016;普蘭克等人,2016),可以減輕在計算成本增加的情況下必須處理固定詞匯表的需要,并支持完全基于字符的 NMT (Ling 等人, 2016;Lee 等人,2017)。

    • 對抗學習
      對抗學習方法已經在 ML 領域掀起了風暴,在 NLP 中也有不同形式的應用。對抗性的例子越來越被廣泛使用,它不僅是作為一種工具來探究模型和理解它們的失敗案例,而且也使自身更加魯棒(Jia & Liang, 2017)。(虛擬)對抗性訓練,即最壞情況擾動(Miyato 等人,2017)和領域對抗性損失(Ganin 等人, 2016;Kim 等人,2017),同樣可以使模型更加魯棒。生成對抗網絡(GANs)對于自然語言生成還不是很有效(Semeniuta 等人, 2018),但在匹配分布時很有用(Conneau 等人, 2018)。

    • 強化學習
      強化學習已被證明對具有時間依賴性的任務有效,例如在訓練期間選擇數據(Fang 等人, 2017;Wu 等人, 2018)和建模對話(Liu 等人, 2018)。RL 對于直接優化不可微的末端度量(如 ROUGE 或 BLEU)也有效,反而在匯總中優化替代損失(如交叉熵)(Paulus 等人, 2018;Celikyilmaz 等人,2018)和機器翻譯場景效果就不明顯了(Ranzato 等人,2016)。類似地,逆向強化學習在過于復雜而無法指定數據的情況下也很有用,比看圖說話任務(Wang 等人, 2018)。

    3)BERT:一切過往, 皆為序章

    Attention機制講解

    attention是一種能讓模型對重要信息重點關注并充分學習吸收的技術,它不算是一個完整的模型,應當是一種技術,能夠作用于任何序列模型中。本文較多引用了本篇文章思路,如感興趣可以跳轉學習。

    Seq2Seq

    在開始講解Attention之前,我們先簡單回顧一下Seq2Seq模型,傳統的機器翻譯基本都是基于Seq2Seq模型來做的,該模型分為encoder層與decoder層,并均為RNN或RNN的變體構成,如下圖所示:
    在這里插入圖片描述
    在encode階段,第一個節點輸入一個詞,之后的節點輸入的是下一個詞與前一個節點的hidden state,最終encoder會輸出一個context,這個context又作為decoder的輸入,每經過一個decoder的節點就輸出一個翻譯后的詞,并把decoder的hidden state作為下一層的輸入。該模型對于短文本的翻譯來說效果很好,但是其也存在一定的缺點,如果文本稍長一些,就很容易丟失文本的一些信息,為了解決這個問題,Attention應運而生。

    Attention

    Attention,正如其名,注意力,該模型在decode階段,會選擇最適合當前節點的context作為輸入。Attention與傳統的Seq2Seq模型主要有以下兩點不同。

    1)encoder提供了更多的數據給到decoder,encoder會把所有的節點的hidden state提供給decoder,而不僅僅只是encoder最后一個節點的hidden state。
    在這里插入圖片描述
    2)decoder并不是直接把所有encoder提供的hidden state作為輸入,而是采取一種選擇機制,把最符合當前位置的hidden state選出來,具體的步驟如下

    • 確定哪一個hidden state與當前節點關系最為密切

    • 計算每一個hidden state的分數值(具體怎么計算我們下文講解)

    • 對每個分數值做一個softmax的計算,這能讓相關性高的hidden state的分數值更大,相關性低的hidden state的分數值更低

    這里我們以一個具體的例子來看下其中的詳細計算步驟:
    在這里插入圖片描述
    把每一個encoder節點的hidden states的值與decoder當前節點的上一個節點的hidden state相乘,如上圖,h1、h2、h3分別與當前節點的上一節點的hidden state進行相乘(如果是第一個decoder節點,需要隨機初始化一個hidden state),最后會獲得三個值,這三個值就是上文提到的hidden state的分數,注意,這個數值對于每一個encoder的節點來說是不一樣的,把該分數值進行softmax計算,計算之后的值就是每一個encoder節點的hidden states對于當前節點的權重,把權重與原hidden states相乘并相加,得到的結果即是當前節點的hidden state。可以發現,其實Atttention的關鍵就是計算這個分值。

    明白每一個節點是怎么獲取hidden state之后,接下來就是decoder層的工作原理了,其具體過程如下:

    第一個decoder的節點初始化一個向量,并計算當前節點的hidden state,把該hidden state作為第一個節點的輸入,經過RNN節點后得到一個新的hidden state與輸出值。注意,這里和Seq2Seq有一個很大的區別,Seq2Seq是直接把輸出值作為當前節點的輸出,但是Attention會把該值與hidden state做一個連接,并把連接好的值作為context,并送入一個前饋神經網絡,最終當前節點的輸出內容由該網絡決定,重復以上步驟,直到所有decoder的節點都輸出相應內容。
    在這里插入圖片描述

    Attention模型并不只是盲目地將輸出的第一個單詞與輸入的第一個詞對齊。實際上,它在訓練階段學習了如何在該語言對中對齊單詞(示例中是法語和英語)。Attention函數的本質可以被描述為一個查詢(query)到一系列(鍵key-值value)對的映射。
    在這里插入圖片描述
    在計算attention時主要分為三步,第一步是將query和每個key進行相似度計算得到權重,常用的相似度函數有點積,拼接,感知機等;然后第二步一般是使用一個softmax函數對這些權重進行歸一化;最后將權重和相應的鍵值value進行加權求和得到最后的attention。目前在NLP研究中,key和value常常都是同一個,即key=value。
    在這里插入圖片描述

    Transrofmer模型講解

    接下來我將介紹《Attention is all you need》這篇論文。這篇論文是google機器翻譯團隊在2017年6月放在arXiv上,最后發表在2017年nips上,到目前為止google學術顯示引用量為2203,可見也是受到了大家廣泛關注和應用。這篇論文主要亮點在于
    1)不同于以往主流機器翻譯使用基于RNN的seq2seq模型框架,該論文用attention機制代替了RNN搭建了整個模型框架。
    2)提出了多頭注意力(Multi-headed attention)機制方法,在編碼器和解碼器中大量的使用了多頭自注意力機制(Multi-headed self-attention)。
    3)在WMT2014語料中的英德和英法任務上取得了先進結果,并且訓練速度比主流模型更快。

    《Attention Is All You Need》是一篇Google提出的將Attention思想發揮到極致的論文。這篇論文中提出一個全新的模型,叫 Transformer,拋棄了以往深度學習任務里面使用到的 CNN 和 RNN ,Bert就是基于Transformer構建的,這個模型廣泛應用于NLP領域,例如機器翻譯,問答系統,文本摘要和語音識別等等方向。關于Transrofmer模型的理解特別推薦一位國外博主文章《The Illustrated Transformer》

    Transformer總體結構

    和Attention模型一樣,Transformer模型中也采用了 encoer-decoder 架構。但其結構相比于Attention更加復雜,論文中encoder層由6個encoder堆疊在一起,decoder層也一樣。
    在這里插入圖片描述每一個encoder和decoder的內部簡版結構如下圖
    在這里插入圖片描述
    對于encoder,包含兩層,一個self-attention層和一個前饋神經網絡,self-attention能幫助當前節點不僅僅只關注當前的詞,從而能獲取到上下文的語義。decoder也包含encoder提到的兩層網絡,但是在這兩層中間還有一層attention層,幫助當前節點獲取到當前需要關注的重點內容。

    現在我們知道了模型的主要組件,接下來我們看下模型的內部細節。首先,模型需要對輸入的數據進行一個embedding操作,(也可以理解為類似w2c的操作),enmbedding結束之后,輸入到encoder層,self-attention處理完數據后把數據送給前饋神經網絡,前饋神經網絡的計算可以并行,得到的輸出會輸入到下一個encoder。
    在這里插入圖片描述

    Self-Attention

    接下來我們詳細看一下self-attention,其思想和attention類似,但是self-attention是Transformer用來將其他相關單詞的“理解”轉換成我們正常理解的單詞的一種思路,我們看個例子:
    The animal didn't cross the street because it was too tired
    這里的it到底代表的是animal還是street呢,對于我們來說能很簡單的判斷出來,但是對于機器來說,是很難判斷的,self-attention就能夠讓機器把it和animal聯系起來
    在這里插入圖片描述
    接下來我們看下詳細的處理過程。

    1、首先,self-attention會計算出三個新的向量,在論文中,向量的維度是512維,我們把這三個向量分別稱為Query、Key、Value,這三個向量是用embedding向量與一個矩陣相乘得到的結果,這個矩陣是隨機初始化的,維度為(64,512)注意第二個維度需要和embedding的維度一樣,其值在BP的過程中會一直進行更新,得到的這三個向量的維度是64低于embedding維度的。

    在這里插入圖片描述
    那么Query、Key、Value這三個向量又是什么呢?這三個向量對于attention來說很重要,當你理解了下文后,你將會明白這三個向量扮演者什么的角色。

    2、計算self-attention的分數值,該分數值決定了當我們在某個位置encode一個詞時,對輸入句子的其他部分的關注程度。這個分數值的計算方法是Query與Key做點乘,以下圖為例,首先我們需要針對Thinking這個詞,計算出其他詞對于該詞的一個分數值,首先是針對于自己本身即q1·k1,然后是針對于第二個詞即q1·k2
    在這里插入圖片描述
    3、接下來,把點成的結果除以一個常數,這里我們除以8,這個值一般是采用上文提到的矩陣的第一個維度的開方即64的開方8,當然也可以選擇其他的值,然后把得到的結果做一個softmax的計算。得到的結果即是每個詞對于當前位置的詞的相關性大小,當然,當前位置的詞相關性肯定會會很大
    在這里插入圖片描述
    4、下一步就是把Value和softmax得到的值進行相乘,并相加,得到的結果即是self-attetion在當前節點的值。
    在這里插入圖片描述
    在實際的應用場景,為了提高計算速度,我們采用的是矩陣的方式,直接計算出Query, Key, Value的矩陣,然后把embedding的值與三個矩陣直接相乘,把得到的新矩陣Q與K相乘,乘以一個常數,做softmax操作,最后乘上V矩陣
    在這里插入圖片描述
    在這里插入圖片描述
    這種通過 query 和 key 的相似性程度來確定 value 的權重分布的方法被稱為scaled dot-product attention。其實scaled dot-Product attention就是我們常用的使用點積進行相似度計算的attention,只是多除了一個(為K的維度)起到調節作用,使得內積不至于太大。
    在這里插入圖片描述

    Multi-Headed Attention

    這篇論文更厲害的地方是給self-attention加入了另外一個機制,被稱為“multi-headed” attention,該機制理解起來很簡單,就是說不僅僅只初始化一組Q、K、V的矩陣,而是初始化多組,tranformer是使用了8組,所以最后得到的結果是8個矩陣。
    在這里插入圖片描述
    在這里插入圖片描述
    這給我們留下了一個小的挑戰,前饋神經網絡沒法輸入8個矩陣呀,這該怎么辦呢?所以我們需要一種方式,把8個矩陣降為1個,首先,我們把8個矩陣連在一起,這樣會得到一個大的矩陣,再隨機初始化一個矩陣和這個組合好的矩陣相乘,最后得到一個最終的矩陣。
    在這里插入圖片描述
    這就是multi-headed attention的全部流程了,這里其實已經有很多矩陣了,我們把所有的矩陣放到一張圖內看一下總體的流程。
    在這里插入圖片描述
    多頭attention(Multi-head attention)整個過程可以簡述為:Query,Key,Value首先進過一個線性變換,然后輸入到放縮點積attention(注意這里要做h次,其實也就是所謂的多頭,每一次算一個頭,而且每次Q,K,V進行線性變換的參數W是不一樣的),然后將h次的放縮點積attention結果進行拼接,再進行一次線性變換得到的值作為多頭attention的結果。可以看到,google提出來的多頭attention的不同之處在于進行了h次計算而不僅僅算一次,論文中說到這樣的好處是可以允許模型在不同的表示子空間里學習到相關的信息,后面還會根據attention可視化來驗證。
    在這里插入圖片描述
    那么在整個模型中,是如何使用attention的呢?如下圖,首先在編碼器到解碼器的地方使用了多頭attention進行連接,K,V,Q分別是編碼器的層輸出(這里K=V)和解碼器中都頭attention的輸入。其實就和主流的機器翻譯模型中的attention一樣,利用解碼器和編碼器attention來進行翻譯對齊。然后在編碼器和解碼器中都使用了多頭自注意力self-attention來學習文本的表示。Self-attention即K=V=Q,例如輸入一個句子,那么里面的每個詞都要和該句子中的所有詞進行attention計算。目的是學習句子內部的詞依賴關系,捕獲句子的內部結構。

    在這里插入圖片描述
    對于使用自注意力機制的原因,論文中提到主要從三個方面考慮(每一層的復雜度,是否可以并行,長距離依賴學習),并給出了和RNN,CNN計算復雜度的比較。可以看到,如果輸入序列n小于表示維度d的話,每一層的時間復雜度self-attention是比較有優勢的。當n比較大時,作者也給出了一種解決方案self-attention(restricted)即每個詞不是和所有詞計算attention,而是只與限制的r個詞去計算attention。在并行方面,多頭attention和CNN一樣不依賴于前一時刻的計算,可以很好的并行,優于RNN。在長距離依賴上,由于self-attention是每個詞和所有詞都要計算attention,所以不管他們中間有多長距離,最大的路徑長度也都只是1。可以捕獲長距離依賴關系。
    在這里插入圖片描述
    現在我們已經接觸了attention的header,讓我們重新審視我們之前的例子,看看例句中的“it”這個單詞在不同的attention header情況下會有怎樣不同的關注點(這里不同顏色代表attention不同頭的結果,顏色越深attention值越大)。
    在這里插入圖片描述
    當我們對“it”這個詞進行編碼時,一個注意力的焦點主要集中在“animal”上,而另一個注意力集中在“tired”(兩個heads)
    但是,如果我們將所有注意力添加到圖片中,可能有點難理解:
    在這里插入圖片描述

    Positional Encoding

    到目前為止,transformer模型中還缺少一種解釋輸入序列中單詞順序的方法。為了處理這個問題,transformer給encoder層和decoder層的輸入添加了一個額外的向量Positional Encoding,維度和embedding的維度一樣,這個向量采用了一種很獨特的方法來讓模型學習到這個值,這個向量能決定當前詞的位置,或者說在一個句子中不同的詞之間的距離。這個位置向量的具體計算方法有很多種,論文中的計算方法如下
    在這里插入圖片描述
    其中pos是指當前詞在句子中的位置,i是指向量中每個值的index,可以看出,在偶數位置,使用正弦編碼,在奇數位置,使用余弦編碼。最后把這個Positional Encoding與embedding的值相加,作為輸入送到下一層。
    在這里插入圖片描述
    為了讓模型捕捉到單詞的順序信息,我們添加位置編碼向量信息(POSITIONAL ENCODING),位置編碼向量不需要訓練,它有一個規則的產生方式(上圖公式)。

    如果我們的嵌入維度為4,那么實際上的位置編碼就如下圖所示:
    在這里插入圖片描述
    那么生成位置向量需要遵循怎樣的規則呢?

    觀察下面的圖形,每一行都代表著對一個矢量的位置編碼。因此第一行就是我們輸入序列中第一個字的嵌入向量,每行都包含512個值,每個值介于1和-1之間。我們用顏色來表示1,-1之間的值,這樣方便可視化的方式表現出來:
    在這里插入圖片描述
    這是一個20個字(行)的(512)列位置編碼示例。你會發現它咋中心位置被分為了2半,這是因為左半部分的值是一由一個正弦函數生成的,而右半部分是由另一個函數(余弦)生成。然后將它們連接起來形成每個位置編碼矢量。

    Layer normalization

    在transformer中,每一個子層(self-attetion,ffnn)之后都會接一個殘差模塊,并且有一個Layer normalization
    在這里插入圖片描述
    在進一步探索其內部計算方式,我們可以將上面圖層可視化為下圖:
    在這里插入圖片描述
    殘差模塊相信大家都很清楚了,這里不再講解,主要講解下Layer normalization。Normalization有很多種,但是它們都有一個共同的目的,那就是把輸入轉化成均值為0方差為1的數據。我們在把數據送入激活函數之前進行normalization(歸一化),因為我們不希望輸入數據落在激活函數的飽和區。

    說到 normalization,那就肯定得提到 Batch Normalization。BN的主要思想就是:在每一層的每一批數據上進行歸一化。我們可能會對輸入數據進行歸一化,但是經過該網絡層的作用后,我們的數據已經不再是歸一化的了。隨著這種情況的發展,數據的偏差越來越大,我的反向傳播需要考慮到這些大的偏差,這就迫使我們只能使用較小的學習率來防止梯度消失或者梯度爆炸。

    BN的具體做法就是對每一小批數據,在批這個方向上做歸一化。如下圖所示:
    在這里插入圖片描述
    可以看到,右半邊求均值是沿著數據 batch_size的方向進行的,其計算公式如下:
    在這里插入圖片描述
    那么什么是 Layer normalization 呢?它也是歸一化數據的一種方式,不過 LN 是在每一個樣本上計算均值和方差,而不是BN那種在批方向計算均值和方差!在這里插入圖片描述
    下面看一下 LN 的公式:
    在這里插入圖片描述
    到這里為止就是全部encoders的內容了,如果把兩個encoders疊加在一起就是這樣的結構,在self-attention需要強調的最后一點是其采用了殘差網絡中的short-cut結構,目的是解決深度學習中的退化問題。
    在這里插入圖片描述

    Decoder層

    在這里插入圖片描述
    上圖是transformer的一個詳細結構,相比本文一開始結束的結構圖會更詳細些,接下來,我們會按照這個結構圖講解下decoder部分。

    可以看到decoder部分其實和encoder部分大同小異,不過在最下面額外多了一個masked mutil-head attetion,這里的mask也是transformer一個很關鍵的技術,我們一起來看一下。

    Mask

    mask 表示掩碼,它對某些值進行掩蓋,使其在參數更新時不產生效果。Transformer 模型里面涉及兩種 mask,分別是 padding mask 和 sequence mask。

    其中,padding mask 在所有的 scaled dot-product attention 里面都需要用到,而 sequence mask 只有在 decoder 的 self-attention 里面用到。

    Padding Mask

    什么是 padding mask 呢?因為每個批次輸入序列長度是不一樣的也就是說,我們要對輸入序列進行對齊。具體來說,就是給在較短的序列后面填充 0。但是如果輸入的序列太長,則是截取左邊的內容,把多余的直接舍棄。因為這些填充的位置,其實是沒什么意義的,所以我們的attention機制不應該把注意力放在這些位置上,所以我們需要進行一些處理。

    具體的做法是,把這些位置的值加上一個非常大的負數(負無窮),這樣的話,經過 softmax,這些位置的概率就會接近0!

    而我們的 padding mask 實際上是一個張量,每個值都是一個Boolean,值為 false 的地方就是我們要進行處理的地方。

    Sequence mask

    文章前面也提到,sequence mask 是為了使得 decoder 不能看見未來的信息。也就是對于一個序列,在 time_step 為 t 的時刻,我們的解碼輸出應該只能依賴于 t 時刻之前的輸出,而不能依賴 t 之后的輸出。因此我們需要想一個辦法,把 t 之后的信息給隱藏起來。

    那么具體怎么做呢?也很簡單:產生一個上三角矩陣,上三角的值全為0。把這個矩陣作用在每一個序列上,就可以達到我們的目的。

    • 對于 decoder 的 self-attention,里面使用到的 scaled dot-product attention,同時需要padding mask 和 sequence mask 作為 attn_mask,具體實現就是兩個mask相加作為attn_mask。
    • 其他情況,attn_mask 一律等于 padding mask。

    編碼器通過處理輸入序列啟動。然后將頂部編碼器的輸出轉換為一組注意向量k和v。每個解碼器將在其“encoder-decoder attention”層中使用這些注意向量,這有助于解碼器將注意力集中在輸入序列中的適當位置:
    在這里插入圖片描述
    完成編碼階段后,我們開始解碼階段。解碼階段的每個步驟從輸出序列(本例中為英語翻譯句)輸出一個元素。
    以下步驟重復此過程,一直到達到表示解碼器已完成輸出的符號。每一步的輸出在下一個時間步被送入底部解碼器,解碼器像就像我們對編碼器輸入所做操作那樣,我們將位置編碼嵌入并添加到這些解碼器輸入中,以表示每個字的位置。
    在這里插入圖片描述

    輸出層

    當decoder層全部執行完畢后,怎么把得到的向量映射為我們需要的詞呢,很簡單,只需要在結尾再添加一個全連接層和softmax層,假如我們的詞典是1w個詞,那最終softmax會輸入1w個詞的概率,概率值最大的對應的詞就是我們最終的結果。
    在這里插入圖片描述

    BERT原理詳解

    從創新的角度來看,bert其實并沒有過多的結構方面的創新點,其和GPT一樣均是采用的transformer的結構,相對于GPT來說,其是雙向結構的,而GPT是單向的,如下圖所示
    在這里插入圖片描述
    elmo:將上下文當作特征,但是無監督的語料和我們真實的語料還是有區別的,不一定的符合我們特定的任務,是一種雙向的特征提取。

    openai gpt就做了一個改進,也是通過transformer學習出來一個語言模型,不是固定的,通過任務 finetuning,用transfomer代替elmo的lstm。
    openai gpt其實就是缺少了encoder的transformer。當然也沒了encoder與decoder之間的attention。

    openAI gpt雖然可以進行fine-tuning,但是有些特殊任務與pretraining輸入有出入,單個句子與兩個句子不一致的情況,很難解決,還有就是decoder只能看到前面的信息。
    其次bert在多方面的nlp任務變現來看效果都較好,具備較強的泛化能力,對于特定的任務只需要添加一個輸出層來進行fine-tuning即可。

    結構

    先看下bert的內部結構,官網最開始提供了兩個版本,L表示的是transformer的層數,H表示輸出的維度,A表示mutil-head attention的個數
    在這里插入圖片描述
    如今已經增加了多個模型,中文是其中唯一一個非英語的模型。
    在這里插入圖片描述
    從模型的層數來說其實已經很大了,但是由于transformer的殘差(residual)模塊,層數并不會引起梯度消失等問題,但是并不代表層數越多效果越好,有論點認為低層偏向于語法特征學習,高層偏向于語義特征學習。

    預訓練模型

    首先我們要了解一下什么是預訓練模型,舉個例子,假設我們有大量的維基百科數據,那么我們可以用這部分巨大的數據來訓練一個泛化能力很強的模型,當我們需要在特定場景使用時,例如做文本相似度計算,那么,只需要簡單的修改一些輸出層,再用我們自己的數據進行一個增量訓練,對權重進行一個輕微的調整。

    預訓練的好處在于在特定場景使用時不需要用大量的語料來進行訓練,節約時間效率高效,bert就是這樣的一個泛化能力較強的預訓練模型。

    BERT的預訓練過程

    接下來我們看看BERT的預訓練過程,BERT的預訓練階段包括兩個任務,一個是Masked Language Model,還有一個是Next Sentence Prediction。

    Masked Language Model

    MLM可以理解為完形填空,作者會隨機mask每一個句子中15%的詞,用其上下文來做預測,例如:my dog is hairy → my dog is [MASK]

    此處將hairy進行了mask處理,然后采用非監督學習的方法預測mask位置的詞是什么,但是該方法有一個問題,因為是mask15%的詞,其數量已經很高了,這樣就會導致某些詞在fine-tuning階段從未見過,為了解決這個問題,作者做了如下的處理:

    • 80%的時間是采用[mask],my dog is hairy → my dog is [MASK]

    • 10%的時間是隨機取一個詞來代替mask的詞,my dog is hairy -> my dog is apple

    • 10%的時間保持不變,my dog is hairy -> my dog is hairy

    那么為啥要以一定的概率使用隨機詞呢?這是因為transformer要保持對每個輸入token分布式的表征,否則Transformer很可能會記住這個[MASK]就是"hairy"。至于使用隨機詞帶來的負面影響,文章中解釋說,所有其他的token(即非"hairy"的token)共享15%*10% = 1.5%的概率,其影響是可以忽略不計的。Transformer全局的可視,又增加了信息的獲取,但是不讓模型獲取全量信息。
    注意:

    • 有參數dupe_factor決定數據duplicate的次數。
    • 其中,create_instance_from_document函數,是構造了一個sentence-pair的樣本。對每一句,先生成[CLS]+A+[SEP]+B+[SEP],有長(0.9)有短(0.1),再加上mask,然后做成樣本類object。
    • create_masked_lm_predictions函數返回的tokens是已經被遮擋詞替換之后的tokens
    • masked_lm_labels則是遮擋詞對應位置真實的label。

    Next Sentence Prediction

    選擇一些句子對A與B,其中50%的數據B是A的下一條句子,剩余50%的數據B是語料庫中隨機選擇的,學習其中的相關性,添加這樣的預訓練的目的是目前很多NLP的任務比如QA和NLI都需要理解兩個句子之間的關系,從而能讓預訓練的模型更好的適應這樣的任務。
    個人理解:

    • Bert先是用Mask來提高視野范圍的信息獲取量,增加duplicate再隨機Mask,這樣跟RNN類方法依次訓練預測沒什么區別了除了mask不同位置外;

    • 全局視野極大地降低了學習的難度,然后再用A+B/C來作為樣本,這樣每條樣本都有50%的概率看到一半左右的噪聲;

    • 但直接學習Mask A+B/C是沒法學習的,因為不知道哪些是噪聲,所以又加上next_sentence預測任務,與MLM同時進行訓練,這樣用next來輔助模型對噪聲/非噪聲的辨識,用MLM來完成語義的大部分的學習。
      在這里插入圖片描述

    輸入

    bert的輸入可以是單一的一個句子或者是句子對,實際的輸入值是segment embedding與position embedding相加,具體的操作流程可參考上面的transformer講解。

    BERT的輸入詞向量是三個向量之和:

    Token Embedding:WordPiece tokenization subword詞向量。
    Segment Embedding:表明這個詞屬于哪個句子(NSP需要兩個句子)。
    Position Embedding:學習出來的embedding向量。這與Transformer不同,Transformer中是預先設定好的值。

    在這里插入圖片描述

    總結

    在這里插入圖片描述
    BERT的去除實驗表明,雙向LM和NSP帶了的提升最大。

    在這里插入圖片描述
    另一個結論是,增加模型參數數量可以提升模型效果。

    在這里插入圖片描述
    BERT預訓練模型的輸出結果,無非就是一個或多個向量。下游任務可以通過精調(改變預訓練模型參數)或者特征抽取(不改變預訓練模型參數,只是把預訓練模型的輸出作為特征輸入到下游任務)兩種方式進行使用。BERT原論文使用了精調方式,但也嘗試了特征抽取方式的效果,比如在NER任務上,最好的特征抽取方式只比精調差一點點。但特征抽取方式的好處可以預先計算好所需的向量,存下來就可重復使用,極大提升下游任務模型訓練的速度。
    在這里插入圖片描述
    后來也有其他人針對ELMo和BERT比較了這兩種使用方式的精度差異。下面列出基本結論:

    在這里插入圖片描述
    在這里插入圖片描述
    總結下BERT的主要貢獻:

    • 引入了Masked LM,使用雙向LM做模型預訓練。
    • 為預訓練引入了新目標NSP,它可以學習句子與句子間的關系。
    • 進一步驗證了更大的模型效果更好: 12 --> 24 層。
    • 為下游任務引入了很通用的求解框架,不再為任務做模型定制。
    • 刷新了多項NLP任務的記錄,引爆了NLP無監督預訓練技術。

    BERT是谷歌團隊糅合目前已有的NLP知識集大成者,刷新11條賽道彰顯了無與倫比的實力,且極容易被用于多種NLP任務。宛若一束煙花點亮在所有NLP從業者心中。更為可貴的是谷歌選擇了開源這些,讓所有從業者看到了在各行各業落地的更多可能性。

    BERT優點

    • Transformer Encoder因為有Self-attention機制,因此BERT自帶雙向功能

    • 因為雙向功能以及多層Self-attention機制的影響,使得BERT必須使用Cloze版的語言模型Masked-LM來完成token級別的預訓練

    • 為了獲取比詞更高級別的句子級別的語義表征,BERT加入了Next Sentence Prediction來和Masked-LM一起做聯合訓練

    • 為了適配多任務下的遷移學習,BERT設計了更通用的輸入層和輸出層

    • 微調成本小

    BERT缺點

    • task1的隨機遮擋策略略顯粗獷,推薦閱讀《Data Nosing As Smoothing In Neural Network Language Models》

    • [MASK]標記在實際預測中不會出現,訓練時用過多[MASK]影響模型表現;

    • 每個batch只有15%的token被預測,所以BERT收斂得比left-to-right模型要慢(它們會預測每個token)

    • BERT對硬件資源的消耗巨大(大模型需要16個tpu,歷時四天;更大的模型需要64個tpu,歷時四天。

    關于BERT最新的各領域應用推薦張俊林的Bert時代的創新(應用篇)

    思考

    • 個人并不認為文章是模型的改進,更認可為任務的設計改進。

    • 論文作者只比較了有沒有task1的影響,并沒有針對task2對比試驗。提升是否來自好的預訓練任務設計沒有明說。

    • bert對nlp領域目前已有知識的有效“整合”,在硬件配置足夠的情況下能提高nlp多領域性能

    BERT適用場景

    第一,如果NLP任務偏向在語言本身中就包含答案,而不特別依賴文本外的其它特征,往往應用Bert能夠極大提升應用效果。典型的任務比如QA和閱讀理解,正確答案更偏向對語言的理解程度,理解能力越強,解決得越好,不太依賴語言之外的一些判斷因素,所以效果提升就特別明顯。反過來說,對于某些任務,除了文本類特征外,其它特征也很關鍵,比如搜索的用戶行為/鏈接分析/內容質量等也非常重要,所以Bert的優勢可能就不太容易發揮出來。再比如,推薦系統也是類似的道理,Bert可能只能對于文本內容編碼有幫助,其它的用戶行為類特征,不太容易融入Bert中。

    第二,Bert特別適合解決句子或者段落的匹配類任務。就是說,Bert特別適合用來解決判斷句子關系類問題,這是相對單文本分類任務和序列標注等其它典型NLP任務來說的,很多實驗結果表明了這一點。而其中的原因,我覺得很可能主要有兩個,一個原因是:很可能是因為Bert在預訓練階段增加了Next Sentence Prediction任務,所以能夠在預訓練階段學會一些句間關系的知識,而如果下游任務正好涉及到句間關系判斷,就特別吻合Bert本身的長處,于是效果就特別明顯。第二個可能的原因是:因為Self Attention機制自帶句子A中單詞和句子B中任意單詞的Attention效果,而這種細粒度的匹配對于句子匹配類的任務尤其重要,所以Transformer的本質特性也決定了它特別適合解決這類任務。

    從上面這個Bert的擅長處理句間關系類任務的特性,我們可以繼續推理出以下觀點:

    既然預訓練階段增加了Next Sentence Prediction任務,就能對下游類似性質任務有較好促進作用,那么是否可以繼續在預訓練階段加入其它的新的輔助任務?而這個輔助任務如果具備一定通用性,可能會對一類的下游任務效果有直接促進作用。這也是一個很有意思的探索方向,當然,這種方向因為要動Bert的第一個預訓練階段,所以屬于NLP屆土豪們的工作范疇,窮人們還是散退、旁觀、鼓掌、叫好為妙。

    第三,Bert的適用場景,與NLP任務對深層語義特征的需求程度有關。感覺越是需要深層語義特征的任務,越適合利用Bert來解決;而對有些NLP任務來說,淺層的特征即可解決問題,典型的淺層特征性任務比如分詞,POS詞性標注,NER,文本分類等任務,這種類型的任務,只需要較短的上下文,以及淺層的非語義的特征,貌似就可以較好地解決問題,所以Bert能夠發揮作用的余地就不太大,有點殺雞用牛刀,有力使不出來的感覺。

    這很可能是因為Transformer層深比較深,所以可以逐層捕獲不同層級不同深度的特征。于是,對于需要語義特征的問題和任務,Bert這種深度捕獲各種特征的能力越容易發揮出來,而淺層的任務,比如分詞/文本分類這種任務,也許傳統方法就能解決得比較好,因為任務特性決定了,要解決好它,不太需要深層特征。

    第四,Bert比較適合解決輸入長度不太長的NLP任務,而輸入比較長的任務,典型的比如文檔級別的任務,Bert解決起來可能就不太好。主要原因在于:Transformer的self attention機制因為要對任意兩個單詞做attention計算,所以時間復雜度是n平方,n是輸入的長度。如果輸入長度比較長,Transformer的訓練和推理速度掉得比較厲害,于是,這點約束了Bert的輸入長度不能太長。所以對于輸入長一些的文檔級別的任務,Bert就不容易解決好。結論是:Bert更適合解決句子級別或者段落級別的NLP任務。

    如果有小伙伴堅持看到這里的話深表感謝,本來要繼續寫源碼分析和具體的實踐了。時間關系,等下周再抽時間寫源碼分析與實踐部分吧。本文僅用于筆者自己總結自己BERT學習之路,期間引用很多專家學者的觀點思路,深表感謝。第一次駕馭這么長的技術文章,每個知識點都想寫點,感覺越寫越亂。若有讀者在閱讀本文期間有不好的閱讀體驗深表歉意。

      本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發現有害或侵權內容,請點擊一鍵舉報。
      轉藏 分享 獻花(0

      0條評論

      發表

      請遵守用戶 評論公約

      類似文章 更多

      主站蜘蛛池模板: 丁香五月亚洲综合在线国内自拍| 国产良妇出轨视频在线观看| 国产精品午夜av福利| 成人免费亚洲av在线| 亚州中文字幕一区二区| 四虎永久精品免费视频| 青青草无码免费一二三区| 国产在线午夜不卡精品影院| 日本一区不卡高清更新二区| 人人澡人摸人人添| 亚洲乱码一卡二卡卡3卡4卡| 成A人片亚洲日本久久| 久热这里只有精品12| 亚洲AV成人片不卡无码| 国产白嫩护士在线播放| 精品无码国产一区二区三区51安| 无码精品人妻一区二区三区免费看| 久久国产成人av蜜臀| 丰满爆乳在线播放| 色偷偷www.8888在线观看| 巨胸美乳无码人妻视频漫画| 人人妻人人澡人人爽欧美一区 | AV无码中文字幕不卡一二三区| 国产av无码专区亚洲av软件| 免费网站看V片在线毛| 无码日韩精品一区二区人妻 | 在国产线视频A在线视频| 国产精品久久久久影院| 欧美一本大道香蕉综合视频 | 无码人妻丰满熟妇区毛片18| 中文字幕国产精品二区| 狠狠色噜噜狠狠狠狠AV| 国产对白老熟女正在播放| 无码AV中文字幕久久专区| 亚洲性日韩精品一区二区三区| 色8激情欧美成人久久综合电影| 18禁无遮挡啪啪无码网站破解版| 国产精品免费久久久久影院| 日本免费最新高清不卡视频| 亚洲中文字幕无码中字| 少妇高清精品毛片在线视频|