ありまっくすのへっぽこ日記

アラフォーでへっぽこエンジニアをしております。へっぽこなりに頑張っています。

DeepLearning講座(第3回)を受けてきたよ

5/11(金)に、DeepLearning講座の第3回目を受けてきました。

テーマはResNet。

ResNetはCNNを改良したもので、非常に性能が良いものと言われています。

その前に前回の復習

 なんでPoolingをするの?

画像を小さくすることによって、計算速度が速くなるが、本来の目的は位置普遍性を持たせるため。畳み込み(Conv)をすると位置は変わらないため、同じ「A」なのに違うものとして認識されてしまいます。

f:id:ari_max:20180518213513p:plain

プーリング

なぜ活性化関数をかませるのか

線形のものは掛け算しても傾きが変わるだけで、意味のある変換ができない。

f:id:ari_max:20180518214506p:plain

線形の変換



ReLuのように非線形のものは掛け算すると意味のある変換ができる

f:id:ari_max:20180519073510p:plain

ReLUの変換

良いモデルって何? 

 良いモデルというのは、以下の条件を満たすものです。

  • 精度が高い
  • パラメータの数が少ない

 

パラメータの数が少なければ、学習速度も認識速度も速くなります。過学習もしにくくなります。 パラメータが少なくして、精度を出すというのがポイントなのです。(それができたら苦労しないけど)

 パラメータ数は1M(M=1,000,000)から5Mくらいが普通。10M越えると多すぎです。

 

 

ResNetとは

Residual Networkの略で、CNNを改良したものです。2015年にMicrosoft Researchが提唱しました。

CNNといえばResNetと言われるくらいのもので、画像認識のだいたいがわかるそうです。移り変わりの激しいDeepLearning界隈で、3年も使われているという優れものです。

どこが優れているかというと、

超多層のネットワークが作れるということです。

 

ニューラルネットワークは層が多ければ多いほど性能が向上するのです。が、以下の問題が発生します。

  • 勾配消失する
  • 特徴が後ろの層まで伝わらない

これを解決するのが、ResNetです。

ResNetは何をするのかというと、「ショートカット」です。

f:id:ari_max:20180520205928p:plain

ResNetではショートカットを行う。

ショートカットを追加するとなぜうまくいくのかというと。。。

  • 入力が最適ならw(重み)は全て0にできる。
  • 最適に近い状態ならwを少しだけ更新することもできる
  • 情報消失が起こりにくい
  • 誤差が伝わりにくい 
  • アンサンブル効果を期待できる(適当にブロックを削除してもあまり精度に影響しない)

 超多層ネットワークの場合、最後の方は「やることがなくなる」はず。

「何もしないようにする」のがResNetなのです。 

 ResNetの中身

ResNetは実際どのような処理を行っているのでしょうか。

下の図のようにコンボリューションの組み合わせにショートカットを加えたものです。コンボリューションを行わず、そのまま足してしまいます。次元の変更がないわけです。 以下の図のような処理のかたまりをResモジュールといい、Resモジュールを何層も組み合わせていきます。

ResモジュールをどうするかというのがResNetのキモになってきます。(色々研究されています)

f:id:ari_max:20180523062836p:plain

ReNetの中身



最新手法とトレンド

ResNetの性能をもっと出すために、色々な手法が提案されています。

ResBlock自体を改造する

層を増やす(BottleNeck)

以下の図のように畳み込みを行う層を増やすという方法があります。

(パラメータ数を増やさずに層を増やしている)

f:id:ari_max:20180523062851p:plain

conv層を増やしたResNet

ショートカットした後は「何もしない」と性能が出ます。

BatchNormalizationした後に処理されるので、ショートカット時のBatchNormalizationは不要なのです。

f:id:ari_max:20180523064501j:plain

  • 足した後に色々操作するのは良くない
  • 足す前にActivation(ReLUなど)しておいた方がいい 
  • ReLUは一つにする

ResNet改良版にはこんなものがあります。

  • WideResNet
  • PyramidNet

独自のブロック

順番を変えるだけでなく、思い切って違う仕組みを取り入れる方法です。

 ResNeXt

入力を分岐させて並列に処理するものです。分岐する数をC(cardinality,濃度)と呼びます。 (分岐の数が1のものがResNet)

ある程度のアンサンブル効果が望めます。

 Xception

ResNetは時間がかかる。。。

計算量の大半はconvolutionなので、Depthwise畳み込みとPointwise畳み込みを組み合わせて使うという手法です。

  • Depthwise畳み込み→チャネル数を1にする
  • Pointwise畳み込み→フィルタのサイズを1×1にする

どうしてこんなことをするのか。。。

入力が H × W × N, 出力チャネル数 M, フィルタサイズ K× K の畳み込みを考えてみると。

  • 普通の畳み込みの計算量 H × W × N × K × K × M
  • Depthwise畳み込み計算量 H × W × N × K × K
  • Pointwise畳み込み計算量 H × W × N × M

普通は M >> K × K なので、

Depthwise畳み込み計算量+Pointwise畳み込み計算量  < 普通の畳み込みの計算量となるわけです。

空間方向とチャネル方向は独立しているので、分けて畳み込みをしても問題はない。

と言われています。

正則化

DeepLearningはとにかく過学習しやすいので、色々な方法で正則化します。

中でも使われている方法は以下です。

StochasticDepth

ResBlockそのものをDropOutする方法で、GANでも使っています。

最後の方は50%ぐらいの確率でDropOutしています。 

f:id:ari_max:20180523204606p:plain

メリットは以下の通りです。

  • 期待値で見たときの深さが短くなる
  • 正則化が期待できる(ランダムにDropOutすることにより、いいフローにしなくてはならない)
  • なぜ、出力層に近い層ほどDropするのかは経験則
Cutout and Random Erasing

 お手軽な割に簡単に性能が上がる。実はCNNに対してはDropOutが有効でない。

  • もともとパラメータが少ない。
  • 隣接画素を推測できる(隣もきっと同じような色だろう。。。)

Random Eragingはランダムにモザイクのようなものをかける

高速化

高速化するためにいくつか方法があります。

SqueezeNet

特別性能が出るわけではないが、小さくて速くてそこそこ性能が出るので人気だそうです。Fire Moduleをつなぎ合わせています。

  • 3×3のフィルタを1×1にする
  • 3×3のチャネルを減らす

f:id:ari_max:20180523233217p:plain

https://openreview.net/pdf?id=S1xh5sYgx

評価

GoogleNetやVGGは時代遅れ。。。

Wide Pyramid Denseは性能が良い。SqueezeNetは速い。

正則化はCutoutがおすすめとのことです。(時間が増えない割に性能が出る)