Min and Max pooling in tensorflow

236 Views Asked by At

I want to create a custom min max pooling layer in tensorflow. What do i mean by that is as max pooling takes the maximum value in a matrix of size k I want to implement a layer which gets the min and max values in a matrix of size k and then concats them according to there index.

for eg:

sequence = [1,2,3,6,5,4]

i want to iterate over this tensor in chunks according to filter size say 3 and get the min and max values

1st chunk [1,2,3]
    min value = 1
    max value = 3
    concat according to sequence [1,3]

2nd chunk [6,5,4]
    min value = 4
    max value = 6
    concat according to sequence [6,4]

and then return whole downsampled sequence as [1,3,6,4]
thus converting 
our original input [1,2,3,6,5,4]
to                 [1,3,6,4]

I tried to code a coustom layer in tensor flow using layer subclassing but got a lot of problems. Posted the question in stackoverflow but know one answered. I have provided a lot of details there you can use it as a reference. link = Custom - minmax pooling - Keras - Tensorflow

In the question the problem is with the while loop

I just want to implement a custom layer with min max pooling functionality as above in tensorflow using layer subclassing so it can be used to downsample the inputs by giving same importance to min values as max values.

Or any other efficient or simple way to implement this functionality in tensorflow.

1

There are 1 best solutions below

12
Alberto On

Usually you don't want to use loops in tf graphs, because they create many bottlenecks, instead, you should try to use TF functions, and IMO the following can be a decent implementation (maybe some steps at the end might be optimized, but i don't think it will lead to a big improvement):

# make your sequence 3D so that maxpool work fine
seq = tf.convert_to_tensor([1,2,3,6,5,4])[tf.newaxis,...,tf.newaxis]
# your window size, which will also be the stride size
window_size = 3
# find the maximum for each chunk
max_seq = tf.nn.max_pool1d(seq,window_size,window_size,"VALID")
# find the minumum for each chunk 
# (minimum is the "inverse" of maximum, thus subtracting max and mult by -1 works)
max = tf.reduce_max(seq)
inverted = -1 * (seq - max)
min_seq = -1 * tf.nn.max_pool1d(inverted,window_size,window_size,"VALID") + max
# concatenate the two sequence, transpose to have the desired order, and reshape to get the right shape
tf.reshape(tf.transpose(tf.concat((min_seq, max_seq), axis=0)), (-1,))

Output:

<tf.Tensor: shape=(4,), dtype=int32, numpy=array([1, 3, 4, 6], dtype=int32)>