Skip to content

digeon-inc/survey-computer-vision

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

survey-computer-vision

textlint

$ yarn install
$ npx textlint README.md

AlexNet

論文概要

どんなもの?

ImageNet Classification with Deep Convolutional Neural Networks

2012年のILSVRCというImageNetを用いた画像分類コンペで圧勝したモデル。

先行研究と比べてどこがすごい?

2012年までは人間が画像から特徴量を設計し、それを用いて分類を行っていたが、AlexNetが2012年のILSVRCで圧勝したことにより機械によって特徴量を抽出できることが示された。また当時、畳み込み演算を含む大規模なCNNを学習することはコストの面で難しかったが、GPUに最適化された畳み込み演算の実装を行うことで学習時間を短縮した。

技術や手法のキモはどこ?

  • ReLU
    • シグモイド関数やtanh関数などの非線形関数よりも数倍速く学習できる
    • 勾配消失対策
  • GPUによる並列計算
    • ネットワークの中の一部のみでGPU間の通信を行うことで、計算を効率化した。
  • ReLUと輝度の正規化の組み合わせが良かった。
  • Overlapping Pooling
    • プーリング層でダウンサンプルする領域を少しずつ被せることで過学習しにくくなった
  • Dropoutで過学習を防いだ。
  • 水平移動や反転などのData Argumentationによって教師データを増やした。

どうやって有効だと検証した?

ImageNetの2011年秋の版で事前学習したAlexNetを2012年のILSVRCでfine tuningすると、テストデータにおいてエラー率は15.3%となった。

議論はある?

中間層をひとつでも取り除くとネットワークの性能が低下するので、ネットワークの深さは非常に重要である。教師データを増やさずにネットワークを大きくしたり、教師なしの事前学習でさらなる性能が得られるかもしれない。

次に読むべき論文は?

アーキテクチャ詳細

画像は論文より引用

5層の畳み込み層と3層の全結合層からなる。

実装の参考

ResNet

論文概要

どんなもの?

Deep Residual Learning for Image Recognition

Microsoft Researchが2015年に提案したモデル。

先行研究と比べてどこがすごい?

当時、画像認識において一般にCNNの層数を増やすことでより高次元の特徴を獲得することは知られていたが、単純に層を重ねるだけでは性能が悪化していく勾配消失問題があった。ResNetではshortcut connectionという機構を導入し、手前の層の入力を後ろの層に直接足し合わせることで、この勾配消失問題を解決した。

技術や手法のキモはどこ?

画像は論文より引用

図の左側がbuilding blockと呼ばれ、右側がbottleneck building blockと呼ばれる。この構造によって勾配がより手前の層まで伝わるようになった。

どうやって有効だと検証した?

ILSVRCという毎年開催されていたImageNetを用いた画像分類コンペにおいて、2014年以前はせいぜい20層程度(VGGが16か19層、GoogleNetが22層)のモデルで競っていた。しかしResNetは152もの層を重ねて学習させることに成功し、2015年のILSVCRで優勝した。

議論はある?

次に読むべき論文は?

アーキテクチャ詳細

実装の参考

Transformer

論文概要

どんなもの?

Attention is All You Need

2017年に提案された自然言語処理のモデル。コンピュータビジョンのモデルではないものの、この論文で提案されたTransformerというアーキテクチャが後発のコンピュータビジョンのモデルに大きな影響を与えたので、ここで取り上げる。

先行研究と比べてどこがすごい?

当時、Seq2SeqのモデルではRNNやCNNと併用してAttentionを用いるものがあった。しかし、この論文ではRNNやCNNを排除してAttentionのみのTransformerというアーキテクチャを提案した。RNNを排除してAttentionや全結合層を用いることによって並列化が可能になって学習にかかる時間が削減された。さらに精度も向上し、入力と出力の文章離れた位置にある任意の依存関係を学習しやすくなった。

技術や手法のキモはどこ?

  • Scaled Dot Product Attention
    • まず、embeddingされた入力ベクトル(sequence_length, d_model)に対して、Query、Key、Valueを計算する。これらは入力ベクトルをそれぞれ重み行列Wq(d_model, d_q)、Wk(d_model, d_k)、Wv(d_model, d_v)で写像して得られる。この論文ではself-attentionを用いるのと、全く同じ構造のレイヤーを複数重ねるので、d_q、d_k、d_v、d_modelは全て等しい。
    • 各Queryと各Keyの内積にsoftmax関数を適用し、QueryとKeyの関連度を計算する。さらにこれをValueとの内積をとることで、各Queryと類似度の高いKeyに対応するValueほど重く重みづけされたValueの重み付き和が得られる。これは、入力のある部分に対して他のどの部分が重要になるかを抽出する操作とみなすことができる。
    • QueryとKeyの内積をで割っているのは、が大きくなったときにQueryとKeyの内積が大きくなり、softmaxの勾配が極端に小さくなっていまうのを防ぐためである。

Scaled Dot Product AttentionはPyTorchを用いて次のように実装できる。

