入門| 請注意,我們要談談神經網絡的注意機制和使用方法

2020-12-04 百家號

選自GitHub

作者:Adam Kosiorek

機器之心編譯

參與:Panda

神經網絡中的注意機制(attention mechanism),也被稱為神經注意(neural attention)或注意(attention),最近也得到了人們越來越多的關注。在本文中,作者將嘗試為不同機制和用例找到共同點,此外還將描述並實現兩個軟視覺注意(soft visual attention)機制範例。本文作者 Adam Kosiorek 為牛津大學在讀博士。

注意機制是什麼?

我們可以粗略地把神經注意機制類比成一個可以專注於輸入內容的某一子集(或特徵)的神經網絡:它可以選擇特定的輸入。設 x∈R^d 為輸入,z∈R^k 為特徵向量,a∈{0,1}^k 是注意向量,g∈R^k 為 attention glimpse,f(x) 為注意網絡(attention network)。一般而言,注意實現為如下形式:

其中 ⊙ 是元素依次相乘。對於軟注意(soft attention),其將特徵與一個(軟)掩模( mask )相乘,該掩模的值在 0 到 1 之間;對於硬注意(hard attention),這些值被限制為確定的 0 或 1,即 a∈{0,1}k。在後面的案例中,我們可以使用硬注意掩模來直接索引其特徵向量

(用 Matlab 的表示方法),它會改變自己的維度,所以現在

,其中 m≤k。

為了理解注意機制的重要性,我們必須考慮到神經網絡實際上就是一個函數近似器。它近似不同類型的函數的能力取決於它的架構。典型的神經網絡的實現形式是矩陣乘法構成的鏈式運算和元素上的非線性,其中輸入的元素或特徵向量只會通過加法彼此交互。

注意機制會計算一個用於對特徵進行乘法運算的掩模。這種看似無關痛癢的擴展會產生重大的影響:突然之間,可以使用神經網絡近似的函數空間多了很多,讓全新的用例成為了可能。為什麼會這樣?儘管我沒有證據,但直觀的想法是:有一種理論認為神經網絡是一種通用的函數近似器,可以近似任意函數並達到任意精度,唯一的限制是隱藏單元的數量有限。在任何實際的設置中,情況卻不是:我們受限於可以使用的隱藏單元的數量。考慮以下案例:我們要近似神經網絡輸入的乘積。前饋神經網絡只能通過使用(許多)加法(以及非線性)來模擬乘法,因此它需要大量神經網絡基礎。如果我們引入乘法交互,那它就會變得簡單且緊湊。

如果我們放鬆對注意掩模的值的限制,使 a∈R^k,那麼上面將注意定義為乘法交互的做法能讓我們考慮更大範圍的模型。比如動態過濾器網絡(DFN:Dynamic Filter Networks)使用了一個過濾器生成網絡,它可以基於輸入而計算過濾器(即任意幅度的權重),並將它們應用於特徵,這在效果上就是一種乘法交互。使用軟注意機制的唯一區別是注意權重並不局限於 0 到 1 之間。在這個方向上更進一步,了解哪些交互應該是相加的、哪些應該是相乘的是非常有意思的。

論文《A Differentiable Transition Between Additive and Multiplicative Neurons》對這一概念進行了探索,參閱:https://arxiv.org/abs/1604.03736。另外,《 深度 | 深度學習能力的拓展,Google Brain 講解注意力模型和增強 RNN 》這篇文章也對軟注意機制進行了很好的概述。

視覺注意

注意機制可應用於任意種類的輸入,不管這些輸入的形態如何。在輸入為矩陣值的案例中(比如圖像),我們可以考慮使用視覺注意(visual attention)。設

為圖像,

為 attention glimpse,即將注意機制應用於圖像 I 所得到的結果。

硬注意

對圖像的硬注意已經存在了很長時間,即圖像裁剪。在概念上這非常簡單,因為僅需要索引。使用 Python(或 TensorFlow),硬注意可以實現為:

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

上面代碼的唯一問題是不可微分;為了學習得到模型的參數,比如藉助分數函數估計器(score-function estimator)等方法,我之前的文章也曾簡要提到過:https://goo.gl/nfPB6r

軟注意

