Vision Transformerとその周辺

# Vision Transformerとその周辺

ディープラーニング界隈で話題になっている、[Vision Transformer(ViT)](http://arxiv.org/abs/2010.11929)の論文の解説をします。何番煎じかわかりませんが、[こちらのコード](https://github.com/lucidrains/vit-pytorch)を使って、実装についても触れます。最後に、ViTに触発された関連の論文についても紹介します。この記事はとある別の用途で執筆したものですが、よくまとまっていると言われたため、Qiitaで公開したいと思います。
## 概要
Self-AttentionはNLPでは絶大な成功を収めており、コンピュータビジョンのタスクにも限定的ではあるが用いられてきた。本論文ではTransformerを本格的に画像に適用し、畳み込みのような画像の帰納バイアス（局所性・並進同変性）が欠けていても、CNNに匹敵・または凌駕するような精度を達成できることを示した。ただし、ImageNetのような*中規模*のデータセットではSOTAのCNNほどの精度は達成できず、JFT-300Mのような巨大なデータセットを用いることで、帰納バイアスに勝る結果を得られた。
## 新規性・差分
* 畳み込みを一切しようせずに、TransformerのEncoderを少し修正したモデルに対して、巨大なデータセットでの事前学習を行っておくことで、複数のデータセットを転移学習してSOTAを達成できることを示した。
* 小さいパッチサイズで埋め込み、Self-Attentionを使う手法は先行研究でされていたが、従来よりも大きいパッチサイズで埋め込むことで、計算コストを削減することにも成功している。
* CNNとハイブリッドなモデルと比較したときに、純粋なViTは画像の帰納バイアスが足りないが、データ量がその帰納バイアスの差を埋めてしまうこと。
* 2次元の位置埋め込みではなく、学習可能な1次元の埋め込みによって、2次元の位置関係を表現できることを示した。

## 手法の概略
Transformer(Attention is All You Need)のEncodeに以下の修正を加えただけ。
* 言語のトークンの代わりに、画像をパッチサイズ$P\times P$のパッチに分割し、そのパッチを線形射影して$D$次元ベクトルに埋め込む。
* BERT同様、学習パラメータとして[cls]トークン入力も併せて、最終的に[cls]トークンの出力を分類に使用する。
* 位置埋め込みはAttention is All You Needにあった1次元の$\cos,\, \sin$を使用した埋め込みではなく、　学習可能な1次元の埋め込みを使用した。
  * 著者らは2次元の位置埋め込みも試しているが、学習可能な1次元の位置埋め込みほとんど変わらなかったため、学習可能な1次元位置埋め込みを採用している。
* 上位の層には分類器をつけた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630841/d20ca794-f557-b39d-0b01-e849c63ec537.png)
## 手法の詳細
### Self Attention
まず、Attention is All You Needの振り返りであるが、Attentionとは、どのようなものだったか。元データMemoryをKeyとValueにわけておき、検索したいベクトルQueryとKeyによって内積など（バリエーションあり）をとり関連度を計算したものである。その関連度をValueにかけることで、Valueから重要な情報を引き出したベクトルを得られる。この機構をAttentionと言った。QueryとMemoryが別のベクトルであれば、Source Target Attentionといい、QueryとMemoryが同じであれば、Self Attentionと言った。ViT(TransformerのEncoder)ではSelf Attentionのみ使用するため、Self Attentionに限って詳細を説明する。Self Attentionを式で定義すると以下の通り。

$$
[\mathbf{q},\mathbf{k}, \mathbf{v}]:=\mathbf{z}\mathbf{U}_{qkv} \\
A:={\rm softmax}\left(\mathbf{qk}^\top/D_h^\frac{1}{2}\right) \\
{\rm SA}(\mathbf{z}):=A\mathbf{v}
$$

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630841/6fc30ec3-7575-2e6b-25d2-c06c527d5638.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630841/8f3f3aec-7e87-c539-99c9-fc3cc21a954e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630841/363fbdca-b2f0-d2ff-6e71-f63ccfa7922b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630841/f29a4f9a-e0cd-773b-1604-795ee2e974bd.png)
ここで、
* $N$: トークン数
* $D$: 入力サイズ
* $D_h$: 射影後のベクトルのサイズ
* $\mathbf{z}\in\mathbb{R}^{N\times D}$: Input
* $\mathbf{U}_{qkv} \in \mathbb{R}^{D\times 3D_h}$: 線形射影
* $\mathbf{q}\in\mathbb{R}^{N\times D_h}$:　Query
* $\mathbf{k}\in\mathbb{R}^{N\times D_h}$:　Key
* $\mathbf{v}\in\mathbb{R}^{N\times D_h}$:　Value
ここで使用されているAttentionの計算は、Scaled Dot-production Attentionと呼ばれるもので、内積を次元の平方で割って*正規化*をすることで、ベクトルのサイズの影響を考慮している。
マルチヘッドではない場合$D=D_h$なのだが、通常はマルチヘッド化したSelf Attentionが使用される。その場合、出力サイズが$D$になるように調整される。

