Пользовательский слой пула - minmax pooling - Keras - Tensorflow - PullRequest
1 голос
/ 15 марта 2019

Я хочу определить свой пользовательский слой пула, вместо того, чтобы возвращать максимальные значения, такие как слой MaxPooling, он вывел бы k максимальных значений и k минимальных значений.

Я использую Tensorflow в качестве бэкэнда. Мне нужно, чтобы выходной вектор был отсортирован.

Я думал об этом:

from keras.layers.pooling import _Pooling1D

class MinMaxPooling1D(_Pooling1D):

    def __init__(self, output_dim, **kwargs):
        self.output_dim = output_dim
        super(MinMaxPooling1D, self).__init__(**kwargs)

    def _pooling_function(self, inputs, **kwargs):
        sorted_ = tf.contrib.framework.sort(inputs, axis = -1)
        print(sorted_)
        return np.concatenate((sorted_[:,:,:self.output_dim/2], sorted_[:,:,-self.output_dim/2:]))

Но тогда я получаю:

Tensor("min_max_pooling1d_1/sort/Neg_1:0", shape=(?, 1, 1, ?), dtype=float32)
ValueError: zero-dimensional arrays cannot be concatenated

Слой MinMaxPooling1D применяется к выводу формы (Нет, 1, 10).

Тогда я думал о добавлении слоя Flatten перед слоем MinMaxPooling1D, но затем возникла проблема с размером:

ValueError: Input 0 is incompatible with layer min_max_pooling1d_5: expected ndim=3, found ndim=2

Ответы [ 2 ]

4 голосов
/ 17 марта 2019

Итак, вы хотите построить слой Keras, который будет принимать трехмерный ввод формы [batch_dim, pool_dim, channels] и производить 4D вывод [batch_dim, pool_dim, channels, min_max_channels].

В отличие от Keras _Pooling1D вы на самом деле измените количество измерений, и я бы порекомендовал реализовать ваш слой, наследуя непосредственно от keras Layer.

Реализуйте метод call, используяtf.sort и взяв желаемое количество элементов max и min из отсортированного ввода и конкатенируя их вдоль нового измерения (рассмотрите возможность использования tf.expand_dims и tf.concat).

ps Я попытался реализовать этоя и обнаружил, что это сложно.Вы в основном хотите что-то отличное от maxpool, и немного более сложное.Вы можете взглянуть на tensorflow/python/ops/gen_nn_ops.py метод max_pool, чтобы оценить, какую работу вы выполняете, если только вы не найдете где-нибудь готовую реализацию ...

2 голосов
/ 18 марта 2019

Вместо того, чтобы пытаться использовать пул, я использую лямбду:

def top_k(inputs, k):
  return tf.nn.top_k(inputs, k=k, sorted=True).values

def least_k(inputs, k):
    return -tf.nn.top_k(-inputs, k=k, sorted = True).values

def minmax_k(inputs, k):
    return tf.concat([least_k(inputs, k), top_k(inputs, k)], axis = -1)

model = Sequential()
...
model.add(Lambda(minmax_k, arguments={'k': R}))
...