我正在尝试在本文中重新创建 char 级 CNN,但在需要创建 k-max 池化层的最后一步有点卡住,因为我使用的是 MXNet,但它没有这个。
一个重要的区别还在于引入了多个时间 k-max 池化层。这允许检测句子中最重要的 k 个特征,独立于它们的特定位置,保持它们的相对顺序。
然而,MXNet 确实有能力添加一个新的操作,我一直在尝试这样做(尽管对数据的形状、给定的过滤器和批量大小有点困惑)。
传入数据的形状:
128 (min-batch) x 512 (number of filters) x 1 (height) x 125 (width)
出来的数据的形状(k-max pooling,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]
但是,我不确定几件事:
- 如何测试这是否有效(一旦我有一些完整的代码)
- 尺寸应该是多少?我正在对最后一个维度进行排序(轴 = 0)
- 对backward()函数做什么,即梯度传播
- 这是否适用于 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)]