$${\rm MSA}(\mathbf{z}) = [{\rm SA1}(\mathbf{z}); {\rm SA2}(\mathbf{z});···; {\rm SAk}(\mathbf{z})]\mathbf{U}_{\rm msa}$$

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630841/7a103408-9902-2c1e-f783-fe51df8985b5.png)

ここで$k$はヘッド数で、$\mathbf{U}_{\rm msa}\in\mathbb{R}^{kD_h\times D}$は線形射影である。
なお、マルチヘッド化すると、適切なヘッド数を設定することで、シングルヘッドよりも性能がよくなることがAttention is All You Needにて実験的に示されている(ただし、$kD_h$を一定とした場合)。内積計算を$N^2$回やる必要があるため、コストは高い。
#### Attentionクラスの実装
``` python
class Attention(nn.Module):
    def __init__(self, dim, heads = 8, dim_head = 64, dropout = 0.):
        super().__init__()
        # 内部の次元はヘッド数とヘッドごとの次元の積になる
        inner_dim = dim_head * heads
        # 最後に射影の必要があるかどうか。
        project_out = not (heads == 1 and dim_head == dim)
        # ヘッド数
        self.heads = heads
        # Softmaxを適用する際にスケーリングする
        self.scale = dim_head ** -0.5
        # 内積qk^Tに適用するSoftmax
        self.attend = nn.Softmax(dim = -1)
        # inputからquery, key, valueを生成するための射影
        self.to_qkv = nn.Linear(dim, inner_dim * 3, bias = False)
        # マルチヘッドの場合か、内部の次元と入出力次元が異なる場合のための線形射影。
        self.to_out = nn.Sequential(
            nn.Linear(inner_dim, dim),
            nn.Dropout(dropout)
        ) if project_out else nn.Identity()

    def forward(self, x):
        # shapeとヘッド数を用意しておく
        b, n, _, h = *x.shape, self.heads
        # 入力に対して、線形変換して、そこから、query, key, valueに分割する
        qkv = self.to_qkv(x).chunk(3, dim = -1)
        # 分割したq,k,vをそれぞれreshape+軸入れ替えして、テンソルの形状をバッチ、ヘッド、トークン数、トークンのサイズにする。
        q, k, v = map(lambda t: rearrange(t, 'b n (h d) -> b h n d', h = h), qkv)
        # qとkの内積を取って、所定のスケーリングする
        dots = einsum('b h i d, b h j d -> b h i j', q, k) * self.scale
        # ソフトマックスを通してアテンションを得る。
        attn = self.attend(dots)
        # アテンションの重みをvにかける。
        out = einsum('b h i j, b h j d -> b h i d', attn, v)
        # 各ヘッドを結合する
        out = rearrange(out, 'b h n d -> b n (h d)')
        # マルチヘッドか内部の次元と入出力次元が異なるならば、射影する。
        return self.to_out(out)
```

### Transformer Encoder
TransformerのEncoder部分はSelf-Attention層とMLP層にResidual構造が入った層の繰り返しである。正規化にはLayerNormalization、MLPの活性化にはGELUが使用されている。

``` math
\mathbf{z}_l^′={\rm MSA}({\rm LN}(\mathbf{z}_{l−1})) +\mathbf{z}_{l−1} \\
\mathbf{z}_l={\rm MLP}({\rm LN}(\mathbf{z}^′_l))+\mathbf{z}_l^′
```

上記において、$l=1,\ldots L$であって、$\mathbf{z}_l, \mathbf{z}'_l\in \mathbb{R}^{N\times D}$、$\mathbf{z}_0$は後で定義する埋め込み後のテンソルである。

ちなみに、MLPはPointwise Convolutionに他ならないので、ViTはCNNの$n\times n$ Convolutionまたは$n\times n$ Depth Wise ComvolutionをMulti-Head Self Attentionに置き換えたという見方もできる。下流の層では、Convolutionでは周辺のピクセルとの関係しか捉えることができなかったが、Self Attentionを採用することで大域的な関係を捉えることができるようになっている。

### Transformerクラス

``` python
class Transformer(nn.Module):
    def __init__(self, dim, depth, heads, dim_head, mlp_dim, dropout = 0.):
        super().__init__()
        self.layers = nn.ModuleList([])
        # Multi Head Self-AttentionとFeedForward(channel mix)を繰り返し適用しているだけ。
        for _ in range(depth):
            self.layers.append(nn.ModuleList([
                PreNorm(dim, Attention(dim, heads = heads, dim_head = dim_head, dropout = dropout)),
                PreNorm(dim, FeedForward(dim, mlp_dim, dropout = dropout))
            ]))
    def forward(self, x):
        for attn, ff in self.layers:
            # Multi Head Self-AttentionとFeedForward(channel mix)を繰り返し適用しているが、Residual構造になっている。ちなみにAttentionをtoken mixに置き換えるとMLP-Mixerの主構成要素となる。
            x = attn(x) + x
            x = ff(x) + x
        return x
```

