###### tags: `opendev`
# Attention
**Attention(注意)** は、人間の目の仕組み(Visual Attention)をもとに考えだされた深層学習の仕組み。ニューラルネットワーク(NN) がどこに注目するかを計算する仕組みの総称。

https://alibaba-cloud.medium.com/self-attention-mechanisms-in-natural-language-processing-9f28315ff905
例えば、人間は、質問といった文章を見たり聞いたりする時、重要そうな部分を無意識に抽出している。
<img src="https://i.imgur.com/WHXNM1V.png" width=50%>
Attention では、入力側のどこに着目するかを計算する、または、注目した入力データに基づいて結果を出力したりする。
---
### 画像処理の Attention の一例
Grad-CAM : CNN がどこに着目しているかを可視化する手法の一つ。
「`boxer`」という犬を表すラベルを入力した場合、

https://arxiv.org/pdf/1610.02391.pdf
予測クラスの出力結果に変化を与えたところ(勾配の大きな箇所)が分類予測を行う上で、重要な箇所としヒートマップを作成している。
${ \displaystyle
\quad \alpha_k^c = \overset{\text{global average pooling}}{\overbrace{\frac{1}{Z} \sum_{x,y} }} \frac{\partial S_c}{\partial f_k(x,y)} \quad (1)
}$
$(1)$
カテゴリ $c$ の確率スコア : $S_c$
$k$ 番目の特徴量マップの座標 $(x, y)$ の出力 : $f_k(x, y)$
$\frac{\partial S_{c}}{\partial f_{k}(x, y)}$ では、特徴量マップ $k$ の座標 $(x, y)$ の画素が変化したとき、ニューラルネットワークのカテゴリ $c$ の出力値 $S_c$ がどのぐらい変化するのか(勾配)を示す。
${ \displaystyle
\quad\quad L^c_{\rm Grad-CAM} = ReLU \underset{\text{linear combination}}
{\underbrace{\left(\sum_k \alpha_k^c f_{k}(x, y) \right)}} \quad\quad (2)
}$
$(2)$
求めた重み $α^c_k$ と $k$ 番目の特徴量マップの座標 $(x, y)$ の出力 $f_k(x, y)$ との線形結合を取ってやればカテゴリ $c$ における Grad-CAM($L^c_{\rm Grad-CAM}$) を求められる。
### 自然言語処理の Attention の一例
下図は、Attention を使ったモデル(Transformer)で俳句生成を行った結果を可視化したもの。

:::info
:book: **解釈可能な AI**
外部(人間)から様子を観察できる機械学習を **解釈可能な AI(Explainable AI, XAI)** という。
内部をわかりやすく可視化することでモデルの精度向上に貢献する。
:::
## 従来の RNN と Attention の違い
RNN は BPTT(Backpropagation Through Time)より長く連なった順伝播ネットワークと考えることができる。
RNN の欠点は、入力を順々にしか処理できない点にある。

https://www.nature.com/articles/nature14539
Attention は、入力文章内の単語関係を一度に処理することで並列計算を可能にしている。
今回は、Attention の中でもアツい分野の **Dot product Attention** について紹介する。
## 様々な Attention
### Self-Attention
Query, Key, Value の3つのベクトルで計算される。
`Query` : Input のうち「検索をかけたいもの」
`Key` : 検索対象と `Query` との近さを測る
`Value` : `Key` に基づき、適切な output を出力する。

ネガポジ分析の例

言語の文法構造、照応関係の獲得に使われる。
### Source-Target Attention

Source-Target Attention でキーワードから俳句を生成した例

翻訳といった変換処理に使われる。
### Scaled Dot-production Attention(縮約付き内積Attention)
$Q$ と $K$ を行列積した値を $softmax$ で正規化するが、値が大きすぎるとき、最小値との差が大きくなりすぎて、うまく $Attention$ を掛けられない問題があった。
そこで、Embedding の次元数で予め割ってあげることで大きすぎる値を減少させる。
$\displaystyle \mathrm{Attention}(Q, K, V)=\mathrm{softmax}(\frac{QK^T}{\sqrt{d_k}})V$


