atriumlts / subpixel

subpixel: A subpixel convnet for super resolution with Tensorflow
MIT License
2.13k stars 301 forks source link

Difference from tf.depth_to_space #32

Open midddle opened 7 years ago

midddle commented 7 years ago

Hi,

Was amazed by this great idea compared to conv2_transpose. Looking at tensorflow documentation I found tf.depth_to_space, which seems to do something similar (at least the non-color version), am I mistaken? What's the difference? What's the reason you did not use this op?

AloshkaD commented 6 years ago

@midddle I'm planning on using depth_to_space in keras. Which is the same. check this out https://github.com/twairball/keras-subpixel-conv

whiteeat commented 6 years ago

According to my experiment, the phase shift implementation is different from tf.depth_to_space, Following is my Experiment, I'm using Tensorflow 1.6.0:

Experiment

Code

import numpy as np
import tensorflow as tf

def _phase_shift(I, r):
    bsize, a, b, c = I.get_shape().as_list()
    bsize = tf.shape(I)[0]  # Handling Dimension(None) type for undefined batch dim
    X = tf.reshape(I, (bsize, a, b, r, r))
    X = tf.transpose(X, (0, 1, 2, 4, 3))  # bsize, a, b, 1, 1
    X = tf.split(axis=1,num_or_size_splits=a, value=X)  # a, [bsize, b, r, r]
    X = tf.concat(axis=2, values=[tf.squeeze(x, axis=1) for x in X])  # bsize, b, a*r, r
    X = tf.split(axis=1, num_or_size_splits=b, value=X)  # b, [bsize, a*r, r]
    X = tf.concat(axis=2, values=[tf.squeeze(x, axis=1) for x in X])  # bsize, a*r, b*r
    return tf.reshape(X, (bsize, a * r, b * r, 1))

def PS(X, r, color=False):
    if color:
        Xc = tf.split(axis=3, num_or_size_splits=3, value=X)
        X = tf.concat(axis=3, values=[_phase_shift(x, r) for x in Xc])
    else:
        X = _phase_shift(X, r)
    return X

init = []
for x in range(0, 9):
    init.append(x)

a = np.array(init, dtype=int)
a = a.reshape((1, 1, 1, 9))

tensor = tf.constant(a)

b = PS(tensor, 3, color=False)
c = tf.depth_to_space(tensor, 3)

sess = tf.Session()
result, result_1 = sess.run([b, c])

print(result)
print(result_1)

sess.close()

Input

a: [[[[0 1 2 3 4 5 6 7 8]]]]

Output

result:
[[[[0] [3] [6]] [[1] [4] [7]] [[2] [5] [8]]]] result_1: [[[[0] [1] [2]] [[3] [4] [5]] [[6] [7] [8]]]]

For the implementation of phase shift, I use the code in #47. So probably I make some mistakes or they are just not same?

chaos5958 commented 6 years ago

@AloshkaD @whiteeat Is there any critical performance difference from using tf.depth_to_space? Because this operation is not supported in TF Light (Tensorflow for Mobile), I'm trying to use phase shift implementation.

whiteeat commented 6 years ago

@chaos5958 My problem is, the phase shift implementation produce different output from tf.depth_to_space one when provided the same input.

purva98 commented 4 years ago

Hey @chaos5958 , even I am trying to use tf.depth_to_space in TFlite. Did you find any solution or alternative?

chaos5958 commented 4 years ago

@purva98 No, instead, I'm using Qualcomm SNPE which supports tranpsose conv layer.