### FeedForwardクラス
``` python
class FeedForward(nn.Module):
    def __init__(self, dim, hidden_dim, dropout = 0.):
        super().__init__()
        # FeedForwardNet
        # GELUとDropoutが入っているところ以外特筆すべきところがない。
        self.net = nn.Sequential(
            nn.Linear(dim, hidden_dim),
            nn.GELU(),
            nn.Dropout(dropout),
            nn.Linear(hidden_dim, dim),
            nn.Dropout(dropout)
        )
    def forward(self, x):
        return self.net(x)
```

### PreNormクラス
``` python
class PreNorm(nn.Module):
    def __init__(self, dim, fn):
        super().__init__()
        # 正規化にはLNを使用してから、FeedForwardNetを適用する
        self.norm = nn.LayerNorm(dim)
        self.fn = fn
    def forward(self, x, **kwargs):
        return self.fn(self.norm(x), **kwargs)
```

## 実装詳細

### ViTクラス
ViTは概要に記載したとおり、まずはパッチの埋め込みを行う。入力画像はパッチサイズが$P\times P$となるようにReshapeしてあげてから、線形層$\mathbf{E}\in \mathbb{R}^{P^2 C\times D}$を利用して、各パッチをサイズ$D$のトークンとして埋め込む。

$[\mathbf{x}^1_p\mathbf{E};\mathbf{x}^2_p\mathbf{E};···;\mathbf{x}^N_p\mathbf{E}]$

ViTではBERTに準じてclass tokenを使用した手法が用いられているため、出力時に分類に使用するclass tokenを埋め込み後のトークン列の先頭に追加する。このclass tokenは学習パラメータとする。

$[\mathbf{x}_{\rm class};\mathbf{x}^1_p\mathbf{E};\mathbf{x}^2_p\mathbf{E};···;\mathbf{x}^N_p\mathbf{E}]$

トークン長が固定の場合は必ずしも、class tokenは必須ではないと考えられる。しかしAppendix D.3によると、画像パッチのみでGAPを用いた場合はうまく行かなかったと書かれている（後発の研究では、実はclass tokenが不要という指摘もあるかもしれないが）。

その後、位置埋め込みを行う。Attention is All You Needでの位置埋め込みは、$\sin, \cos$を使った種類の1次元の埋め込みを使用していたが、ここでは2次元の画像を扱っているため、この位置埋め込みを使用するのは適切とはいえない。2次元の位置埋め込みを使うと思いきや、ViTでは1次元の学習可能な位置埋め込みを使用している。採用理由については、Appendix　D.4で詳細に説明されている。1次元の学習可能な位置埋め込みが2次元や相対位置埋め込みと比較して遜色なかったとのことだ。

位置埋め込みは$\mathbf{E}_{pos}\in\mathbb{R}^{(N+1)\times D}$を学習パラメータとして、埋め込んだトークンに加える。つまり、埋め込み全体は以下の式で表せる。

``` math
\mathbf{z}_0=[\mathbf{x}_{\rm class};\mathbf{x}^1_p\mathbf{E};\mathbf{x}^2_p\mathbf{E};···;\mathbf{x}^N_p\mathbf{E}]+\mathbf{E}_{pos}
```

埋め込み後はTransformerのEncoderに入力し、その出力のclass tokenのみを分類器に入力して分類を行う。

