1. 程式人生 > >深度學習筆記——Attention Model(注意力模型)學習總結

深度學習筆記——Attention Model(注意力模型)學習總結

深度學習裡的Attention model其實模擬的是人腦的注意力模型,舉個例子來說,當我們觀賞一幅畫時,雖然我們可以看到整幅畫的全貌,但是在我們深入仔細地觀察時,其實眼睛聚焦的就只有很小的一塊,這個時候人的大腦主要關注在這一小塊圖案上,也就是說這個時候人腦對整幅圖的關注並不是均衡的,是有一定的權重區分的。這就是深度學習裡的Attention Model的核心思想。

AM剛開始也確實是應用在影象領域裡的,AM在影象處理領域取得了非常好的效果!於是,就有人開始研究怎麼將AM模型引入到NLP領域。最有名的當屬“Neural machine translation by jointly learning to align and translate”這篇論文了,這篇論文最早提出了Soft Attention Model,並將其應用到了機器翻譯領域。後續NLP領域使用AM模型的文章一般都會引用這篇文章(目前引用量已經上千了!!!)

如下圖所示,機器翻譯主要使用的是Encoder-Decoder模型,在Encoder-Decoder模型的基礎上引入了AM,取得了不錯的效果:


Soft Attention Model:

這裡其實是上面圖的拆解,我們前面說過,“Neural machine translation by jointly learning to align and translate”這篇論文提出了soft Attention Model,並將其應用到了機器翻譯上面。其實,所謂Soft,意思是在求注意力分配概率分佈的時候,對於輸入句子X中任意一個單詞都給出個概率,是個概率分佈。

即上圖中的ci是對Encoder中每一個單詞都要計算一個注意力概率分佈,然後加權得到的。如下圖所示:


其實有Soft AM,對應也有一個Hard AM。既然Soft是給每個單詞都賦予一個單詞對齊概率,那麼如果不這樣做,直接從輸入句子裡面找到某個特定的單詞,然後把目標句子單詞和這個單詞對齊,而其它輸入句子中的單詞硬性地認為對齊概率為0,這就是Hard Attention Model的思想。Hard AM在影象裡證明有用,但是在文本里面用處不大,因為這種單詞一一對齊明顯要求太高,如果對不齊對後續處理負面影響很大。

但是,斯坦福大學的一篇paper“Effective Approaches to Attention-based Neural Machine Translation”提出了一個混合Soft AM 和Hard AM的模型,論文中,他們提出了兩種模型:Global Attention Model和Local Attention Model,Global Attention Model其實就是Soft Attention Model,Local Attention Model本質上是Soft AM和 Hard AM的一個混合。一般首先預估一個對齊位置Pt,然後在Pt左右大小為D的視窗範圍來取類似於Soft AM的概率分佈。

Global Attention Model和Local Attention Model

Global AM其實就是soft AM,Decoder的過程中,每一個時間步的Context vector需要計算Encoder中每一個單詞的注意力權重,然後加權得到。


Local AM則是首先找到一個對其位置,然後在對其位置左右一個視窗內來計算注意力權重,最終加權得到Context vector。這其實是Soft AM和Hard AM的一個混合折中。

靜態AM

其實還有一種AM叫做靜態AM。所謂靜態AM,其實是指對於一個文件或者句子,計算每個詞的注意力概率分佈,然後加權得到一個向量來代表這個文件或者句子的向量表示。跟soft AM的區別是,soft AM在Decoder的過程中每一次都需要重新對所有詞計算一遍注意力概率分佈,然後加權得到context vector,但是靜態AM只計算一次得到句子的向量表示即可。(這其實是針對於不同的任務而做出的改變)


強制前向AM

Soft AM在逐步生成目標句子單詞的時候,是由前向後逐步生成的,但是每個單詞在求輸入句子單詞對齊模型時,並沒有什麼特殊要求。強制前向AM則增加了約束條件:要求在生成目標句子單詞時,如果某個輸入句子單詞已經和輸出單詞對齊了,那麼後面基本不太考慮再用它了,因為輸入和輸出都是逐步往前走的,所以看上去類似於強制對齊規則在往前走。

看了這麼多AM模型以及變種,那麼我們來看一看AM模型具體怎麼實現,涉及的公式都是怎樣的。