https://arxiv.org/abs/1706.03762
```python=
import tensorflow as tf
def scaled_dot_product_attention(q, k, v, mask):
"""アテンションの重みの計算
q, k, vは最初の次元が一致していること
k, vは最後から2番めの次元が一致していること
マスクは型(パディングかルックアヘッドか)によって異なるshapeを持つが、
加算の際にブロードキャスト可能であること
引数:
q: query shape == (..., seq_len_q, depth)
k: key shape == (..., seq_len_k, depth)
v: value shape == (..., seq_len_v, depth_v)
mask: (..., seq_len_q, seq_len_k) にブロードキャスト可能な
shapeを持つ浮動小数点テンソル。既定値はNone
戻り値:
出力、アテンションの重み
"""
matmul_qk = tf.matmul(q, k, transpose_b=True) # (..., seq_len_q, seq_len_k)
# matmul_qkをスケール
dk = tf.cast(tf.shape(k)[-1], tf.float32)
scaled_attention_logits = matmul_qk / tf.math.sqrt(dk)
# マスクをスケール済みテンソルに加算
if mask is not None:
scaled_attention_logits += (mask * -1e9)
# softmax は最後の軸(seq_len_k)について
# 合計が1となるように正規化
attention_weights = tf.nn.softmax(scaled_attention_logits, axis=-1) # (..., seq_len_q, seq_len_k)
output = tf.matmul(attention_weights, v) # (..., seq_len_q, depth_v)
return output, attention_weights
```
https://www.tensorflow.org/tutorials/text/transformer
## Transformer
Attention Is All You Need(2017, 被引用数: 18767) という論文が Google から発表された。
Attention しか使わない Encoder-Decoder モデル。
機械翻訳のスコアを既存の RNN 系の Encoder-Decoder モデルよりも高い性能をだし、最高性能(SOTA: State of the Art)を記録。
### Transformer のシンプルな図