``` python 
class ViT(nn.Module):
    def __init__(self, *, image_size, patch_size, num_classes, dim, depth, heads, mlp_dim, pool = 'cls', channels = 3, dim_head = 64, dropout = 0., emb_dropout = 0.):
        super().__init__()
        image_height, image_width = pair(image_size)
        patch_height, patch_width = pair(patch_size)

        assert image_height % patch_height == 0 and image_width % patch_width == 0, 'Image dimensions must be divisible by the patch size.'

        # パッチの数
        num_patches = (image_height // patch_height) * (image_width // patch_width)
        # パッチあたりの特徴量の数(RGB*パッチの解像度)
        patch_dim = channels * patch_height * patch_width
        assert pool in {'cls', 'mean'}, 'pool type must be either cls (cls token) or mean (mean pooling)'

        # パッチ埋め込み、シンプルにパッチを切り出すように形状変更して、線形射影する層の定義
        # なお、Rearrangeはeinops.layers.torchで定義されており、Pytorchのモジュールとして可読性と保ったまま転置やReshapeがまとめてできる。この場合も、本来のpytorchでview, permute, reshapeという操作が必要だが、Rearrangeのみで対応可能。
        self.to_patch_embedding = nn.Sequential(
            Rearrange('b c (h p1) (w p2) -> b (h w) (p1 p2 c)', p1 = patch_height, p2 = patch_width),
            nn.Linear(patch_dim, dim),
        )
        # 位置埋め込み、各パッチごとに学習可能なパラメータを設定しておく。
        # 論文通りだが、クラストークンもパラメータなので、クラストークンにも位置埋め込みを足すのはずっと不思議。
        self.pos_embedding = nn.Parameter(torch.randn(1, num_patches + 1, dim))
        # クラストークン
        self.cls_token = nn.Parameter(torch.randn(1, 1, dim))
        # 埋め込み時のドロップアウト
        self.dropout = nn.Dropout(emb_dropout)
        # Transformerのエンコーダ
        self.transformer = Transformer(dim, depth, heads, dim_head, mlp_dim, dropout)
        # クラストークンを使うかアベレージプーリングするか
        self.pool = pool
        # 無意味な層だが、自己教師あり学習のときに潜在空間の層の名前を使いたいだけ
        self.to_latent = nn.Identity()
        # 分類器
        self.mlp_head = nn.Sequential(
            nn.LayerNorm(dim),
            nn.Linear(dim, num_classes)
        )

    def forward(self, img):
        # パッチ埋め込み
        x = self.to_patch_embedding(img)
        # shape取得
        b, n, _ = x.shape
        # (BERT同様)クラストークンをバッチのインスタンス数だけ用意する
        cls_tokens = repeat(self.cls_token, '() n d -> b n d', b = b)
        # クラストークンと埋め込んだパッチを結合する
        x = torch.cat((cls_tokens, x), dim=1)
        # 位置埋め込みを加える
        # x += self.pos_embedding　ではだめなのかと思ったが、トークン数が事前学習した画像のパッチ数より少ないならばこの実装のほうがよいのかもしれない。
        x += self.pos_embedding[:, :(n + 1)]
        # Dropout
        x = self.dropout(x)
        # Transformerのエンコーダに入力する
        x = self.transformer(x)
        # クラストークンを使うか、アベレージプーリングするか。
        x = x.mean(dim = 1) if self.pool == 'mean' else x[:, 0]
        # おそらく、潜在空間の層の名前を使いたいだけ。上記操作後の出力をフックして特徴量として使えるようにするためではないか。
        x = self.to_latent(x)
        # 分類器
        return self.mlp_head(x)
```

## その他、論文中で検証されたことについて
論文中では、Layer数が異なる3種類タイプに、パターンの入力パッチサイズの組み合わせたモデルで検証されていた。

### SOTAとの比較

ResNetを改良版であるBiTや、EfficientNetの改良版であるNoisy Studentとの比較実験がされていた。JFT-300MやImageNet21kでの事前学習の後、転移学習をした結果だが、ViT-L/16ではBiTと同等であり、ViT-H/14では上回っている。Noisy Studentと比較しても同等くらいの結果ではある。学習時間をみても、遥かに改善されている。しかしながら、　ViT-L/16であってもTPUv3の1コアあたり230日もかかるということだから、庶民には苦しい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630841/218db73f-0c71-8f4b-bdf5-4a3921b241db.png)

### データセットのサイズがどの程度重要か？
ImageNet1kではBiTに劣るが、ImageNet21kやJFT-300Mでは上回るか競合する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630841/a7e54ca2-00b7-1313-3419-515e46e23b65.png)

JFT-300Mの部分集合(9M,30M,90M,300M)を使った実験でも同様の傾向がみられる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630841/99b2600b-9c87-2fa5-d63d-78257b7d4035.png)


### 計算量に対する精度のよさ
ViT、BiTと、BiTの特徴マップをTransformerに入力するハイブリッドモデルを使った比較実験
JFT-300Mで事前学習して、転移学習したときの精度と計算量をプロットした図（左：5データセットの転移学習の平均、右：ImageNetの転移学習）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630841/15ce278d-2142-cf98-44a2-458f09d5a802.png)
BiTよりViTがのほうが、コストパフォマンスがよく、ハイブリッドモデルとの比較でも、計算量が多くなってくると差がなくなることがわかる。

### 線形埋め込みのフィルタ可視化
下位層で学ぶべき単純なパターンを学んでいる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630841/611cb2c0-513d-8bb1-7b70-a75fa2e4dfb1.png)

### 位置埋め込みの影響
学習済みの位置埋め込みベクトルのコサイン類似度を計算すると実際に位置が近いところほどコサイン類似度が近い。つまり2次元構造が正しく学ばれていることが確認できる。前述の通り、本研究では、2次元埋め込みに取り替えたとしても性能に優位性はなかった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630841/6a2d4315-e385-a1fe-d172-64fae6e44097.png)


### パッチ間の情報が統合される距離
Self-Attentionによって、（最）下位の層であっても画像全体にわたり情報を統合することができるようになった。本研究では、Attentionの重みに基づき、情報が統合される距離を計算した。その結果、層が深くなるほどこの距離が増加することが判明した。私見であるが、この事実はCNNが成功してきたことの裏付けにもなっていると考える。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630841/c8cdff7b-4ecf-000a-e668-8925f9f2a9a1.png)


### 自己教師あり学習
BERTを模倣して、masked patch predictionを事前学習行い、場合、JFT-300Mのラベルをすべて使って事前学習した場合より4%劣るが、スクラッチから学習させるよりは2%勝った(ImageNet,ViT-L/16での検証)。

## 後発の研究

### Transformerベースモデル

