當前位置:
首頁 > 科技 > 神經網路中的「注意力」是什麼?怎麼用?這裡有一篇詳解

神經網路中的「注意力」是什麼?怎麼用?這裡有一篇詳解

原文來源:GitHub

作者:Adam Kosiorek

「雷克世界」編譯:嗯~阿童木呀、多啦A亮

「機器人圈」正式更名為「雷克世界」,後台回復「雷克世界」查看更多詳情。

神經網路中的注意力機制(Attention mechanisms),也被稱為「神經注意力」或「注意力」,最近吸引了廣泛的注意力(雙關語)。而在接下來的這篇文章中,我將描述和實現兩種軟視覺注意力機制。

什麼是注意力(attention)

一種非正式的說法是,神經注意力機制可以使得神經網路具備專註於其輸入(或特徵)子集的能力:選擇特定的輸入。這可以是x∈R^d一個輸入,z∈R^k一個特徵向量,a∈[0,1]^k一個注意力向量或f ? (x) 注意力網路。通常來說,注意力為

其中⊙是指元素對應乘法(element-wise multiplication)。下面我們可以談論一下軟注意力(soft attention),它將特徵與一個值在0和1之間的掩碼或當這些值被限定為0或1時的硬注意力(hard attention)相乘,即a∈^k。在後一種情況下,我們可以使用硬注意力掩碼直接索引特徵向量:za =z[a](用Matlab表示法),可以改變其維度。

如果你想要弄明白為什麼注意力機制如此至關重要,那我們就有必要思考一下一個神經網路的真正意義是什麼:函數近似器。它的能夠近似不同類別函數的能力主要依賴於它的架構。一個典型的神經網路可以被實現為一系列矩陣乘法(matrix multiplications)和元素對應非線性乘法(element-wise non-linearities),其中輸入或特徵向量的元素僅僅通過加法相互作用。

注意力機制會對一個用於與特徵相乘的掩碼後進行計算,這種看似簡單的額擴展具有深遠的影響:突然間,一個可以通過神經網路進行很好的近似的函數空間得到了極大的擴展,使得全新的用例成為可能。為什麼會出現這種情況呢?直覺認為是以下原因,雖然沒有足夠的證據:這種理論認為神經網路是一個通用函數近似器,可以對任意函數進行近似為任意精度,但只能在無限數量的隱藏單位限定條件下進行。而在任何實際情況下,情況並非如此:我們受限於可以使用的隱藏單位的數量。考慮以下示例:我們要對N個輸入的結果進行近似,前饋神經網路只能通過模擬具有許多加法(以及非線性)的乘法來實現,因此需要大量神經網路的實際空間。但如果我們引入乘法交互的理念,過程就會自然而然的變得簡單而有便捷。

上述將注意力定義乘法交互(multiplicative interactions)的做法使得我們如果想要放鬆對注意力掩碼值的約束且a∈R^k,可以考慮一種更為廣泛的類模型。例如,動態過濾網路(DFN)使用的是一個過濾器生成網路,它是基於輸入來計算過濾器(或任意大小的權重),並將其應用於特徵,這實際上是一種乘法交互。與軟注意力機制的唯一區別就是,注意力權重值沒有被限制在0和1之間。想要在這個方向上進行進一步研究,那麼去了解哪些交互作用是相加的,哪些是相乘的,探討加法和乘法神經元之間的可微分轉換的概念這都將是非常有趣的。一個非常優秀的博客distill blog上面提供了一個很好的關於軟注意力機制的闡述,大家不妨去看一看。

視覺注意力

注意力可以應用於任何類型的輸入而不管其形狀如何。在矩陣值輸入(如圖片)的情況下,我們可以談論視覺注意力。不管是I∈R^H×W圖像還是g∈R^ h×w注意力的一角都可以說是將注意力機制運用於圖像的結果。

硬注意力(Hard Attention)

硬注意力在圖像中的應用已經被人們熟知多年:圖像裁剪(image cropping)。從概念上來看是非常簡單的,因為它只需要索引。硬注意力可以用Python(或Tensorflow)實現為:

g = I[y:y+h, x:x+w]

上述存在的唯一的問題是它是不可微分的;你如果想要學習模型參數的話,就必須使用分數評估器(score-function estimator)關於這一點,我的前一篇文章中有對其的簡要介紹。

軟注意力

