how to get a tensorflow tf by index? - numpy

object_for_each_prior = tf.constant([1 for i in range(8732)])
-><tf.Tensor: shape=(8732,), dtype=int32, numpy=array([1, 1, 1, ..., 1, 1, 1], dtype=int32)>
Then if I want to get the position 1148,1149
prior_for_each_object = tf.constant([1148,1149])
object_for_each_prior[prior_for_each_object]
Then I got the following error
TypeError: Only integers, slices (`:`), ellipsis (`...`), tf.newaxis (`None`) and scalar tf.int32/tf.int64 tensors are valid indices, got <tf.Tensor: shape=(2,), dtype=int32, numpy=array([1148, 1149], dtype=int32)>
If I want to get the tensor's number by index how should I approach it?

Use tf.gather_nd function to index tensors.
Here's example:
>>> object_for_each_prior = tf.constant([1 for i in range(8732)])
>>> prior_for_each_object = tf.gather_nd(object_for_each_prior, indices=[[1148], [1149]])
>>> prior_for_each_object
<tf.Tensor: shape=(2,), dtype=int32, numpy=array([1, 1])>
>>> prior_for_each_object.numpy()
array([1, 1])
refer this doc to know more about tf.gatherr_nd.

Related

How do you get the max value in a tensorflow dataset whilst keeping the same shape and dimension?

Consider the following code below:
import tensorflow as tf
x = tf.constant([5, 1, 2, 4])
tf.reduce_max(x)
The result of the above would give me the output x:
<tf.Tensor: shape=(), dtype=int32, numpy=5>
However, I want to get the max value in such a format:
<tf.Tensor: shape=(4,), dtype=int32, numpy=array([5,5,5,5]dtype=int32)>
Any ideas how to code this?
Thanks to Flavia Giammarino for helping.
import tensorflow as tf
x = tf.constant([5, 1, 2, 4])
tf.reduce_max(x)
test=tf.repeat(tf.reduce_max(x), repeats=x.shape[0])
print(test)
I got the following output as desired:
tf.Tensor([5 5 5 5], shape=(4,), dtype=int32)

How to do predictions with tf.dataset

I have an issue with tf.datasets and tf.keras.predict(). I don't know why the length of the output array of predict() is larger than the original lenght of data used. Here is a sketch:
Before I used arrays. And if I applied predict() on a array of lenght x I get an output of lenght x... This is my expected behaviour.
I have a csv of test data with some lenght (10000). Now I use
LABEL_COLUMN = 'label'
LABELS = [0, 1]
def get_dataset(file_path, **kwargs):
dataset = tf.data.experimental.make_csv_dataset(
file_path,
batch_size=1, # Artificially small to make examples easier to show.
label_name=LABEL_COLUMN,
na_value="?",
num_epochs=1,
ignore_errors=True,
**kwargs)
return dataset
to convert this to a tf.dataset.
val='data/test.csv'
val_data= get_dataset(val)
Now using
scores=bert_model.predict(val_data)
gives an array ouput which is very much larger than of the original csv file (10000)...
I am really off. Also I ask myself how does keras know what "keys" of the tf.dataset to use for predictrions.
The structure of the 1. elemnt of the dataset looks like "val[0]":
({'input_ids': <tf.Tensor: shape=(15,), dtype=int32, numpy=
array([ 3, 2019, 479, 1169, 4013, 26918, 259, 4, 14576,
3984, 889, 648, 1610, 26918, 4])>, 'token_type_ids': <tf.Tensor: shape=(15,), dtype=int32, numpy=array([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1])>, 'attention_mask': <tf.Tensor: shape=(15,), dtype=int32, numpy=array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])>}, <tf.Tensor: shape=(), dtype=int64, numpy=0>)
why does my label column has no key with name "label"? The first 3 keys all have their names and the model is trained with these 3 columns.
I use above structure with label column as input for predict...
Any idea? Is it due to the function of making a dataset from a csv?

ValueError: Shapes must be equal rank in assign_add()

