R-MACのRegionの取得方法

こんにちはネザーです。

今回は、R-MACのRegionの取得方法についてサンプルコードで説明したいと思います。

R-MACとはRegional Maximum Activations of Convolutions[1]の略で、ResNetなどのCNNでは出力層の手前でGAP(Global Average Pooling)を用いて、各チャンネルで特徴マップ全体に対してAveragePoolingをかけることが多いですが、R-MACでは特徴マップ全体ではなく、一部分に対してCNNの中間層の特徴マップに対してRoIプーリングを行います。R-MACでは下図のようにRoIプーリングを行う矩形の大きさと位置を変えてそれぞれRoIプーリングを行います。(詳しい内容は論文をご覧ください)

画像1

        (R-MACでRoIプーリングを行うRegion.[1]より引用)

論文では、特徴マップが長方形の場合について説明していますが、VGGNetやResNetなど多くのCNNでは入力画像は正方形であり、そのため中間層の特徴マップを正方形であることが多いです。特徴マップが長方形でもRegionは正方形で設定しますので、長方形だと縦と横のどちらが長いかなど、特徴マップが正方形の場合に比べて処理が複雑になってしまいます。

そのため、特徴マップが正方形を前提にするとRegionの推定方法も処理手順も簡単になり理解しやすくなります。下記にサンプルコードを載せましたので、R-MACのRegionの取得方法を知りたい方は参考にしてください。

# H: 特徴マップの高さ
# W: 特徴マップの幅
# L: スケール(大きいほど小さいRegionまで取得)
import numpy as np
def rmac_region_square(self, H: int, W: int, L: int):
   assert H == W  # 正方形かどうかチェック

   regions = []
   for l in range(1, L + 1):  # l=1の場合、特徴マップ全体でプーリング
       region_w = np.floor(2 * W / (l + 1)) # 1つのregionの1辺の長さ

       if (region_w < 1):
           continue

       region_w_half = np.floor(region_w / 2)  # regionの1辺の長さの半分

       if (l == 1):
           grid_w = 0  # Region外の部分はないため0
       else:
           grid_w = (W - region_w) / (l - 1)  # 1グリッドの1辺の長さ グリッドはRegion外の1矩形

       sx_array = np.floor(region_w_half + np.arange(0, l) * grid_w) - region_w_half
       sy_array = np.copy(sx_array)
    
       for sy in sy_array:
           for sx in sx_array:
               region = np.array([sx, sy, region_w, region_w], dtype=np.int)
               regions.append(region)

   regions = np.asarray(regions)
   return regions

[1] G. Tolias, R. Sicre, and H. J´egou, “Particular object retrieval with integral max-pooling of CNN activations,” in ICLR, 2015, pp. 1–12.

この記事が気に入ったらサポートをしてみませんか?