KerasのCNNで使うpaddingのめも

こんにちは、ぐぐりら(@guglilac)です。
プログラミングの記事の記念すべき初投稿!

まずはお試しということで、deep learningのフレームワークであるkerasを使ってて疑問に思ったことをサクッとめもる記事。



paddingとは


CNNで出てくるレイヤーは畳み込み層(convolution layer)とプーリング層(pooling layer)などがありますが、どっちにもpaddingを設定できるとこがあります。

ちなみにpaddingとは、畳み込みやプーリングを行う際に入力の周辺を0で埋めてやることを言います。

paddingする利点はこんなかんじ。

  1. 入力の端に存在する要素のたたみ込まれる回数が増えるので端の情報をより拾うようになる
  2. データの大きさをある程度保持できる(小さくなりすぎるのを防ぐ)

padding=sameってなにがsameなんじゃ


って思ったのでドキュメント読んでみました。

すると、Conv1dレイヤーの説明にちょこっと

"same"は元の入力と同じ長さを出力がもつように入力にパディングします.

との文言が。
なるほど、入出力が同じ大きさになるからsameなのかー

でも、自分で書いてみたときpoolingレイヤーでpadding=sameにしたのに同じ大きさにならなかったんだよなあ。だからこの記事書き始めたというわけなので、このままでは納得できません。

paddingの説明が腑に落ちず他にも調べてみたらこんな記事を見つけました。
kerasではなくTensorFlowの記事ですがだいたい同じ。なはず。

Tensorflow - padding = VALID/SAMEの違いについて

この記事を参考に、padding=sameの意味を自分の言葉で説明すると

padding=sameにすると、入力の大きさをstridesの大きさで単純に割ったものが出力の大きさになります。

stridesとは、convolutionやpoolingに使うフィルターをどのくらいの幅で動かしていくかという移動量のこと。

ということは原因はstridesにありそう!と思い自分のコードを見ると、なぜかstridesを指定していない!!笑

ドキュメントのstridesの欄をみてみるとわかり
stridesのデフォルトの値の決め方がconvとpoolingで異なることが原因でした。


convolutionレイヤーでは、stridesを指定しないと、stridesは1になります。
つまり1マスずつフィルターを移動させていくかんじ。
padding=sameかつstrides未指定だと、入力サイズを1で割るので確かに入出力のサイズは同じになります。ちゃんとsame感でてます。

一方、poolingレイヤーでstrides未指定の場合、stiridesの大きさはフィルターのサイズと同じ値で設定されるようになっています。
poolingフィルターのサイズを普通1にはしないので、poolingレイヤーでstridesを未指定にするとほぼ確実に入出力のサイズはsameにはなりません。

まとめ


convolutionレイヤーは確かにsameになってるけど、poolingレイヤーはsameじゃなくなりがち。
poolingのstridesはサボらずちゃんと設定しよう。(自戒)




コメント