#### [DeiT](https://arxiv.org/abs/2012.12877)

クラストークンの他に蒸留トークンを追加、クラストークンが正解ラベルに近づけるだけでなく、蒸留トークンが学習済みの教師(特にCNN)の出力に近づくように学習させた。

#### [T2T](http://arxiv.org/abs/2101.11986)

Self-Attentionの後にConv Moduleに似た(Reshape+)Unfoldという操作を加えることで、トークン長を短くしつつ局所的な情報を取り込んだ。

#### [PVT](http://arxiv.org/abs/2102.12122)

いくつかのステージにわけて、各ステージの最初にはパッチ埋め込み＋位置埋め込みを用いて、トークン長を減らし、かつ階層構造を表現する。また、keyとvalueの次元を削減するAttentionモジュール(SRA)を導入した。

#### [TNT](http://arxiv.org/abs/2103.00112)
従来の手法（Outer Transformer）に加え、局所的な特徴を抽出するためのInner Transformerを用意する。また、パッチをさらに分割したサブパッチを作成し、ViTと同様のエンコードしてInner Transformerに入力する。その出力は次のブロックのInner Transformerに渡すだけでなく、Outer Transformerの出力に対して、重みをかけて、バイアスと一緒に足す。

#### [DeepViT](http://arxiv.org/abs/2103.11886)

Transformerでは、ただブロックを重ねて性能向上に寄与しない（飽和する）。この問題をRe-attentionという構造を取り入れて解決した。それは、異なるヘッドのAttentionに対して学習可能な変換行列をかけて集約して、valueにかける機構である。このような仕組みを採用することで、異なる層でその多様性を増し、深いモデルの訓練に成功した。

#### [Swin](http://arxiv.org/abs/2103.14030)

パッチのマージ(プーリングのようなもの)採用し、階層化したVision Transoformer。Attention計算においてもshifted windowを導入し、画像的な局所構造を取り入れた。

#### [CrossViT](http://arxiv.org/abs/2103.14899)
スモールブランチとラージブランチのデュアル構造を取り入れた。それぞれをCross Attentionという機構で互いに影響を及ぼし合うような構造を取り入れ、性能を向上させた。

#### [CvT](http://arxiv.org/abs/2103.15808)
CNNとのハイブリッドモデル。PVTのように階層化されているが、それらの階層へ埋め込むときに畳み込みを使う。そのおかげで位置埋め込みも不要となる。加えて、Attentionの線形射影の代わりにも畳み込みを使う（トークンを2次元に成形してから適用する）。keyとvalueの射影にはストライド2にすると計算量を減らせる。

#### [PiT](https://arxiv.org/abs/2103.16302)
ストライド2のDepthWise Convによるプーリング構造を導入した。

#### [Cait](http://arxiv.org/abs/2103.17239)
Self AttentionとMLPのResBlockにおいて、元のinputにかける前に、残差に学習可能な対角行列パラメータをかける。また、クラストークンを最初に入力するのではなく、中間層から入力する。クラス入力後はSel Self Attentionの代わりに、Class Attentionを使う。Class Attentionはclass tokenをqueryに使い、他のtokenをkeyとvalueに使ったAttentionである。Class Token適用後はclass tokenのみ、MLPでシャッフルする。

#### [LeViT](http://arxiv.org/abs/2104.01136)
分類トークンをやめて、パッチ埋め込みの代わりにストライド2の畳み込みを複数回使う。また、Transformerも階層化し、同一階層の最後のAttentionでは、$\mathbf{q}$の射影にストライド2を適用する。位置埋め込みの代わりに、Attentionでバイアスを注入している。その他にも「keyの次元を減らす。」、「Hardswishを使用する」、「正規化の位置を変更する」などの工夫をしている。

#### [Nest](http://arxiv.org/abs/2105.12723)
画像パッチをブロックにわけて、それらを別画像のようにTransformerのEncoderに入力する。その出力を畳み込みとプーリングを使って行い、ブロックをマージして、同様の操作を繰り返し適用する。収束が早く、画像生成にも有効であるようである。

#### [XCiT](http://arxiv.org/abs/2106.09681)
転置版のAttentionを使う。これまでのSelf Attentionはトークン数に依存して計算量が増えたが、$\mathbf{k}^{\top}\mathbf{q}$を使うことで、計算量が$D_h$に依存するから、高解像度の画像であっても効率的に処理できる。

#### [CrossFormer](http://arxiv.org/abs/2108.00154)
さまざまなパッチサイズの埋め込みを結合した埋め込みを使っている。また、長短距離Attention（Self-Attentionを長距離用と短距離用でわけた）を使ったアーキテクチャ。Attention時に加えるバイアスはパラメータではなく、お手製のMLPベースのモジュールで出力された値を使っている。

#### [Mobile-Former](https://arxiv.org/abs/2108.05895)
MobileNetベースのアーキテクチャとTransformerベースのアーキテクチャが並列的に設計されている。ただし、MobileNetのボトルネック部分(次元が低いところ)で相互にAttentionが入っているため、CNNとTransformerが互いに影響を及ぼしながら学習できる。CrossViTに近いか？

