CNNの代表的なモデルと手法

Python, ML07 January 2021

AlexNet

  • 2012年のILSVRC(ImageNet Large Scale Visual Recognition Challenge) で優勝したモデル
  • このモデルが当時すごい精度を出したので、DeepLearningに火がついた
  • 当時はGPUが足らなかったので、ネットワークを並列にした変則的な形になっている
  • NNにおいて多層にすると精度が上がるということも、本モデルによって示された
  • 2021年現在は使用されることはない

VGG16

  • 2014年のILSVRCで出てきたモデル
  • シンプルでそこそこ精度出る
  • 当時Poolingの縮小サイズや、フィルタ(カーネル)のサイズ・ストライドなどの値は、試してみて良い物を使用するという流れだったが、本モデルが理論立てて解析し、最適解を提案した
    • 3✖️3(フィルタサイズ)の畳み込みを繰り返す
    • MaxPoolingを1回挟み、画像を1/2に縮小する
    • MaxPooling後はチャンネル数を2倍にする
  • 基本はこの後に出てきた改良版のモデルも上記の理論に従う事になる
    • 自身でCNNを自作するときもこれに従うと良い

VGG16のデメリット

  • フィルタ(カーネル)サイズが大きすぎる
    • 重みパラメータが多くて最適化が困難
  • Pooling時のストライドが大きすぎる
    • 元画像の情報が失われすぎる

なぜ3✖️3なのか?

  • 現代ではほとんどがVGG16に従い、3✖️3の畳み込みをしている
  • 5✖️5の畳みこみと3✖️3の畳み込みを2回行うことは、実質画像上で見る(畳み込む)範囲は同じだと考えられる
    • 3✖️3で畳み込みしたものをもう一度畳み込む
  • 同じ範囲を見れるなら、当然パラメータの少ない3✖️3が適切である

GoogLeNet

  • 2014年のILSVRCで優勝したモデル
  • 複雑で使いづらい
    • 改良しづらい

Inceptionモジュール

  • モジュールというある程度の1部のネットワークをまとめた概念が生まれた
    • 現在ではこのモジュール単位での取り扱いが主流になっている
    • モジュールを連結させてネットワークを構築する
  • 1✖️1の畳み込みを使っていく手法もここから生まれた
  • 1✖️1や3✖️3の畳み込みをいた後にそれらを合体させてる
  • スパースな畳み込みとも言う

1✖️1の畳み込み

  • チャンネル方向のみの畳み込みをする
  • 各チャンネルごとに重みをかけて計算してるのと同等
  • 該当範囲(画像ならピクセル)において、重要なチャンネルの情報は残し、役に立たないチャンネルは削除することができる

Global Average Pooling

  • CNNで畳み込みの後最後のFC層でパラメータが増えるのを避けたいためにできた
  • 最後の出力を画像の幅と高さが1✖️1になるようにAverage Pooling(平均でPooling)する
  • 必ずと言っていいほど使用する

Residual Network(ResNet)

そもそもDLの考え

  • 基本的に層を増やせば増やすほど良い
  • ただ、50層とかを超えてくると精度が下がる
  • 今までは50層くらいしか増やせなかったのを、ResNetは1000層くらいまで増やした
    • 一応限界は勿論ある

どうやる?

  • 多層のネットワークはおそらく最後の層では改善することがなくなるはず
    • 何もしないで入力をそのまま出力に出してあげたい
    • CNNでは入力に対してパラメータが極端に少ないと言う特性があるので、難しい
    • この考え方は後に誤りだったと判明する
  • 出力を0にして、あとで入力を足せばいい

x: 入力 y: 出力

$$ f(x)=x-y $$

結果的に、上記を求めればいい

計算も簡単、パラメータもほとんど増えない。デメリットなし

勾配消失を避ける

  • 層が多いと勾配消失する可能性が上がる
  • ResNetは上記のバイパスによる値の流れがあるので、バックプロパゲーションで入力層にも誤差が伝わりやすい

研究者の主張

  • 不要な層は恒等写像として出力する=削除しても問題ない
  • ResNetはそれを実現した

最近の研究結果

  • 不要な層以外も削除してみて結果をみたら精度がほぼ変わらなかった
    • つまりそれぞれが対して仕事をしてない(影響を与えてないと考えられる)
  • 結果としてResNetが精度をあげるのは、アンサンブル学習(バギング)的な働きをするから

DenseNet

  • ResNetは必ず次の層に対してバイパスを作ってたが。これは次の層だけでなく、もっと先の層にも流す
    • 精度はすごく上がる
    • めちゃくちゃ遅いので使用されない

## ResNext - ResNetの処理をモジュール単位で行うようなネットワーク - ResNetとInceptionモジュールの合併みたいな

Xception

  • 普通の畳み込みを行わすに以下のような畳み込みを行う
  • 計算が少し早くなる
    • 実質フィルタサイズの2乗分早くなるが実際はGPUやCPUの稼働的にそこまではならない

Depthwise Separable Convolution

以下の二つの組み合わせ

  • Depthwise Convolution
    • チャンネルごとに畳み込みを行う(k✖️k✖️1)
  • Pointwise Convolution
    • 1✖️1✖️C

MobileNet

  • とにかく小さくて早くしたい
  • 精度はある程度でいいからと言うモチベーション
  • スマホにも乗せれるレベル

仕組み

  • Depthwise Separable Convolutionを使う
  • 1✖️1の畳み込みを多用する
  • v2
  • v3
    • 一部の層の活性化関数で「h-swish(Swishの改良版)」を使用
    • Squeeze-and-Excitation (SE Block) を導入

UNet

  • 画像を入力しそれとほぼ同等の形状の画像を出力する
    • semantic segmentation
  • MaxPoolingを行うとその分解像度が下がる
  • MaxPoolingする前の高解像度の時の特徴も使っていく

tags: Python, ML