我們知道,注意力機制是在序列到序列模型中用於注意編碼器狀態的最常用方法,它同時還可用於回顧序列模型的過去狀態。使用注意力機制,系統能基於隱藏狀態 s_1,...,s_m 而獲得環境向量(context vector)c_i,這些環境向量可以和當前的隱藏狀態 h_i 一起實現預測。環境向量 c_i 可以由前面狀態的加權平均數得出,其中狀態所加的權就是注意力權重 a_i:


注意力函式 f_att(h_i,s_j) 計算的是目前的隱藏狀態 h_i 和前面的隱藏狀態 s_j 之間的非歸一化分配值。

而實際上,注意力函式也有很多種變體。接下來我們將討論四種注意力變體:加性注意力(additive attention)、乘法(點積)注意力(multiplicative attention)、自注意力(self-attention)和關鍵值注意力(key-value attention)。

加性注意力(additive attention)

加性注意力是最經典的注意力機制 (Bahdanau et al., 2015) [15],它使用了有一個隱藏層的前饋網路(全連線)來計算注意力的分配:


也就是:

乘法(點積)注意力(multiplicative attention)

乘法注意力(Multiplicative attention)(Luong et al., 2015) [16] 通過計算以下函式而簡化了注意力操作:


加性注意力和乘法注意力在複雜度上是相似的,但是乘法注意力在實踐中往往要更快速、具有更高效的儲存,因為它可以使用矩陣操作更高效地實現。兩個變體在低維度 d_h 解碼器狀態中效能相似,但加性注意力機制在更高的維度上效能更優。

自注意力(self-attention)

注意力機制不僅能用來處理編碼器或前面的隱藏層,它同樣還能用來獲得其他特徵的分佈,例如閱讀理解任務中作為文字的詞嵌入 (Kadlec et al., 2017) [37]。然而,注意力機制並不直接適用於分類任務,因為這些任務並不需要情感分析(sentiment analysis)等額外的資訊。在這些模型中,通常我們使用 LSTM 的最終隱藏狀態或像最大池化和平均池化那樣的聚合函式來表徵句子。

自注意力機制(Self-attention)通常也不會使用其他額外的資訊,但是它能使用自注意力關注本身進而從句子中抽取相關資訊 (Lin et al., 2017) [18]。自注意力又稱作內部注意力,它在很多工上都有十分出色的表現,比如閱讀理解 (Cheng et al., 2016) [38]、文字繼承 (textual entailment/Parikh et al., 2016) [39]、自動文字摘要 (Paulus et al., 2017) [40]。


關鍵值注意力(key-value attention)

關鍵值注意力 (Daniluk et al., 2017) [19] 是最近出現的注意力變體機制,它將形式和函式分開,從而為注意力計算保持分離的向量。它同樣在多種文字建模任務 (Liu & Lapata, 2017) [41] 中發揮了很大的作用。具體來說,關鍵值注意力將每一個隱藏向量 h_i 分離為一個鍵值 k_i 和一個向量 v_i:[k_i;v_i]=h_i。鍵值使用加性注意力來計算注意力分佈 a_i:


其中 L 為注意力窗體的長度,I 為所有單元為 1 的向量。然後使用注意力分佈值可以求得環境表徵 c_i:


其中環境向量 c_i 將聯合現階段的狀態值 v_i 進行預測。

最後的最後,再加一個自己用keras實現的簡單的靜態AM(自注意力)層的程式碼吧:

from keras import backend as K
from keras.engine.topology import Layer
from keras import initializers, regularizers, constraints

