Tensorflow: Stringify tensor as a whole (without creating tensor of strings)

Viewed 383

I have the following array,

a = tf.random.uniform((5,2), 0, 10)

<tf.Tensor: shape=(5, 2), dtype=float32, numpy=
array([[3.8656425 , 6.7514324 ],
       [0.49138665, 3.5968459 ],
       [4.435692  , 4.7223845 ],
       [7.3588967 , 0.31867146],
       [1.6837907 , 3.2266355 ]], dtype=float32)>

What I want is array of stringified arrays like below this would return a numpy array, but I want to do tensorflow ops to return a tensor:

list(map(str, a.numpy()))

['[3.8656425 6.7514324]',
 '[0.49138665 3.5968459 ]',
 '[4.435692  4.7223845]',
 '[7.3588967  0.31867146]',
 '[1.6837907 3.2266355]']

When I use tf.as_string()

tf.as_string(a)

<tf.Tensor: shape=(5, 2), dtype=string, numpy=
array([[b'3.865643', b'6.751432'],
       [b'0.491387', b'3.596846'],
       [b'4.435692', b'4.722384'],
       [b'7.358897', b'0.318671'],
       [b'1.683791', b'3.226635']], dtype=object)>

I also tried using

tf.map_fn(tf.as_string, a, dtype=tf.string)

# Same output as above

tf.as_string() converts float/int tensors to string tensors of same shape. Is there any tensorflow op that stringifies tensors as a whole?

2 Answers

You can use tf.strings.format:

import tensorflow as tf

tf.random.set_seed(0)
a = tf.random.uniform((5,2), 0, 10)
b = tf.map_fn(lambda r: tf.strings.format('{}', r, summarize=-1), a, tf.string)
print(b)
# tf.Tensor(
# [b'[2.91975141 2.06566453]' b'[5.35390759 5.61257458]'
#  b'[4.16674519 8.0782795]' b'[4.93225098 9.98129272]'
#  b'[6.96735144 1.25373602]'], shape=(5,), dtype=string)

As a workaround, I'm joining individual strings

b = tf.map_fn(lambda x: tf.strings.join(x, separator=" "), tf.as_string(a))
b = tf.map_fn(lambda x: tf.strings.join(['[', x, ']']), b)

<tf.Tensor: shape=(5,), dtype=string, numpy=
array([b'[3.865643 6.751432]', b'[0.491387 3.596846]',
       b'[4.435692 4.722384]', b'[7.358897 0.318671]',
       b'[1.683791 3.226635]'], dtype=object)>

Other answers are welcome :)

Related