class ScaledDotProductAttention(nn.Module):
    def __init__(self, d_model: int) -> None:
        """
        Args:
            d_model: embedded vector length
        """
        super().__init__()
        self.d_k: int = d_model
        self.w_q = nn.Linear(d_model, d_model, bias=False)
        self.w_k = nn.Linear(d_model, d_model, bias=False)
        self.w_v = nn.Linear(d_model, d_model, bias=False)
        self.out = nn.Linear(d_model, d_model, bias=False)

    def forward(self, x: torch.Tensor, mask: Optional[torch.BoolTensor] = None) -> torch.Tensor:
        """
        Args:
            x: input tensor [batch_size, sequence_length, d_model]
        Returns:
            out: torch.Tensor [batch_size, sequence_length, d_model]
        """
        query, key, value = self.w_q(x), self.w_k(x), self.w_v(x)
        query /= math.sqrt(self.d_k)
        attn_weight = torch.bmm(query, key.transpose(-2, -1))
        if mask is not None:
            attn_weight = attn_weight.masked_fill(mask, -1e9)
        attn_weight = functional.softmax(attn_weight, dim=-1)
        attn = torch.matmul(attn_weight, value)
        out = self.out(attn)
        return out
  • Multi Head Attention
    • 各単語に対して1組の次元のQuery、Key、Valueを持たせるのではなく、それらを種類の異なる重みベクトルにより写像したもので種類の異なるAttentionを計算する。それぞれのQuery、Key、Valueから構成されるAttention機構はheadと呼ばれ、それぞれで異なる部分空間から有益な情報を抽出することができる。 これによって、アンサンブルのような効果が得られる
    ただし

Multi Head Attentionは、Scaled Dot Product Attentionの実装を少し改変する事で実装できる。計算効率のため、各headに分割されたQuery, Key, Valueをそれぞれまとめて保持する。Query、Key、Valueのテンソルの形状は(batch_size, num_head, sequence_length, dim_per_head)のようになる。

class MultiHeadAttention(nn.Module):
    def __init__(self, d_model: int, num_head: int) -> None:
        """
        Args:
            d_model: embedded vector length
        """
        super().__init__()
        assert d_model % num_head == 0, f"d_model({d_model}) must be dividible by num_head({num_head})"
        self.d_k: int = d_model
        self.num_head: int = num_head
        self.dim_per_head: int = d_model // num_head
        self.w_q = nn.Linear(d_model, d_model, bias=False)
        self.w_k = nn.Linear(d_model, d_model, bias=False)
        self.w_v = nn.Linear(d_model, d_model, bias=False)
        self.out = nn.Linear(d_model, d_model, bias=False)

    def forward(
        self, x: torch.Tensor, mask: Optional[torch.BoolTensor] = None
    ) -> torch.Tensor:
        """
        Args:
            x: input tensor [batch_size, sequence_length, d_model]
        Returns:
            out: torch.Tensor [batch_size, sequence_length, d_model]
        """
        batch_size: int = x.size()[0]
        query: torch.Tensor = self.w_q(x)
        key: torch.Tensor = self.w_k(x)
        value: torch.Tensor = self.w_v(x)
        # [batch_size, sequence_length, d_model] -> [batch_size, sequence_length, num_head, dim_per_head] -> [batch_size, num_head, sequence_length, dim_per_head]
        query = query.view(batch_size, -1, self.num_head, self.dim_per_head).transpose(1,2)
        key = key.view(batch_size, -1, self.num_head, self.dim_per_head).transpose(1,2)
        value = value.view(batch_size, -1, self.num_head, self.dim_per_head).transpose(1,2)
        query /= math.sqrt(self.d_k)
        attn_weight = torch.matmul(query, key.transpose(2, 3))
        if mask is not None:
            attn_weight = attn_weight.masked_fill(mask, -1e9)
        attn_weight = functional.softmax(attn_weight, dim=-1)
        attn = torch.matmul(attn_weight, value)
        # [batch_size, num_head, sequence_length, dim_per_head] -> [batch_size, sequence_length, num_head, dim_per_head] -> [batch_size, sequence_length, d_model]
        attn = attn.transpose(1, 2).contiguous().view(batch_size, -1, self.d_k)
        out = self.out(attn)
        return out
  • Positional Encoding
    • 再帰や畳み込みを排除しているので、単語の順序把握するためにPositional Encodingを利用する。
    • ここではサインとコサインを用い、posを単語の位置、iをd_model、すなわち入力ベクトルの次元として以下のような式で計算する。計算した値は入力ベクトルに単に加算される。
    • Transformerはサインやコサインといった関数の形状を簡単に学習できるため、位置エンコーディングとしてこのような関数を利用している。

どうやって有効だと検証した?

WMT 2014 English-German、 WMT 2014 English-Frenchというデータセットで英語からドイツ語、フランス語への翻訳タスクを行った。結果は英語-ドイツ語翻訳タスクではBLEUスコア28.4、英語-フランス語翻訳タスクではBLEUスコア41.8でstate-of-the-artを達成した。

議論はある?

Attentionベースのモデルに期待しており、これをテキスト以外に画像、動画、音声などで活用できるようなAttentionを研究する予定だ。

次に読むべき論文は?

アーキテクチャ詳細

画像は論文より引用

  • DecoderのMasked Multi Head Attentionは、対象単語より左の単語のみに依存するように、softmaxの入力値を一部マスクしている。
  • Multi Head AttentionやFeed ForwardにはResidual構造がある。

実装の参考

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published