I am reading tf.Variable in Tensorflow r2.0 in TF2:
import tensorflow as tf
# Create a variable.
w = tf.constant([1, 2, 3, 4], tf.float32, shape=[2, 2])
# Use the variable in the graph like any Tensor.
y = tf.matmul(w,tf.constant([7, 8, 9, 10], tf.float32, shape=[2, 2]))
v= tf.Variable(w)
# The overloaded operators are available too.
z = tf.sigmoid(w + y)
tf.shape(z)
# Assign a new value to the variable with `assign()` or a related method.
v.assign(w + 1)
v.assign_add(tf.constant([1.0, 21]))
ValueError: Shapes must be equal rank, but are 2 and 1 for
'AssignAddVariableOp_4' (op: 'AssignAddVariableOp') with input shapes:
[], 2.
And also how come the following returns false?
tf.shape(v) == tf.shape(tf.constant([1.0, 21],tf.float32))
My other question is that when we are in TF 2, we should not use tf.Session() anymore, correct? It seems we should never run session.run(), but the API document keys doing it with tf.compat.v1, etc. So why they are using it in TF2 docs?
Any help would be appreciated.
CS
As it clearly says in the error, it is expecting shape [2,2] for assign_add on v which is having the shape [2,2].
If you try to give any shape other than the initial shape of the Tensor which you are trying to do assign_add the error will be given.
Below is the modified code with the expected shape for the operation.
import tensorflow as tf
# Create a variable.
w = tf.constant([1, 2, 3, 4], tf.float32, shape=[2, 2])
# Use the variable in the graph like any Tensor.
y = tf.matmul(w,tf.constant([7, 8, 9, 10], tf.float32, shape=[2, 2]))
v= tf.Variable(w)
# The overloaded operators are available too.
z = tf.sigmoid(w + y)
tf.shape(z)
# Assign a new value to the variable with `assign()` or a related method.
v.assign(w + 1)
print(v)
v.assign_add(tf.constant([1, 2, 3, 4], tf.float32, shape=[2, 2]))
Output for v:
<tf.Variable 'UnreadVariable' shape=(2, 2) dtype=float32, numpy=
array([[3., 5.],
[7., 9.]], dtype=float32)>
Now the following Tensor comparison is returning True.
tf.shape(v) == tf.shape(tf.constant([1.0, 21],tf.float32))
<tf.Tensor: shape=(2,), dtype=bool, numpy=array([ True, True])>
Coming to your tf.Session() question, in TensorFlow 2.0 eager execution is enabled by default, still, if you need to disable eager execution and can use tf.Session like below.
import tensorflow as tf
tf.compat.v1.disable_eager_execution()
hello = tf.constant('Hello, TensorFlow!')
sess = tf.compat.v1.Session()
print(sess.run(hello))

use tf.shape() on tensorflow placeholder

Let's looke at this simple made up tf operation:
data = np.random.rand(1,2,3)
x = tf.placeholder(tf.float32, shape=[None, None, None], name='x_pl')
out = x
print ('shape:', tf.shape(out))
sess = tf.Session()
sess.run(out, feed_dict={x: data})
and the print is:
shape: Tensor("Shape_13:0", shape=(3,), dtype=int32)
I read that you should use tf.shape() to get the 'dynamic' shape of the tensor, which seems to be what I need, but why the shape is shape=(3,)?
why it is not (1,2,3)? as it should be determined when the session is run?
suppose this is part of a neural network where I need to know the last dimension of x, for example, to pass x into a Dense layer, for which the last dimension of x needed to be known.
how do it do it then?
It is because tf.shape() is an op and you have to run it within a session.
data = np.random.rand(1,2,3)
x = tf.placeholder(tf.float32, shape=[None, None, None], name='x_pl')
out = x
print ('shape:', tf.shape(out))
z = tf.shape(out)
sess = tf.Session()
out_, z_ =sess.run([out,z], feed_dict={x: data})
print(f"shape of out: {z_}")
will return
shape: Tensor("Shape:0", shape=(3,), dtype=int32)
shape of out: [1 2 3]
Even if you look at the example from the docs (https://www.tensorflow.org/api_docs/python/tf/shape):
t = tf.constant([[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]]])
tf.shape(t)
If you run it just like that it will return something like
<tf.Tensor 'Shape_4:0' shape=(3,) dtype=int32>
but if you run it within a session then you will get the expected result
t = tf.constant([[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]]])
print(sess.run(tf.shape(t)))
[2 2 3]

Element-wise assignment in tensorflow

In numpy, it could be easily done as
>>> img
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]], dtype=int32)
>>> img[img>5] = [1,2,3,4]
>>> img
array([[1, 2, 3],
[4, 5, 1],
[2, 3, 4]], dtype=int32)
However, there seems not exist similar operation in tensorflow.
You can never assign a value to a tensor in tensorflow as the change in tensor value is not traceable by backpropagation, but you can still get another tensor from origin tensor, here is a solution
import tensorflow as tf
tf.enable_eager_execution()
img = tf.constant(list(range(1, 10)), shape=[3, 3])
replace_mask = img > 5
keep_mask = tf.logical_not(replace_mask)
keep = tf.boolean_mask(img, keep_mask)
keep_index = tf.where(keep_mask)
replace_index = tf.where(replace_mask)
replace = tf.random_uniform((tf.shape(replace_index)[0],), 0, 10, tf.int32)
updates = tf.concat([keep, replace], axis=0)
indices = tf.concat([keep_index, replace_index], axis=0)
result = tf.scatter_nd(tf.cast(indices, tf.int32), updates, shape=tf.shape(img))
Actually there is a way to achieve this. Very similar to #Jie.Zhou's answer, you can replace tf.constant with tf.Variable, then replace tf.scatter_nd with tf.scatter_nd_update