🎉
KerasのMaxPooling pool_sizeを変えたら予想外の結果になった話【GAP vs Flatten で挙動が逆転】
KerasでCNNを書くとき、MaxPooling2Dの pool_size はなんとなく (2, 2) にしていませんか?
「pool_sizeを大きくすると空間情報が失われて精度が下がるはず」——私もそう思っていました。
ところが実際に動かしてみると、結果は2回とも予想を裏切りました。
GAP版:pool_size=(4,4) が最高精度
GlobalAveragePooling2D(GAP)を使ったモデルで pool_size を 2×2 / 3×3 / 4×4 の3パターンで比較したところ、最も圧縮率の高い (4,4) が最高精度(72.30%)・最短学習時間(91.7秒)という逆転結果になりました。
| pool_size | Test Acc | 学習時間 |
|---|---|---|
| (2,2) | 67.80% | 128.4秒 |
| (3,3) | 69.52% | 103.8秒 |
| (4,4) | 72.30% | 91.7秒 |
理由はGAPの仕組みにありました。GAPはPooling後の特徴マップを「チャンネルあたり1つの平均値」に集約するため、pool_sizeが違っても GAP後は全パターン同じ128次元ベクトルになります。pool_sizeの空間サイズ差がGAPで吸収され、さらに強い圧縮が正則化として機能した結果です。
Flatten版:(2,2) が最下位に
次にGAPをFlattenに変えて同じ実験をしたところ、今度は逆の方向に予想が外れました。
| pool_size | Test Acc | パラメータ数 |
|---|---|---|
| (2,2) | 68.74% | 約111万 |
| (3,3) | 71.33% | 約21万 |
| (4,4) | 71.18% | 約13万 |
パラメータ数が最多の (2,2) が最下位です。Flattenはpool_size後の特徴マップをそのまま展開するため、(2,2) のDense層入力は8,192次元・パラメータ約111万に膨らみ、Ep5の時点でval_lossが底を打ち深刻な過学習に陥りました。
一方 (4,4) はEp30時点でもtrain_lossが0.24とまだ収束途中で、エポックを増やせばさらに伸びる可能性があります。
まとめ:pool_sizeの最適値はGAP/Flattenで逆転する
- GAPモデル:pool_sizeを大きくしても精度が落ちない。正則化効果で大きめが有利なこともある
- Flattenモデル:pool_sizeを小さくするとパラメータが爆発し過学習しやすい。CIFAR-10レベルでは (3,3) や (4,4) の方が効率が良い
「どちらのモデルを使うか」が pool_size の最適値より先に決めるべき設計上の判断です。
実験コード・詳細な考察・グラフはブログ記事で公開しています。
- GAP版の詳細 →
- Flatten版の詳細 →
Discussion