I am trying to implement in tensorflow (or keras) a channel shuffle function. I have found this implementation but it seems to be wrong because I think it's based on this pytorch implementation.
I have managed to do it with concatenate() but I would like an implementation using permute_dimensions(). Also, I am not sure if the concatenate version is slower (if someone can answer this one I would be grateful).
A working tensorflow implementation using concatenate():
import tensorflow as tf
import tensorflow.keras.backend as K
from tensorflow.keras import layers
from tensorflow.keras import models
import numpy as np
a = tf.constant([[[[1, 2], [3, 4], [5, 6]], [[7, 8], [9, 10], [11, 12]]]])
sess = tf.Session()
print('x', sess.run(a))
groups = 2 # separate into 2 group
h, w, in_channel = K.int_shape(a)[1:]
l = K.reshape(a, [-1, h, w, in_channel // groups, groups])
m = K.concatenate((l[..., 1], l[..., 0]))
l = K.reshape(m, [-1, h, w, in_channel])
print('y', sess.run(l))
with output:
x [[[[ 1 2]
[ 3 4]
[ 5 6]]
[[ 7 8]
[ 9 10]
[11 12]]]]
y [[[[ 2 1]
[ 4 3]
[ 6 5]]
[[ 8 7]
[10 9]
[12 11]]]]
A keras non working implementation is below:
def channel_shuffle(x):
g = 2
b, h, w, c = x.shape.as_list()
x = K.reshape(x, [-1, h, w, g, c // g])
x = K.permute_dimensions(x, (0, 1, 2, 4, 3))
x = K.reshape(x, [-1, h, w, c])
return x
input_shape = (2, 3, 2)
x = np.array([[[[1, 2], [3, 4], [5, 6]], [[7, 8], [9, 10], [11, 12]]]])
image_input = layers.Input(input_shape)
permuted_x = channel_shuffle4(image_input)
model = models.Model(inputs=[image_input], outputs=permuted_x)
y = model.predict(x)
print('x', x)
print('y', y)
with output:
x [[[[ 1 2]
[ 3 4]
[ 5 6]]
[[ 7 8]
[ 9 10]
[11 12]]]]
y [[[[ 1. 2.]
[ 3. 4.]
[ 5. 6.]]
[[ 7. 8.]
[ 9. 10.]
[11. 12.]]]]
which obviously does not change the input data at all. So, how can I achieve the desired result? Basically which axes should I interchange? I have made some experiments but I cannot seem to find the right one.