軟注意最簡單的形式在圖像方面和向量值特徵方面並無不同,還是和上面的(1)式一樣。論文《Show, Attend and Tell: Neural Image Caption Generation with Visual Attention》是最早使用這種類型的注意的研究之一:https://arxiv.org/abs/1502.03044

該模型可以學習注意圖像的特定部分,同時生成描述這部分的詞。

但是,這種類型的軟注意非常浪費計算資源。輸入中變暗的部分對結果沒有貢獻,但仍然還是需要處理。它也過度參數化了:實現這種注意的 sigmoid 激活函數是彼此獨立的。它可以同時選擇多個目標,但在實際中,我們往往希望進行選擇並且僅關注場景中的單個元素。下面這兩個機制解決了這個問題,它們分別是由 DRAW(https://arxiv.org/abs/1502.04623)和 Spatial Transformer Networks(https://arxiv.org/abs/1506.02025)這兩項研究引入的。它們也可以重新調整輸入的大小,從而進一步提升性能。

高斯注意(Gaussian Attention)

高斯注意是使用參數化的一維高斯過濾器來創造圖像大小的注意圖(attention map)。設

是注意向量,其分別通過 y 和 x 坐標指定了應該注意圖像中的哪一部分。其注意掩模可以創建為

在上圖中,上面一行表示 ax,右邊一列表示 ay,中間的矩形表示得到的結果 a。這裡為了可視化,向量中僅包含 0 和 1. 實際上,它們可以實現為一維的高斯向量。一般而言,高斯的數量就等於空間的維度,且每個向量都使用了 3 個參數進行參數化:第一個高斯的中心 μ、連續的高斯中心之間的距離 d 和這些高斯的標準差 σ。使用這種參數化,注意和 glimpse 在注意的參數方面都是可微分的,因此很容易學習。

上面形式的注意仍然很浪費,因為它只選擇了圖像的一部分,同時遮擋了圖像的其它部分。我們可以不直接使用這些向量,而是將它們分別投射進

中。現在,每個矩陣的每一行都有一個高斯,參數 d 指定了連續行中的高斯中心之間的距離(以列為單位)。現在可以將 glimpse 實現為:

我最近一篇關於使用帶有注意機制的 RNN 進行生物啟發式目標跟蹤的論文 HART 中就使用了這種機制,參閱:https://arxiv.org/abs/1706.09262。這裡給出一個例子,下面左圖是輸入圖像,右圖是 attention glimpse;這個 glimpse 給出了主圖中綠色標記出的框。

下面的代碼可以讓你在 TensorFlow 中為某個 minibatch 樣本創建一個上述的帶有矩陣值的掩模。如果你想創造 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 = 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

H, W = img_tensor.shape.as_list()[ 1 : 3 ]

split_ax = transform_params.shape.ndims - 1

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

# create Gaussian masks, one for each axis

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

Ax = gaussian_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,可以很輕鬆地在 TensorFlow 中實現它。Sonnet 地址:https://github.com/deepmind/sonnet

def spatial_transformer(img_tensor, transform_params, crop_size):

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

constraints = snt. AffineWarpConstraints .no_shear_2d()

img_size = img_tensor.shape.as_list()[ 1 :]

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

grid_coords = warper(transform_params)

glimpse = snt.resampler(img_tensor[..., tf.newaxis], grid_coords)

高斯注意 vs. 空間變換器

高斯注意和空間變換器可以實現非常相似的行為。我們該選擇使用哪一個呢?這兩者之間有一些細微的差別:

高斯注意是一種過度參數化的裁剪機制:需要 6 個參數,但卻只有 4 個自由度(y、x、高度、寬度)。STN 只需要 4 個參數。

我還沒運行過任何測試,但 STN 應該更快。它依賴於在採樣點上的線性插值法,而高斯注意則必須執行兩個巨大的矩陣乘法運算。STN 應該可以快上一個數量級(在輸入圖像中的像素方面)。

高斯注意應該更容易訓練(沒有測試運行)。這是因為結果得到的 glimpse 中的每個像素都可以是源圖像的相對大批量的像素的凸組合,這使得我們能更容易找到任何錯誤的原因。而 STN 依賴於線性插值法,這意味著每個採樣點的梯度僅相對其最近的兩個像素是非 0 的。

你可以在這裡查看代碼示例:https://github.com/akosiorek/akosiorek.github.io/tree/master/notebooks/attention_glimpse.ipynb

一個簡單的範例

讓我們來創建一個簡單的高斯注意和 STN 範例。首先,我們需要載入一些庫,定義尺寸,創建並裁剪輸入圖片。

import tensorflow as tf

import sonnet as snt

import numpy as np

import matplotlib . pyplot as plt

img_size = 10 , 10

glimpse_size = 5 , 5

# Create a random image with a square

x = abs ( np . random . randn ( 1 , * img_size )) * . 3

x [ 0 , 3 : 6 , 3 : 6 ] = 1

crop = x [ 0 , 2 : 7 , 2 : 7 ] # contains the square

隨後,我們需要 TensorFlow 變量的佔位符。

tf . reset_default_graph ()

# placeholders

tx = tf . placeholder ( tf . float32 , x . shape , 'image' )

tu = tf . placeholder ( tf . float32 , [ 1 ], 'u' )

ts = tf . placeholder ( tf . float32 , [ 1 ], 's' )

td = tf . placeholder ( tf . float32 , [ 1 ], 'd' )

stn_params = tf . placeholder ( tf . float32 , [ 1 , 4 ], 'stn_params' )

我們現在可以定義高斯注意和 STN 在 Tensorflow 上的簡單表達式。

# Gaussian Attention

gaussian_att_params = tf . concat ([ tu , ts , td , tu , ts , td ], - 1 )

gaussian_glimpse_expr = gaussian_glimpse ( tx , gaussian_att_params , glimpse_size )

# Spatial Transformer

stn_glimpse_expr = spatial_transformer ( tx , stn_params , glimpse_size )

運行這些表達式並繪製它們:

sess = tf . Session ()

# extract a Gaussian glimpse

u = 2

s = . 5

d = 1

u , s , d = ( np . asarray ([ i ]) for i in ( u , s , d ))

gaussian_crop = sess . run ( gaussian_glimpse_expr , feed_dict ={ tx : x , tu : u , ts : s , td : d })

# extract STN glimpse

transform = [. 4 , -. 1 , . 4 , -. 1 ]

transform = np . asarray ( transform ). reshape (( 1 , 4 ))

stn_crop = sess . run ( stn_glimpse_expr , { tx : x , stn_params : transform })

# plots

fig , axes = plt . subplots ( 1 , 4 , figsize =( 12 , 3 ))

titles = [ 'Input Image' , 'Crop' , 'Gaussian Att' , 'STN' ]

imgs = [ x , crop , gaussian_crop , stn_crop ]

for ax , title , img in zip ( axes , titles , imgs ):

ax . imshow ( img . squeeze (), cmap = 'gray' , vmin = 0. , vmax = 1. )

ax . set_title ( title )

ax . xaxis . set_visible ( False )

ax . yaxis . set_visible ( False )

以上代碼也在 Jupyter Notebook 上:https://github.com/akosiorek/akosiorek.github.io/blob/master/notebooks/attention_glimpse.ipynb

結語

注意機制能夠擴展神經網絡的能力:它們允許近似更加複雜的函數,用更直觀的話說就是能關注輸入的特定部分。它們已經幫助提升了自然語言處理的基準表現,也帶來了圖像描述、記憶網絡尋址和神經編程器等全新能力。

我相信注意機制最重要的用例還尚未被發現。比如,我們知道視頻中的目標是連續連貫的,它們不會在幀切換時憑空消失。注意機制可以用於表達這種連貫性的先驗知識。具體怎麼做?請拭目以待。

原文連結:http://akosiorek.github.io/ml/2017/10/14/visual-attention.html

本文為機器之心編譯, 轉載請聯繫本公眾號獲得授權。

------------------------------------------------

加入機器之心(全職記者/實習生):hr@jiqizhixin.com

投稿或尋求報導:content@jiqizhixin.com

廣告&商務合作:bd@jiqizhixin.com

相關焦點

  • 神經網絡中的注意機制(Attention Mechanism)
    局限性這種編碼器 - 解碼器方法的潛在問題是神經網絡需要能夠將源句子的所有必要信息壓縮成固定長度的矢量。注意力(Attention)如何解決問題?注意機制(Attention Mechanism)允許解碼器在輸出生成的每個步驟處注意源句子的不同部分。我們不是將輸入序列編碼為單個固定的上下文向量,而是讓模型學習如何為每個輸出時間步驟生成上下文向量。
  • 入門| Tensorflow實戰講解神經網絡搭建詳細過程
    【IT168 技術】之前我們講了神經網絡的起源、單層神經網絡、多層神經網絡的搭建過程、搭建時要注意到的具體問題、以及解決這些問題的具體方法。本文將通過一個經典的案例:MNIST手寫數字識別,以代碼的形式來為大家梳理一遍神經網絡的整個過程。
  • 神經網絡原來這麼簡單,機器學習入門貼送給你|乾貨
    這裡有一個入門貼適合你。什麼神經網絡、隨機森林、計算機視覺通通一網打盡。這個Facebook軟體工程師做了一個入門貼。專為基礎為零的初學者打造。有基礎的同學,也可以來看看加深一下理解。我們就以神經網絡為例先來一睹為快吧!神經網絡概論作者說,神經網絡並不複雜!
  • 一種兼具神經網絡高效性和高斯過程靈活性的方法——神經過程
    在今年的ICML上,研究人員提出了不少有趣的工作,其中神經過程(NPs)引起了許多人的注意,它基於神經網絡概率模型,但又可以表示隨機過程的分布。這意味著NPs結合了兩個領域的元素: 深度學習:神經網絡是靈活的非線性函數,可以直接訓練 高斯過程:GP提供了一個概率框架,可用於學習非線性函數的分布 兩者都有各自的優點和缺點。
  • 為什麼要進行圖學習?談一談逆勢而上的圖神經網絡
    圖核論文的研究綜述: 2020圖核方法最新進展與未來挑戰,151頁pdf注意力機制 | 圖卷積多跳注意力機制 | Direct multi-hop Attention based GNNNeurIPS2020 | 基於路徑積分設計的圖卷積和圖池化操作NeurIPS 2020 | 基於模型的對抗元強化學習NeurIPS 2020 | Hinton
  • 神經網絡原來這麼簡單,機器學習入門貼送給你 | 乾貨
    這裡有一個入門貼適合你。什麼神經網絡、隨機森林、計算機視覺通通一網打盡。這個Facebook軟體工程師做了一個入門貼。專為基礎為零的初學者打造。有基礎的同學,也可以來看看加深一下理解。神經網絡概論作者說,神經網絡並不複雜!「神經網絡」一詞很流行,人們通常認為它很難,但其實要簡單得多。是不是這樣呢?先看再說。神經網絡的理解主要分為三個部分,神經元、神經網絡的構建、訓練神經網絡。神經元——神經網絡的基本單元
  • 極簡機器學習課程:使用Python構建和訓練一個完整的人工神經網絡
    而本文介紹的系列視頻,將帶領大家使用Python構建和訓練一個完整的人工神經網絡。1.數據+架構要想使用一種機器學習的方法,我們首先需要數據。在本節中,我們介紹如何使用Python實現正向傳播。3.梯度下降本節重點放在如何改進神經網絡,使預測更準確。 梯度下降法,是當今最流行的優化(optimization)算法,亦是至今最常用的優化神經網絡的方法。
  • 使用微波爐的方法和注意事項
    使用注意事項1、雞蛋不管帶不帶殼都不能用微波爐加熱。帶殼雞蛋放在微波爐裡加熱後會爆炸,這個估計知道的人不少。但還有件事您是否知道——沒殼的雞蛋,不管全熟的、半生不熟的,還是有沒有放在水中一起加熱,只要沒攤開來,再被微波爐一加熱,危險性跟帶殼的時候一樣高。
  • 農藥殘留檢測儀的使用方法及注意事項
    有機磷和氨基甲酸酯類農藥對膽鹼酯酶正常功能有抑制作用,其抑制率與農藥的濃度呈正相關係。正常情況下,酶催化神經傳導代謝產物(乙醯膽鹼)水解,其水解產物顯色劑反應,產生黃色物質,用農藥殘留檢測儀器測定吸光度隨時間的變化值,計算出抑制率,通過抑制率可以判斷出樣品中是否含有有機磷或氨基甲酸酯類農藥的存在。
  • 烤箱第一次使用要注意什麼 烤箱使用方法是什麼
    家家戶戶現在的生活水平應該都要比之前高,那麼在這種情況下,高科技物品的使用就是必須的,科技物品方面,雖說整體效果看起來很好,但是想要實際的達成一些情況,必須也得在操作方面符合要求,烤箱就是這麼一個物品,那麼問題就來了,烤箱第一次使用要注意什麼?烤箱使用方法是什麼?
  • 直觀理解並使用Tensorflow實現Seq2Seq模型的注意機制
    採用帶注意機制的序列序列結構進行英印地語神經機器翻譯Seq2seq模型構成了機器翻譯、圖像和視頻字幕、文本摘要、聊天機器人以及任何你可能想到的包括從一個數據序列到另一個數據序列轉換的任務的基礎。如果您曾使用過谷歌Translate,或與Siri、Alexa或谷歌Assistant進行過互動,那麼你就是序列對序列(seq2seq)神經結構的受益者。
  • Keras入門系列教程:兩分鐘構建你的第一個神經網絡模型
    這是一個用於構建和訓練模型的高級API,其中包括對TensorFlow特定功能的一流支持,例如急切執行, tf.data pipeline和estimators。 tf.keras使TensorFlow更易於使用而不犧牲靈活性和性能。
  • 盤點| 機器學習入門算法:從線性模型到神經網絡
    原標題:盤點 | 機器學習入門算法:從線性模型到神經網絡 選自Dataconomy 機器之心編譯 參與:王宇欣、吳攀、蔣思源 預測問題分為兩大類: 現在我們已經介紹了機器學習在預測方面的應用,我們可以討論機器學習算法,其分為 3 個組別:線性模型(linear models)、樹型模型(tree-based models)、和神經網絡(neural networks)。
  • 從經典結構到改進方法,神經網絡語言模型綜述
    神經網絡語言模型(NNLM)克服了維數的限制,提升了傳統語言模型的性能。本文對 NNLM 進行了綜述,首先描述了經典的 NNLM 的結構,然後介紹並分析了一些主要的改進方法。研究者總結並對比了 NNLM 的一些語料庫和工具包。此外,本文還討論了 NNLM 的一些研究方向。
  • 深度|人工神經網絡深入分析
    本文與吳老師的講解方式不同,筆者希望能從神經網絡的起源揭開神經網絡的面紗,從而幫助更多的對神經網絡感興趣但卻沒有相關理論基礎的朋友們。說起人工神經網絡的起源肯定要追溯到生物的神經網絡。因此非線性可分要用到多層神經元,下面筆者先介紹一下多層神經網絡。
  • 冰毯和冰帽的使用方法及注意事項
    冰毯、冰帽的使用在臨床上是一種常見的物理降溫方法之一,物理降溫包括局部冷療法和全身冷療。
  • 數字萬用表的使用方法及注意事項
    導讀 通常,數字式萬用表由液晶顯示屏、功能選擇旋鈕、測試表筆、測量電路和電池等組成。那,大家可知數字萬用表的使用方法及注意事項嗎?
  • 教程 | 如何使用TensorFlow構建、訓練和改進循環神經網絡
    目前有很多人工智慧應用都依賴於循環深度神經網絡,在谷歌(語音搜索)、百度(DeepSpeech)和亞馬遜的產品中都能看到RNN的身影。然而,當我們開始著手構建自己的 RNN 模型時,我們發現在使用神經網絡處理語音識別這樣的任務上,幾乎沒有簡單直接的先例可以遵循。
  • 全站儀的使用方法及注意事項
    打開APP 全站儀的使用方法及注意事項 網絡整理 發表於 2020-05-22 11:23:26   全站儀的使用方法   全站儀放樣模式有兩個功能,即測定放樣點和利用內存中的已知坐標數據設置新點,如果坐標數據未被存入內存,則也可從鍵盤輸入坐標。
  • 硫酸亞鐵的使用方法和注意細節!
    使用方法:硫酸亞鐵可以使用葉面施肥和灌土施肥的方式:1,灌土方式:將硫酸亞鐵兌水500倍左右,直接澆灌在花土上,澆灌的方式以澆透水的形式澆灌,澆灌到花盆底部有多餘的水流出就可以。2,葉面噴霧:先將硫酸亞鐵進行800倍左右的稀釋,然後噴霧到花卉的葉面和葉的背面,噴霧時以葉尖有水滴滴下就可以,單一一次作業施用硫酸冶鐵,要連續的三次每次間隔大約15分鐘。硫酸冶鐵的擴散性不是很好,每次噴霧要細,要均勻。