2

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
  • What version of TensorFlow are you using? And do you need the result as a tensor, and using only TensorFlow operations, or is it okay to get a NumPy array and then convert that to string? Commented Mar 3, 2020 at 11:05
  • I'm using tensorflow 2; I would need a tensor result, I don't want to use the numpy way mentioned in the question (or a similar method) and then convert it to a tensor. I'd like an op that returns a tensor, thanks Commented Mar 3, 2020 at 12:09

2 Answers 2

2

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)
Sign up to request clarification or add additional context in comments.

Comments

0

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 :)

2 Comments

this is not a workaround, this the way to do it. Your misconception is that you think each row of your matrix in your tf.Tensor is one tensor, or it belongs together or something. You might think that, but tensorflow doesn't. You can see that in <tf.Tensor: shape=(5, 2), ..., it's just a 5x2 matrix. It might be printed as a list of lists, but it's not, it's a tf.Tensor. So, you'll need some extra steps to get what you want. As your entire implementation of the extra steps is within tensorflow, this LGTM.
My objective was to simply Stringify tensor as a whole, and in the example I have given in the question, I am trying to do the same, except that to each element in a tensor (i.e inside a map_fn). I was expecting an inbuilt tf fn that does that. That said I agree that tensorflow might be doing something similar to do the formatting using tf.strings.format, with more fancy options though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.