5

For example, I have a tensor A = tf.Variable([a, b, c, d, e]) and through tf.tile(), it can give a tensor like [a, b, c, d, e, a, b, c, d, e]

But I want to reform A into something like: [a, a, b, b, c, c, d, d, e], where the elements are duplicated at the original place.

What is the most efficient way (less operations) to achieve that (through different-able ops)?

null
  • 1,167
  • 1
  • 12
  • 30

1 Answers1

7

You can do it by adding a dimension, tiling along that dimension, and removing it:

import tensorflow as tf

A = tf.constant([1, 2, 3, 4, 5])

B = tf.expand_dims(A, axis=-1)
C = tf.tile(B, multiples=[1,2])
D = tf.reshape(C, shape=[-1])

with tf.Session() as sess:
    print('A:\n{}'.format(A.eval()))
    print('B:\n{}'.format(B.eval()))
    print('C:\n{}'.format(C.eval()))
    print('D:\n{}'.format(D.eval()))

gives

A:
[1 2 3 4 5]
B: # Add inner dimension
[[1]
 [2]
 [3]
 [4]
 [5]]
C: # Tile along inner dimension
[[1 1]
 [2 2]
 [3 3]
 [4 4]
 [5 5]]
D: # Remove innermost dimension
[1 1 2 2 3 3 4 4 5 5]

Edit: as pointed out in the comments, using tf.stack allows to specify the additional dimension on the go:

F = tf.stack([A, A], axis=1)
F = tf.reshape(F, shape=[-1])

with tf.Session() as sess:
    print(F.eval())

[1 1 2 2 3 3 4 4 5 5]
sdcbr
  • 7,021
  • 3
  • 27
  • 44
  • Thanks for your answer, but when I test a gradient `g = tf.gradients(3*D, A)`, why it returns `[None]`? – null Aug 13 '18 at 12:39
  • I'm using a `tf.constant` in my example to keep it simple, not a `tf.Variable`. The same logic applies to variables though. – sdcbr Aug 13 '18 at 12:43
  • 1
    There is also some discussion [here](https://stackoverflow.com/questions/44952886/tensorflow-merge-two-2-d-tensors-according-to-even-and-odd-indices) about odd and even positions and interleaving which is interesting.`A = tf.Variable(['a', 'b', 'c', 'd', 'e']) print(sess.run(A[0::2])) print(sess.run(A[1::2]))` – Mohan Radhakrishnan Aug 13 '18 at 12:47
  • @sdcbr very strange, I test that code in my PC, the returned gradient is good, but in google colab, it returns `None` – null Aug 13 '18 at 12:49
  • @MohanRadhakrishnan, thanks for the reference, that actually allows to do it with less code, I've updated my answer. – sdcbr Aug 13 '18 at 13:02