### MLP-basedモデル

#### [MLP-Mixer](http://arxiv.org/abs/2105.01601)
ViTのSelf-Attentionをトークン同士を混ぜるようなMLP(token-mixing MLP)に置き換えただけのシンプルなアーキテクチャでも、それなりの精度が達成できることについて言及した。token-mixing MLPが位置埋め込みの役割も吸収するため、位置埋め込みなしでも機能する。クラストークンは使用していない。

#### [FF](http://arxiv.org/abs/2105.02723)
位置埋め込みがあり、クラストークンが使用されている以外は、MLP-Mixerとほぼ同じ。

#### [ResMLP](http://arxiv.org/abs/2105.03404)
Layer Normalization の代わりにAffine層を使っているが、それ以外はMLP-Mixerとほぼ同じ。

#### [gMLP](http://arxiv.org/abs/2105.08050)
トークンを混ぜる部分にゲート構造を採用している。

#### [$S^2$-MLP](http://arxiv.org/abs/2106.07477), [$S^2$-MLPv2](http://arxiv.org/abs/2108.01072)
$S^2$-MLPは、token-mixing MLPの代わりにチャンネルを左右上下に１ピクセルずつずらしている。$S^2$-MLPv2は更に進めて、Vision Permutatorに似た分岐構造を採用している。この操作は学習パラメータがないDepthWise Convと等価なので、これをMLPベースと言っていいのか疑問。

#### [Vision Permutator](https://arxiv.org/abs/2106.12368)
token-mixing MLPの代わりに、チャンネル用のMLPと、高さ方向とチャンネルを同時にまぜるMLP、幅方向とチャンネルを同時にまぜるMLPをそれぞれ適用し、連結する。

#### [Rethinking Token-Mixing MLP](http://arxiv.org/abs/2106.14882)
token-mixing MLPに巡回構造を持つ重み行列を使用することでパラメータを削減した。またチャンネル次元に沿ってグループわけを行い、異なるグループには別の重み行列を使用してトークン方向に混ぜる。巡回構造を持つ重み行列をかける計算は、高速フーリエ変換を使うと計算量が$\mathcal{O}(N^2)$から$\mathcal{O}(N\log{N})$に削減できる。

#### [AS-MLP](http://arxiv.org/abs/2107.08391)
token-mixing MLPの代わりに、高さ方向と幅方向のMLPを並列につなぐ。それぞれのMLPの適用時に、高さ方向と幅方向で少しずつずらしてから適用する。

#### [CycleMLP](http://arxiv.org/abs/2107.10224)
token-mixing MLPの代わりに、ギザギザにチャンネル横断するようなMLPを適用する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630841/f99c57f2-89f9-1c7c-17b3-ab47afcc7a9e.png)

#### [RaftMLP](http://arxiv.org/abs/2108.04384)
MLP-Mixerのtoken-mixing MLPを、複数チャンネルを結合した上で、水平方向と垂直方向に直列で適用する構造を取り入れた。

#### [MOI-Mixer](http://arxiv.org/abs/2108.07505)
MLP-Mixerのtoken-mixing MLPを並列化して、結合部分をアダマール積を使用した。画像分類ではなくレコメンドタスクに適用。

### その他のモデル

#### [LambdaNetworks](http://arxiv.org/abs/2102.08602)
Attentionの代わりに、${\rm softmax}(\mathbf{E}+\mathbf{k}^{\top})\mathbf{v}$を先に計算することで、$N^2$回の内積計算をする必要がなくなる。$D_h$は小さくしてもよいので、コスト削減につながる。EfficientNetと比べて速く、ハイブリッドモデルも有効である。

### ViT系のモデルの考察など

#### [Do Vision Transformers See Like Convolutional Neural Networks?](http://arxiv.org/abs/2108.08810)

ViTに関する詳細な調査


## 動かしてみた
お試しで、CIFAR100を使用して学習を行ってみた。今回はlucidrains/vit-pytorchの実装を使用したため、事前学習済みの重みは使用しておらず、さらにハイパーパラメータは適当である（timmを使用すれば事前学習済みのモデルは利用しやすい）。

* 埋め込む次元: 192
* MLPの次元: 576
* 深さ: 12
* アテンションのヘッド数: 16
* バッチサイズ: 32
* オプティマイザ
    * AdamW
    * 重み減衰: 0.1
    * 最大学習率: 1e-3
    * 終了学習率: 1e-5
    * 最初の3epochsは0から最大学習率まで線形に増やし、その後1e-5までcos減衰(21epochs)
* パッチサイズ2,4,8の3パターン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630841/95d61fd0-6501-f772-40be-da598bb13db0.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630841/4fe5711e-d434-f4fc-0d1f-245ffaa8709f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630841/f658691e-6e8b-764e-1d76-423e84487c10.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630841/1566d3bf-b5c7-923c-ccc5-5be15aee6827.png)