class Attention_layer(Layer):
    """
        Attention operation, with a context/query vector, for temporal data.
        Supports Masking.
        Follows the work of Yang et al. [https://www.cs.cmu.edu/~diyiy/docs/naacl16.pdf]
        "Hierarchical Attention Networks for Document Classification"
        by using a context vector to assist the attention
        # Input shape
            3D tensor with shape: `(samples, steps, features)`.
        # Output shape
            2D tensor with shape: `(samples, features)`.
        :param kwargs:
        Just put it on top of an RNN Layer (GRU/LSTM/SimpleRNN) with return_sequences=True.
        The dimensions are inferred based on the output shape of the RNN.
        Example:
            model.add(LSTM(64, return_sequences=True))
            model.add(AttentionWithContext())
        """

    def __init__(self,
                 W_regularizer=None, b_regularizer=None,
                 W_constraint=None, b_constraint=None,
                 bias=True, **kwargs):

        self.supports_masking = True
        self.init = initializers.get('glorot_uniform')

        self.W_regularizer = regularizers.get(W_regularizer)
        self.b_regularizer = regularizers.get(b_regularizer)

        self.W_constraint = constraints.get(W_constraint)
        self.b_constraint = constraints.get(b_constraint)

        self.bias = bias
        super(Attention_layer, self).__init__(**kwargs)

    def build(self, input_shape):
        assert len(input_shape) == 3

        self.W = self.add_weight((input_shape[-1], input_shape[-1],),
                                 initializer=self.init,
                                 name='{}_W'.format(self.name),
                                 regularizer=self.W_regularizer,
                                 constraint=self.W_constraint)
        if self.bias:
            self.b = self.add_weight((input_shape[-1],),
                                     initializer='zero',
                                     name='{}_b'.format(self.name),
                                     regularizer=self.b_regularizer,
                                     constraint=self.b_constraint)

        super(Attention_layer, self).build(input_shape)

    def compute_mask(self, input, input_mask=None):
        # do not pass the mask to the next layers
        return None

    def call(self, x, mask=None):
        uit = K.dot(x, self.W)

        if self.bias:
            uit += self.b

        uit = K.tanh(uit)

        a = K.exp(uit)

        # apply mask after the exp. will be re-normalized next
        if mask is not None:
            # Cast the mask to floatX to avoid float64 upcasting in theano
            a *= K.cast(mask, K.floatx())

        # in some cases especially in the early stages of training the sum may be almost zero
        # and this results in NaN's. A workaround is to add a very small positive number to the sum.
        # a /= K.cast(K.sum(a, axis=1, keepdims=True), K.floatx())
        a /= K.cast(K.sum(a, axis=1, keepdims=True) + K.epsilon(), K.floatx())
        print a
        # a = K.expand_dims(a)
        print x
        weighted_input = x * a
        print weighted_input
        return K.sum(weighted_input, axis=1)

    def compute_output_shape(self, input_shape):
        return (input_shape[0], input_shape[-1])


相關推薦

深度學習筆記——Attention Model注意力模型學習總結

深度學習裡的Attention model其實模擬的是人腦的注意力模型,舉個例子來說,當我們觀賞一幅畫時,雖然我們可以看到整幅畫的全貌,但是在我們深入仔細地觀察時,其實眼睛聚焦的就只有很小的一塊,這個時候人的大腦主要關注在這一小塊圖案上,也就是說這個時候人腦對整幅圖的關注並

STL學習筆記— —無序容器Unordered Container