軟注意力,在其最簡單的變體中,對於圖像與和向量值來說沒有什麼不同,並在等式1中得到了完全實現。這種類型的注意力的最早的用途之一是來自於一篇叫做《Show, Attend and Tell》(https://arxiv.org/abs/1502.03044)的論文:

該模型學習趨向於該圖像的特定部分,同時生成描述該部分的單詞。

然而,這種類型的軟注意力在計算上是非常浪費的。輸入的黑色部分對結果沒有任何影響,但仍然需要處理。同時它也是過度參數化的:實現注意力的sigmoid 激活函數是彼此相互獨立的。它可以一次選擇多個目標,但實際操作中,我們經常希望具有選擇性,並且只能關注場景中的一個單一元素。由DRAW和空間變換網路(Spatial Transformer Networks)引入的以下兩種機制很好地別解決了這個問題。它們也可以調整輸入的大小,從而進一步提高性能。

高斯注意力(Gaussian Attention)

高斯注意力通過利用參數化的一維高斯濾波器來創建圖像大小的注意力圖。使 a y ∈R^h和a x ∈R^w是注意向量,它們分別指定在yy和xx軸中應該出現哪一部分圖像。注意力掩碼可以創建為:

在上圖中,頂行顯示ax,右邊的列顯示ay,中間的矩形顯示結果a。這裡,為了可視化的目的,向量只包含0和1。實際上,它們可以被實現為一維高斯的向量。通常,高斯數等於空間維度,每個向量由三個參數參數化:第一個高斯 μ的中心、連續高斯d的中心距離和高斯標準偏差 σ。通過這個參數,注意力和 glimpse在注意力參數方面是可以區分的,因此很容易學習。

上述形的注意力仍然是浪費的,因為它只選擇一部分圖像,同時遮擋所有剩餘的部分。而不是直接使用向量,我們可以將它們分別放入矩陣 A y ∈R^h×H和 A x ∈R^w×W。現在,每個矩陣每行有一個高斯,參數 d 指定連續行中高斯中心之間的距離(以列為單位)。Glimpse現在實施為:

我在HART中使用了這種機制,我最近的一篇關於RNN的生物啟發對象跟蹤的文章引起關注(https://arxiv.org/abs/1706.09262)。這裡是左側輸入圖像的示例,注意力glimpse在右側; glimpse將顯示主圖像中標記的框為綠色:

下面的代碼可以為Tensorflow中的一小批樣本創建上述矩陣值的掩碼。如果要創建Ay,你可以將其稱為Ay = gaussian_mask(u, s, d, h, H),其中u,s,d為該順序的μ,σ 和 d,以像素為單位指定。

def gaussian_mask(u, s, d, R, C):

"""

:param u: tf.Tensor, centre of the first Gaussian.

:param s: tf.Tensor, standard deviation of Gaussians.

:param d: tf.Tensor, shift between Gaussian centres.

:param R: int, number of rows in the mask, there is one Gaussian per row.

:param C: int, number of columns in the mask.

"""

# indices to create centres

R = tf.to_float(tf.reshape(tf.range(R), (1, 1, R)))

C = tf.to_float(tf.reshape(tf.range(C), (1, C, 1)))

centres = u[np.newaxis, :, np.newaxis] + R * d

column_centres = C - centres

mask = tf.exp(-.5 * tf.square(column_centres / s))

# we add eps for numerical stability

normalised_mask /= tf.reduce_sum(mask, 1, keep_dims=True) + 1e-8

return normalised_mask

我們還可以編寫一個函數,直接從圖像中提取glimpse:

def gaussian_glimpse(img_tensor, transform_params, crop_size):

"""

:param img_tensor: tf.Tensor of size (batch_size, Height, Width, channels)

:param transform_params: tf.Tensor of size (batch_size, 6), where params are (mean_y, std_y, d_y, mean_x, std_x, d_x) specified in pixels.

:param crop_size): tuple of 2 ints, size of the resulting crop

"""

# parse arguments

h, w = crop_size

uy, sy, dy, ux, sx, dx = tf.split(transform_params, 6, -1)

# create Gaussian masks, one for each axis

Ay = mask(uy, sy, dy, h, H)

Ax = mask(ux, sx, dx, w, W)

# extract glimpse

glimpse = tf.matmul(tf.matmul(Ay, img_tensor, adjoint_a=True), Ax)

return glimpse

空間變換(Spatial Transformer)

空間變換(STN)允許進行更多的普通變換,與圖像裁剪只有細微區別,但是圖像裁剪是可能的用例之一。它由兩個要素組成:網格生成器和採樣器。網格生成器指定網格的點被採樣,而採樣器,只採樣點。來自DeepMind的最近的神經網路庫Sonnet(https://github.com/deepmind/sonnet),用Tensorflow實現尤其容易。

def spatial_transformer(img_tensor, transform_params, crop_size):

"""

:param img_tensor: tf.Tensor of size (batch_size, Height, Width, channels)

:param transform_params: tf.Tensor of size (batch_size, 4), where params are (scale_y, shift_y, scale_x, shift_x)

:param crop_size): tuple of 2 ints, size of the resulting crop

"""

constraints = snt.AffineWarpConstraints.no_shear_2d()

warper = snt.AffineGridWarper(img_size, crop_size, constraints)

grid_coords = warper(transform_params)

glimpse = snt.resampler(img_tensor, grid_coords)

return glimpse

高斯注意力(Gaussian Attention)與空間變換(Spatial Transformer)

高斯注意力和空間變換都可以實現非常相似的行為。我們如何選擇使用哪一個?這裡有幾個細微差別:

?高斯注意力是一個超參數的裁剪機制:它需要六個參數,但只有四個自由度(y、x、height 、width)。空間變換(STN)只需要四個參數。

?我還沒有運行任何測試,但是STN應該更快。它依賴於採樣點的線性插值,而高斯注意李必須執行兩個巨大的矩陣乘法。STN可以快一個數量級(以輸入圖像的像素為單位)。

?高斯注意力應該(沒有測試運行)更容易訓練。這是因為所發生的glimpse中的每個像素可以是源圖像相對大的像素塊的凸組合,這樣可以更容易地找到任何錯誤的原因。另一方面,STN依賴於線性插值,這意味著每個採樣點的梯度對於兩個最近的像素而言都是非零的。

結論

注意力機制擴展了神經網路的能力:它們能接近更複雜的函數,或者更直觀地說,它們可以專註於輸入的特定部分。它們使自然語言基準測試的性能得到改進,以及賦予圖像字幕、記憶網路和神經程序的全新能力。

我認為注意力最重要的案例尚未發現。例如,我們知道視頻中的對象是一致的和連貫的,它們不會消失在框架中。注意力機制可以用來表達這種一致性,後續將如何發展,我們會持續關注。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 雷克世界 的精彩文章:

「詞嵌入」在NLP中扮演什麼角色?一文搞懂Word Embeddings背後原理
他是吳恩達導師,被馬雲聘為「達摩院」首座
DeepMind最新論文提出「Rainbow」,將深度強化學習組合改進

TAG:雷克世界 |