## 参考文献
1. https://github.com/lucidrains/vit-pytorch
1. Dosovitskiy, Alexey, Lucas Beyer, Alexander Kolesnikov, Dirk Weissenborn, Xiaohua Zhai, Thomas Unterthiner, Mostafa Dehghani, et al. 2020. “An Image Is Worth 16x16 Words: Transformers for Image Recognition at Scale.” arXiv [cs.CV]. arXiv. http://arxiv.org/abs/2010.11929.
1. Devlin, Jacob, Ming-Wei Chang, Kenton Lee, and Kristina Toutanova. 2018. “BERT: Pre-Training of Deep Bidirectional Transformers for Language Understanding.” arXiv [cs.CL]. arXiv. http://arxiv.org/abs/1810.04805.
1. Vaswani, Ashish, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N. Gomez, Łukasz Kaiser, and Illia Polosukhin. 2017. “Attention Is All You Need.” In Advances in Neural Information Processing Systems, 5998–6008. papers.nips.cc.
1. Touvron, Hugo, Matthieu Cord, Matthijs Douze, Francisco Massa, Alexandre Sablayrolles, and Herve Jegou. 2021. “Training Data-Efficient Image Transformers & Distillation through Attention.” In Proceedings of the 38th International Conference on Machine Learning, edited by Marina Meila and Tong Zhang, 139:10347–57. Proceedings of Machine Learning Research. PMLR.
1. Yuan, Li, Yunpeng Chen, Tao Wang, Weihao Yu, Yujun Shi, Zihang Jiang, Francis E. H. Tay, Jiashi Feng, and Shuicheng Yan. 2021. “Tokens-to-Token ViT: Training Vision Transformers from Scratch on ImageNet.” arXiv [cs.CV]. arXiv. http://arxiv.org/abs/2101.11986.
1. Wang, Wenhai, Enze Xie, Xiang Li, Deng-Ping Fan, Kaitao Song, Ding Liang, Tong Lu, Ping Luo, and Ling Shao. 2021. “Pyramid Vision Transformer: A Versatile Backbone for Dense Prediction without Convolutions.” arXiv [cs.CV]. arXiv. http://arxiv.org/abs/2102.12122.
1. Han, Kai, An Xiao, Enhua Wu, Jianyuan Guo, Chunjing Xu, and Yunhe Wang. 2021. “Transformer in Transformer.” arXiv [cs.CV]. arXiv. http://arxiv.org/abs/2103.00112.
1. Zhou, Daquan, Bingyi Kang, Xiaojie Jin, Linjie Yang, Xiaochen Lian, Zihang Jiang, Qibin Hou, and Jiashi Feng. 2021. “DeepViT: Towards Deeper Vision Transformer.” arXiv [cs.CV]. arXiv. http://arxiv.org/abs/2103.11886.
1. Liu, Ze, Yutong Lin, Yue Cao, Han Hu, Yixuan Wei, Zheng Zhang, Stephen Lin, and Baining Guo. 2021. “Swin Transformer: Hierarchical Vision Transformer Using Shifted Windows.” arXiv [cs.CV]. arXiv. http://arxiv.org/abs/2103.14030.
1. Chen, Chun-Fu, Quanfu Fan, and Rameswar Panda. 2021. “CrossViT: Cross-Attention Multi-Scale Vision Transformer for Image Classification.” arXiv [cs.CV]. arXiv. http://arxiv.org/abs/2103.14899.
1. Wu, Haiping, Bin Xiao, Noel Codella, Mengchen Liu, Xiyang Dai, Lu Yuan, and Lei Zhang. 2021. “CvT: Introducing Convolutions to Vision Transformers.” arXiv [cs.CV]. arXiv. http://arxiv.org/abs/2103.15808.
1. Heo, Byeongho, Sangdoo Yun, Dongyoon Han, Sanghyuk Chun, Junsuk Choe, and Seong Joon Oh. 2021. “Rethinking Spatial Dimensions of Vision Transformers.” arXiv [cs.CV]. arXiv. http://arxiv.org/abs/2103.16302.
3. Touvron, Hugo, Matthieu Cord, Alexandre Sablayrolles, Gabriel Synnaeve, and Hervé Jégou. 2021. “Going Deeper with Image Transformers.” arXiv [cs.CV]. arXiv. http://arxiv.org/abs/2103.17239.
1. Graham, Ben, Alaaeldin El-Nouby, Hugo Touvron, Pierre Stock, Armand Joulin, Hervé Jégou, and Matthijs Douze. 2021. “LeViT: A Vision Transformer in ConvNet’s Clothing for Faster Inference.” arXiv [cs.CV]. arXiv. http://arxiv.org/abs/2104.01136.
5. Zhang, Zizhao, Han Zhang, Long Zhao, Ting Chen, and Tomas Pfister. 2021. “Aggregating Nested Transformers.” arXiv [cs.CV]. arXiv. http://arxiv.org/abs/2105.12723.
6. El-Nouby, Alaaeldin, Hugo Touvron, Mathilde Caron, Piotr Bojanowski, Matthijs Douze, Armand Joulin, Ivan Laptev, et al. 2021. “XCiT: Cross-Covariance Image Transformers.” arXiv [cs.CV]. arXiv. http://arxiv.org/abs/2106.09681.
7. Wang, Wenxiao, Lu Yao, Long Chen, Deng Cai, Xiaofei He, and Wei Liu. 2021. “CrossFormer: A Versatile Vision Transformer Based on Cross-Scale Attention.” arXiv [cs.CV]. arXiv. http://arxiv.org/abs/2108.00154.
8. Chen, Y., X. Dai, D. Chen, M. Liu, X. Dong, and L. Yuan. 2021. “Mobile-Former: Bridging MobileNet and Transformer.” arXiv Preprint arXiv. https://arxiv.org/abs/2108.05895.
9. Tolstikhin, Ilya, Neil Houlsby, Alexander Kolesnikov, Lucas Beyer, Xiaohua Zhai, Thomas Unterthiner, Jessica Yung, et al. 2021. “MLP-Mixer: An All-MLP Architecture for Vision.” arXiv [cs.CV]. arXiv. http://arxiv.org/abs/2105.01601.
10. Melas-Kyriazi, Luke. 2021. “Do You Even Need Attention? A Stack of Feed-Forward Layers Does Surprisingly Well on ImageNet.” arXiv [cs.CV]. arXiv. http://arxiv.org/abs/2105.02723.
11. Touvron, Hugo, Piotr Bojanowski, Mathilde Caron, Matthieu Cord, Alaaeldin El-Nouby, Edouard Grave, Gautier Izacard, et al. 2021. “ResMLP: Feedforward Networks for Image Classification with Data-Efficient Training.” http://arxiv.org/abs/2105.03404.
12. Liu, Hanxiao, Zihang Dai, David R. So, and Quoc V. Le. 2021. “Pay Attention to MLPs.” arXiv [cs.LG]. arXiv. http://arxiv.org/abs/2105.08050.
13. Yu, Tan, Xu Li, Yunfeng Cai, Mingming Sun, and Ping Li. 2021. “S2-MLP: Spatial-Shift MLP Architecture for Vision.” arXiv [cs.CV]. arXiv. http://arxiv.org/abs/2106.07477.
14. Hou, Qibin, Zihang Jiang, Li Yuan, Ming-Ming Cheng, Shuicheng Yan, and Jiashi Feng. 2021. “Vision Permutator: A Permutable MLP-Like Architecture for Visual Recognition,” 1–12.
15. Yu, Tan, Xu Li, Yunfeng Cai, Mingming Sun, and Ping Li. 2021. “Rethinking Token-Mixing MLP for MLP-Based Vision Backbone.” arXiv [cs.CV]. arXiv. http://arxiv.org/abs/2106.14882.
16. Lian, Dongze, Zehao Yu, Xing Sun, and Shenghua Gao. 2021. “AS-MLP: An Axial Shifted MLP Architecture for Vision.” arXiv [cs.CV]. arXiv. http://arxiv.org/abs/2107.08391.
17. Chen, Shoufa, Enze Xie, Chongjian Ge, Ding Liang, and Ping Luo. 2021. “CycleMLP: A MLP-like Architecture for Dense Prediction.” arXiv [cs.CV]. arXiv. http://arxiv.org/abs/2107.10224.
18. Yu, Tan, Xu Li, Yunfeng Cai, Mingming Sun, and Ping Li. 2021. “S2-MLPv2: Improved Spatial-Shift MLP Architecture for Vision.” arXiv [cs.CV]. arXiv. http://arxiv.org/abs/2108.01072.
19. Tatsunami, Yuki, and Masato Taki. 2021. “RaftMLP: Do MLP-Based Models Dream of Winning Over Computer Vision?” arXiv [cs.CV]. arXiv. http://arxiv.org/abs/2108.04384.
20. Lee, Hojoon, Dongyoon Hwang, Sunghwan Hong, Changyeon Kim, Seungryong Kim, and Jaegul Choo. 2021. “MOI-Mixer: Improving MLP-Mixer with Multi Order Interactions in Sequential Recommendation.” arXiv [cs.LG]. arXiv. http://arxiv.org/abs/2108.07505.
21. Raghu, Maithra, Thomas Unterthiner, Simon Kornblith, Chiyuan Zhang, and Alexey Dosovitskiy. 2021. “Do Vision Transformers See Like Convolutional Neural Networks?” arXiv [cs.CV]. arXiv. http://arxiv.org/abs/2108.08810.
22. Bello, Irwan. 2021. “LambdaNetworks: Modeling Long-Range Interactions Without Attention.” arXiv [cs.CV]. arXiv. http://arxiv.org/abs/2102.08602.
23. Raghu, Maithra, Thomas Unterthiner, Simon Kornblith, Chiyuan Zhang, and Alexey Dosovitskiy. 2021. “Do Vision Transformers See Like Convolutional Neural Networks?” arXiv [cs.CV]. arXiv. http://arxiv.org/abs/2108.08810.