ring 最大 布局 size fad oca rgs template max 簡單介紹 在頭文件<unordered_set>和<unordered_map> 中定義 namespace std { templa

CSS Box Model盒子模型

圖片 clas 添加 wid 分享 borde html model com CSS Box Model(盒子模型) 一、簡介 所有HTML元素可以看作盒子,在CSS中,"box model"這一術語是用來設計和布局時使用。 CSS盒模型本質上是一個盒子,封裝周圍的HTML

機器學習筆記——線性迴歸Linear Regression

線性迴歸演算法 1 簡單線性迴歸(Simple Liner Regression) 解決迴歸問題 思想簡答,容易實現 許多強大的非線性模型的基礎 結果具有很好的可解釋性 蘊含機器學習中的很多重要思想 1.1 什麼是線性迴歸演算法?

機器學習筆記——梯度下降Gradient Descent

梯度下降演算法(Gradient Descent) 在所有的機器學習演算法中,並不是每一個演算法都能像之前的線性迴歸演算法一樣直接通過數學推導就可以得到一個具體的計算公式,而再更多的時候我們是通過基於搜尋的方式來求得最優解的,這也是梯度下降法所存在的意義。 不是一個機器學習演

go學習筆記-面向物件Methods, Interfaces

面向物件(Methods, Interfaces) Method method是附屬在一個給定的型別上的,他的語法和函式的宣告語法幾乎一樣,只是在func後面增加了一個receiver(也就是method所依從的主體)。 語法 func (r ReceiverType) funcName(param

go學習筆記-型別轉換Type Conversion

型別轉換(Type Conversion) 型別轉換用於將一種資料型別的變數轉換為另外一種型別的變,基本格式 type_name(expression) type_name 為型別,expression 為表示式。 示例 func testCov() { var a = 20 var

機器學習筆記——logistic迴歸logistic regression

logistic迴歸 logistic迴歸實際上並不是一種迴歸演算法,而是一種分類演算法,意思就是輸出值是離散值(01或者更多類),而它叫這個名字完全是歷史原因。我們可以從下圖看出對於分類問題,如果我們採用傳統的迴歸演算法並不能獲得很好的效果 假設稱述 由於輸出的值是0和1,因此我

Nginx學習筆記——geoip模組地域資訊

概述 基於IP地址匹配MaxMind GeoIP二進位制檔案,讀取IP所在地域資訊。 安裝模組 yum install nginx-module-geoip 使用場景 (1)區別國內外作HTTP的訪問規

《Oracle PL/SQL例項精講》學習筆記11——異常 高階概念

本章介紹瞭如下內容: 1. RAISE_APPLICATION_ERROR “在我們寫proc程式中經常要有錯誤處理,在錯誤處理中我們經常要輸出錯誤資訊來給幫助我們分析和解決錯誤原因,從而更正資料。這時候就會用到SQLCODE和SQLERRM. SQLCode:資

Unix網路程式設計學習筆記課後題Chapter 6

6.1 在/usr/include/x86_64-linux-gnu/sys/select.h中檢視fd_set的定義 /* fd_set for select and pselect. */ typedef struct { /* XPG4.2 requires this

Unix網路程式設計學習筆記課後題Chapter 4

4.1 如何辨別<netinet/in.h>中定義的INADDR_是主機序還是網路序。 less /usr/include/netinet/in.h 可以發現是按小端序儲存的,Linux的主機序就是小端序。 還有個想法,可以用htonl()去轉換,看結果是不是相等。

Unix網路程式設計學習筆記課後題Chapter 3

3.1 因為不同型別的套接字長度不同。IPV4和IPV6套接字長度固定,但Unix域結構和資料鏈路結構是可變長度的,需要一個引數記錄結果的大小,直接傳就是值傳遞了,需要傳一個指標,以實現引用傳遞。 3.2 void指標只能用來傳引數,不能對void型別指標加減和解引用 3.3 匆匆忙

機器學習筆記——梯度下降Gradient D

梯度下降演算法(Gradient Descent) 在所有的機器學習演算法中,並不是每一個演算法都能像之前的線性迴歸演算法一樣直接通過數學推導就可以得到一個具體的計算公式,而再更多的時候我們是通過基於搜尋的方式來求得最優解的,這也是梯度下降法所存在的意義。 不

《Oracle PL/SQL例項精講》學習筆記17——記錄第二部分

本章內容: 1. 記錄型別(使用基於表和基於遊標的記錄,使用使用者定義的記錄,瞭解記錄的相容性) 2. 巢狀記錄(即,包含其他記錄和集合的記錄) 3. 記錄集合 程式碼如下: 1. 使用巢

我的python自動化學習筆記-第一篇介面測試

學習的介面測試工具postman、jmeter 在介面測試之前,我們要獲得介面文件。介面文件會告訴我們: url 請求方式 請求引數 引數的說明 url即要訪問的連結、地址 請求方式指。。。有直接向伺服器獲取資料的請求方式(get)。有的要輸入一些資料,才能向伺服器獲取資料(post),

SM9學習筆記與圖解合集

1. 整體架構 整體架構分三層(如圖1): l  介面層:提供對外介面以完成SM9功能。主要分為: n  系統介面:主要完成KGC參與的工作。 n  功能介面:主要完成KGC不參與的工作。 l  SM9功能層:提供SM9的功能模組。主要分成: n  主金鑰生成:

Spring學習筆記——Spring Scope作用域詳解

引言 在Spring學習筆記 —— 從IOC說起中,曾經提到過Spring中的Bean是根據Scope(作用域)來生成的,但是一直都沒有詳細解釋過,除了Singleton(單例)和prototype(原型)作用域之外,另外一種重要的作用域——使用者自定義

機器學習筆記——推薦系統recommender system

推薦系統 我們在平時最常見的就是某個網站給你推薦廣告,豆瓣給你推薦電影,網易雲給你推薦你喜歡的歌,這種系統我們統一稱作推薦系統 基於內容的推薦 我們舉一個電影打分的例子 我們可以為某一部電影選定特徵,不同人對不同的特徵有不同的偏愛特性,藉此我們可以預測某個人對某部特定電影的打分

機器學習筆記——異常檢測anomaly detection

異常檢測 當我們需要讓一個系統從許多未標註的資料中學習到某些正常的特徵,從而能夠診斷出非正常的資料,我們把這個過程叫做異常檢測 我們要做的就是對於給定的一組特徵值,我們輸出一個概率,如果這個概率值小於某個臨界值,代表資料異常 演算法 我們可以採用高斯函式來擬合這個概率值,