深層学習

プーリング

局所窓の値を集約して特徴マップの空間サイズを下げる層。最大値と平均値の選択、stride、位置ずれへの性質を実装と出力形状で整理します。

  • B|標準
  • 深層学習

数式の記号で止まったら 記号の読み方 (∂・⊙・転置・上付き添字を、読み方から)

ひとことで言うと

プーリング層は、特徴マップ上の局所窓をstride幅で動かし、窓内の値を1つに集約して空間解像度を下げます。最大値なら強い反応を残し、平均値なら反応の総量をならします。通常はチャネルごとに独立して処理するため、チャネル数を増やす層ではありません。

小さな地域ごとに「いちばん目立つ店」を記録するのが最大値プーリング、地域全体の「平均的なにぎわい」を記録するのが平均プーリングです。記録する地域を重ねずに進めれば、地図は粗くなりますが、細かな位置を少し変えても地域の代表値は保ちやすくなります。

なぜ必要か

畳み込みの出力をそのまま次段へ渡すと、縦横の要素数と計算量が大きいままです。プーリングは学習する重みを持たず、局所窓の集約だけで表現を小さくし、後段の計算とメモリを抑えます。

strideを窓の大きさと同じにすると、隣り合う窓を重ねずに縮小できます。strideを1にしても、縦横サイズは窓とpaddingの条件次第です。プーリングだから必ず半分になるわけではありません。

設定空間サイズへの作用
strideを大きくする窓を遠くへ動かすため、出力を粗くしやすい
strideを1にする窓を細かく走査し、縮小率を抑えやすい
paddingを加える境界を含めて窓を置けるが、出力形状も変わる

仕組み

入力をチャネルごとの特徴マップ x\mathbf{x}、窓を Wi,j\mathcal{W}_{i,j}、出力を yi,jy_{i,j} とします。最大値プーリングと平均プーリングは、集約演算だけが異なります。

yi,jmax=max⁡(u,v)∈Wi,jxu,v,yi,javg=1∣Wi,j∣∑(u,v)∈Wi,jxu,vy_{i,j}^{\mathrm{max}} = \max_{(u,v) \in \mathcal{W}_{i,j}} x_{u,v}, \qquad y_{i,j}^{\mathrm{avg}} = \frac{1}{|\mathcal{W}_{i,j}|}\sum_{(u,v) \in \mathcal{W}_{i,j}} x_{u,v}

i,ji,j は出力上の位置、Wi,j\mathcal{W}_{i,j} はその位置に対応する入力窓、∣Wi,j∣|\mathcal{W}_{i,j}| は窓の要素数です。最大値は窓内の強い特徴を残すので、特徴が窓のどこにあるかを少し変えても同じ値になりやすい一方、最大でない反応は捨てます。平均値は複数の反応を残しますが、突出した反応は薄まります。この局所的な位置ずれへの頑健さは、厳密な位置情報を保持する性質ではなく、粗い位置で存在を表す性質です。

2次元の高さ方向について、入力サイズを HinH_{\mathrm{in}}、窓の高さを KK、paddingを PP、strideを SS とすると、通常の切り捨て設定では出力高さは次で決まります。HoutH_{\mathrm{out}} は出力高さ、⌊⋅⌋\lfloor\cdot\rfloor は小数点以下を切り捨てる演算です。

Hout=⌊Hin+2P−KS⌋+1H_{\mathrm{out}} = \left\lfloor \frac{H_{\mathrm{in}} + 2P - K}{S} \right\rfloor + 1

幅方向も同じ計算です。PyTorchの MaxPool2d ではstrideの既定値がkernel sizeで、paddingを使う最大値プーリングでは窓の外側を負の無限大として扱います。ceil_mode=True なら切り上げを使います。

プーリング自体に重みやbiasはなく、学習パラメータは増えません。ただし最大値の選択位置は逆伝播で勾配を受け取る場所を決めます。したがって「パラメータがない」と「学習時に何も計算しない」は同じではありません。

試験でどう問われるか

問われ方正解に寄る条件引っかけ
最大値と平均値の比較最大値は強い反応を残し、平均値は窓内をならす平均値も最大反応をそのまま保持すると考える
出力サイズの計算kernel sizeだけでなくstride、padding、切り捨て/切り上げを見るプーリングなら常に縦横1/2になるとする
パラメータ数通常のpoolingは学習パラメータを持たない出力チャネル数ぶん重みが増えるとする
位置ずれへの性質局所窓内の位置変化を吸収しやすいが、位置情報を完全には保たないどんな移動にも不変だとする
畳み込みとの置換stride付き畳み込みで縮小を担える場合がある常に同じ演算・同じ表現になるとする

実装で確かめる

NumPyで2×2窓をstride 2で動かし、最大値と平均値の違いを確認します。

import numpy as np

x = np.array([[1., 2., 0., 4.],
              [3., 1., 5., 2.],
              [0., 6., 2., 1.],
              [4., 1., 3., 0.]])
windows = [x[r:r+2, c:c+2] for r in (0, 2) for c in (0, 2)]
max_pool = np.array([w.max() for w in windows]).reshape(2, 2)
avg_pool = np.array([w.mean() for w in windows]).reshape(2, 2)
print(max_pool)
print(avg_pool)

このコードの出力は最大値が [[3. 5.] [6. 3.]]、平均値が [[1.75 2.75] [2.75 1.5 ]] です。

取り違えやすいもの

用語プーリングとの切り分け
stride付き畳み込み学習するカーネルで特徴抽出と縮小を同時に行う。poolingは固定の集約で、置換しても意味は同じとは限らない
最大値プーリング窓内の最大値だけを出力する。強い反応の検出に寄る
平均プーリング窓内の平均を出力する。反応をならして残す
padding入力の周囲を補う設定。poolingの集約規則そのものではない

想起チェック

最大値プーリングと平均プーリングの違いは何か

最大値プーリングは窓内の最大値を、平均プーリングは窓内の値の平均を出力します。前者は強い反応を残し、後者は反応をならします。

プーリングの出力サイズを決める設定は何か

kernel size、stride、paddingが基本です。ceil_mode のように切り上げを選ぶ設定もあるため、窓の大きさだけでは決まりません。

プーリング層に学習パラメータはあるか

通常の最大値・平均プーリングには学習する重みやbiasはありません。ただし最大値の選択位置など、順伝播と逆伝播の計算はあります。

出典