"BOKU"のITな日常

還暦越えの文系システムエンジニアの”BOKU”は新しいことが大好きです。

CNNのプーリング層「MaxPooling」の仕組みを数式なしで整理してみた/ディープラーニング

今回はPoolingレイヤーについて、頭の整理を兼ねて、ざっくり整理してみます。

Pooling層は、画像認識に優れた性能がある「CNN(Convolutional Neural Network)」の構成要素のひとつですね。

f:id:arakan_no_boku:20190330090249j:plain

 

 

Pooling層って何が目的?

 

Pooling層の目的は、「特徴をより強調する」ことです。

結局。

機械学習でやりたいことは、「違いを識別できる特徴を抽出する」ことですから。

画像を構成する要素の中で、より強い要素を際立たせるのが有効な対策になりえるだろうというのは、納得感があります。

だからPooling層のすることは、Convolutionで出力されてきた数値の特徴をより際立たせるために、もうひと手間加工するってことです。

とはいえ。

Pooling層と言っても種類があります。

Neural Network Consoleにも様々な種類のPoolingレイヤーが用意されてます。

それらを全部・・というと大変なので、、頻繁に使う代表的な「MaxPooling」に絞って整理します。

 

 

MaxPolingの具体例

 

ちなみにリファレンスマニュアルの説明にはこう書いてあります。

MaxPooling
近傍の入力値の最大値を出力します

これを読んで。

  • 近傍ってなんだ?
  • それを出力したら、何が良いんだ?

とか思った人だけ、続きを読んでください(笑)

さて。

まず例として、以下のような簡単なデータを使います。

f:id:arakan_no_boku:20181112220545j:plain

これをConvolutionの出力と考えます。

リファレンスでの「近傍」は、Poolingの入力=Convolutionの出力のことです。

MaxPoolingのやることは、事前に決めた範囲の中の「最大の数字」だけを出力する。

ただ、それだけです。

その事前に決めた範囲のことを、フィルターとかカーネルと呼びます。

 

今回のサンプルにするフィルター(カーネル)のサイズは、2×2にします。

元データよりフィルターは小さいですから、全体をカバーするために、1か所やったら、位置をずらして、また次をする・・みたいに処理していきます。

この位置をずらす大きさのことを、Strids(ストライド)といいます。

今回はこれも2×2にします。

Poolingの処理は、左上からはじめます。

まず。

2行2列の範囲の中で、一番大きい数字を選んで出力します。

f:id:arakan_no_boku:20181112221107j:plain

つぎに、右に2列分ずらして、同様に2行2列の中で最も大きい数字だけ出力します。

f:id:arakan_no_boku:20181112221202j:plain

つぎに、下に2行分ずらして、左側から2行2列の中で最も大きい数字を出力します。

f:id:arakan_no_boku:20181112221433j:plain

あとは同様に右に2列ずらして同じことをします。

f:id:arakan_no_boku:20181112221513j:plain

これが、MaxPoolingがやっていることです。

シンプルそのものです。

 

ConvolutionとPoolingは必ずセットで必要なのか

 

CNN(Convolutional Neural Network)の場合、基本的にConvolutionとPoolingはセットで使います。

たとえば、こんな感じで。

f:id:arakan_no_boku:20181112224225j:plain

では、このMaxPoolingがなくなると、どうなるんだろう?

学習の精度は大きく落ちるのか?

などの疑問がわいてきます。

疑問がわいたら、やってみようということで、以下みたいなモデルをくんでやってみました。

f:id:arakan_no_boku:20181112224516j:plain

MaxPoolingをとっぱらって、Convolutionだけを3つ重ねてます。

かなり、違和感バリバリです。

これでMNISTを学習・評価してみると。

f:id:arakan_no_boku:20181112224826j:plain

おーー。

97.8%・・。

あまり、良くはありません。

でも、Pooling層がなければ、無茶苦茶になるわけでもない。

こういう微妙な結果になるのは、Pooling層の役割が「特徴をより絞り込む」ことにあるからなんでしょうね。

 

使ってはいけないケースもありうる

 

こうやって、何をしているのかわかると、イメージができます。

例えば。

画像を学習させて、細部にいたるまで復元に近い状態にしたい場合とかは、Pooling層を使っちゃダメだろうな・・とか。

だって、細かい特徴を切り落としてしまいますからね。

逆に、大きな括りで分類できればいい・・みたいな用途だと、Pooling層は結構有効にきくだろうなってものわかります。

共通の際立った特徴だけを抽出する役目を果たしてくれるわけですから。

そういうイメージができる、できないって、重要じゃないのかな。

個人的にはそう思うわけです。

ではでは。