4

このペーパーで文字レベルの CNN を再作成しようとしていますが、k-max プーリング レイヤーを作成する必要がある最終ステップで少し行き詰まりました。MXNet を使用していて、これがないからです。

重要な違いは、複数の一時的な k-max プーリング レイヤーの導入です。これにより、特定の位置に関係なく、文内の k 個の最も重要な特徴を検出し、それらの相対的な順序を維持できます。

ただし、MXNet には、私がそうしようとしてきた新しい操作を追加する機能があります (ただし、フィルターとバッチサイズを指定すると、データの形状に少し混乱します)。

入ってくるデータの形:

128 (min-batch) x 512 (number of filters) x 1 (height) x 125 (width)

出てくるデータの形状 (k-max プーリング、k = 7):

128 (min-batch) x 512 (number of filters) x 1 (height)  x 7 (width)

これまでの私の考え...:

class KMaxPooling(mx.operator.CustomOp):
    def forward(self, is_train, req, in_data, out_data, aux):
        # Desired (k=3):
        # in_data = np.array([1, 2, 4, 10, 5, 3])
        # out_data = [4, 10, 5]
        x = in_data[0].asnumpy()
        idx = x.argsort()[-k:]
        idx.sort(axis=0)
        y = x[idx]

ただし、いくつかの点についてはわかりません。

  1. これが機能するかどうかをテストする方法 (完全なコードを取得したら)
  2. 寸法はどうあるべきですか?最後の次元 (軸 = 0) で並べ替えています
  3. backward() 関数、つまり勾配伝播に対して何をすべきか
  4. これが GPU で動作するかどうか - C/cuda で書き直す必要があると思いますか?

私はkerasのために他の誰かによってこの例を見つけました(しかし、リンクする担当者がいません):

import numpy as np
import theano.tensor as T
from keras.layers.core import MaskedLayer

class KMaxPooling(MaskedLayer):
    def __init__(self, pooling_size):
        super(MaskedLayer, self).__init__()
        self.pooling_size = pooling_size
        self.input = T.tensor3()

    def get_output_mask(self, train=False):
        return None

    def get_output(self, train=False):
        data = self.get_input(train)
        mask = self.get_input_mask(train)

        if mask is None:
            mask = T.sum(T.ones_like(data), axis=-1)
        mask = mask.dimshuffle(0, 1, "x")

        masked_data = T.switch(T.eq(mask, 0), -np.inf, data)

        result = masked_data[T.arange(masked_data.shape[0]).dimshuffle(0, "x", "x"),
                             T.sort(T.argsort(masked_data, axis=1)[:, -self.pooling_size:, :], axis=1),
                             T.arange(masked_data.shape[2]).dimshuffle("x", "x", 0)]
4

1 に答える 1