Poolingがしたいときのメモ


概要

いろいろなPoolingをしたい
skimage.measureblock_reduceを使う

内容

  • DLでよく使われるMax, Average以外のPoolingをしたいものの、端数処理などが面倒。
  • いい感じに処理してくれるライブラリはないものか...
  • ありました
binning.py
import numpy as np
from skimage import measure

#画像の代わり
img = np.arange(2000*3000*3).reshape(2000, 3000, 3).astype(np.uint32)
print(img.shape, img.dtype, np.average(img))
# (2000, 3000, 3) uint32 8999999.5

skimage.measure.block_reduce(image, block_size, func=<function sum>, cval=0, func_kwargs=None)

引数として
image : 入力画像(N次元)
block_size : Poolingに使うブロックの大きさ(これもN次元)
function sum : Poolingに使う計算方法、 numpy.sum、numpy.min、numpy.max、numpy.mean、numpy.medianをサポート。
cval : paddingする場合の値
func_kwargs : 出力のdtypeなどを指定できる。

以下のように、ピクセル当たりの平均が16倍になっていることからsum poolingができていることがわかる。

binning_4.py
img_bin = measure.block_reduce(img, (4, 4, 1), np.sum, func_kwargs={'dtype': np.uint32})
print(img_bin.shape, img_bin.dtype, np.average(img_bin))
# (500, 750, 3) uint32 143999992.0

Paddingを7などの割り切れない数値にしても計算ができている。

binning_7.py
img_bin_7 = measure.block_reduce(img, (7, 7, 1), np.sum, func_kwargs={'dtype': np.uint32})
print(img_bin_7.shape, img_bin_7.dtype, np.average(img_bin_7))
# (286, 429, 3) uint32 440119296.7871289