{%pdf https://arxiv.org/pdf/1706.03762.pdf%}
Transformer の構造を応用することで様々な分野に応用が利くため、深層学習ではアツい研究分野となっている。
翻訳・文章生成 : Transformer
物体検出 : [DETR(Detection Transformer)](https://ai-scholar.tech/articles/object-detection/detr-object-detection-transformers-paradigm)
画像分類 : [Vision Transformer(ViT)](https://qiita.com/omiita/items/0049ade809c4817670d7)
音声認識 : [Conformer](https://ai-scholar.tech/articles/voice-recognition/transformer)
強化学習 : [Gated Transformer-XL(GTrXL)](https://ai-scholar.tech/articles/reinforcement-learning/GTrXL)
GAN : [TransGAN](https://ai-scholar.tech/articles/transformer/transGAN)
### Position Encoding(Positional Encoding)
位置エンコーディングとも言う。Attention では RNN のように順々に入力を行わないため、時系列ラベル(Position Encoding)をつけてやる必要がある。
```python=
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
vocab_size = 20000 # 語彙数を 20 万に設定
maxlen = 200 # 各文を最大 200 字に設定
embed_dim = 32 # 各トークンの Embedding size
```
```python=
class TokenAndPositionEmbedding(layers.Layer):
def __init__(self, maxlen, vocab_size, embed_dim):
# 多重継承し、 コンストラクタ(__init__ メソッド)を実行している
# super(TokenAndPositionEmbedding, self).__init__()
super().__init__()
self.token_emb = layers.Embedding(input_dim=vocab_size, output_dim=embed_dim)
self.pos_emb = layers.Embedding(input_dim=maxlen, output_dim=embed_dim)
def call(self, x):
# -1 で最後の要素を指定する
maxlen = tf.shape(x)[-1]
positions = tf.range(start=0, limit=maxlen, delta=1)
# (None, 32)
positions = self.pos_emb(positions)
# (None, 20, 32)
x = self.token_emb(x)
return x + positions
```
`layers.Embedding` : [Embedding](https://keras.io/ja/layers/embeddings/)
`tf.shape`: [tf.shape](https://www.tensorflow.org/api_docs/python/tf/shape?hl=ja)
`tf.range`: [tf.range](https://www.tensorflow.org/api_docs/python/tf/range)
```python=
tf.range(start=0, limit=maxlen, delta=1)
```
```
array([ 0, 1, 2,... maxlen-1])
```
### Multi-Head Attention
Simple Attention を並列に並べたアーキテクチャー
Transformer は、Multi-Head Attention と Feed-forward Network を積み重ねた構造で構成される。

1つの Attention で学習を行うよりも小さな複数の head に分けて Attention を行うことで性能が向上した。これは、複数ヘッドが異なる部分空間を処理するためと考えられている。
$MultiHead(Q,K,V)=Concat(head_1,...,head_h)W_o$
$where \space head_i = Attention(QW^Q_i, KW^K_i, VW^V_i)$
$head$ は $Q,K,V$ からなる $Attention$ を指す。
<img src="https://i.imgur.com/bPb1AX8.png" width=50%>
```python=
att = layers.MultiHeadAttention(num_heads=num_heads, key_dim=embed_dim)
```
`layers.MultiHeadAttention` : [MultiHeadAttention layer](https://keras.io/api/layers/attention_layers/multi_head_attention/)
### 実装
元論文(Attention Is All You Need)に忠実な実装
[言語理解のためのTransformerモデル](https://www.tensorflow.org/tutorials/text/transformer)
今回はすぐできる Keras で行う(colab)
https://colab.research.google.com/drive/1YfdBFlGSJjYubJmlAuF-gUxetOTtt9M5?usp=sharing
Transformer を画像に応用した**Vision Transformer(ViT)**
2020年10月に登場。
https://colab.research.google.com/drive/1B3lQI8Bwfr2HwaokxZL4XGvZ8Qc1QfcS?usp=sharing
## Transformer の応用と改良
<img src="https://i.imgur.com/VmIBBFd.png" width=75%>
## 事前学習済言語モデル(Pretrained Language Model)
単語の出現確率をモデル化したものを「**言語モデル(LM, Language Model)**」と言う。
大量のデータで事前に学習(Pretrained)を行ったモデルを「**事前学習済モデル**」と言う。
### BERT(Bidirectional Encoder Representation from Transformers)
{%pdf https://arxiv.org/pdf/1810.04805.pdf %}
Google の研究チームが 2018年10月に公開した論文で、文章分類、質問応答、固有表現抽出等の多様なタスクで公開当時のSOTAを達成した。
BERT は、大量のデータで事前学習し、比較的少量のデータで転移学習を行うことで各タスクでSOTAを達成した。
BERT-Large は、16のクラウド TPU で 4日間学習を行った。
データセットは、Wikipedia(数TB) + BookCorpus(5GB)

BERTは、ランダムにマスクされた単語を周辺情報から予測する(穴埋め問題)を採用した、双方向Transformer。
#### Masked Language Model(Mask LM)
BERTでは、次の単語を予測するのではなく、ランダムにマスクされた単語を周辺情報から予測することを事前学習タスクとした。
<img src="https://i.imgur.com/kj3ALW2.png" width=50%>
#### Next Sentence Prediction(NSP)
2つの文章の関係性を学習する。
`[CLS]`: 文の最初を表す
`[SEP]`: 文の区切りを表す

Masked Language Model と Next Sentence Prediction
https://colab.research.google.com/drive/1l5MaVIZeUzo1wAsWpnm_LkQpVYmlwJPv?usp=sharing
BERT fine tuning による感情分析
https://colab.research.google.com/drive/1PuqTh-yHvKYW3RLVJjGEUTETfEpsWAoW?usp=sharing
BERTによる文書分類
https://colab.research.google.com/drive/1a8N0PvXHY8Fj2YVp3ppoF6g5tAexVsCK?usp=sharing
京大 BERT日本語Pretrainedモデル
https://nlp.ist.i.kyoto-u.ac.jp/?ku_bert_japanese
### 様々な事前学習済モデル

https://github.com/thunlp/PLMpapers