TypeError: 'Tensor' object does not support item assignment in TensorFlow
Question:
I try to run this code:
outputs, states = rnn.rnn(lstm_cell, x, initial_state=initial_state, sequence_length=real_length)
tensor_shape = outputs.get_shape()
for step_index in range(tensor_shape[0]):
word_index = self.x[:, step_index]
word_index = tf.reshape(word_index, [-1,1])
index_weight = tf.gather(word_weight, word_index)
outputs[step_index, :, :]=tf.mul(outputs[step_index, :, :] , index_weight)
But I get error on last line:
TypeError: 'Tensor' object does not support item assignment
It seems I can not assign to tensor, how can I fix it?
Answers:
In general, a TensorFlow tensor object is not assignable, so you cannot use it on the left-hand side of an assignment.
The easiest way to do what you’re trying to do is to build a Python list of tensors, and tf.stack()
them together at the end of the loop:
outputs, states = rnn.rnn(lstm_cell, x, initial_state=initial_state,
sequence_length=real_length)
output_list = []
tensor_shape = outputs.get_shape()
for step_index in range(tensor_shape[0]):
word_index = self.x[:, step_index]
word_index = tf.reshape(word_index, [-1,1])
index_weight = tf.gather(word_weight, word_index)
output_list.append(tf.mul(outputs[step_index, :, :] , index_weight))
outputs = tf.stack(output_list)
* With the exception of tf.Variable
objects, using the Variable.assign()
etc. methods. However, rnn.rnn()
likely returns a tf.Tensor
object that does not support this method.
Another way you can do it is like this.
aa=tf.Variable(tf.zeros(3, tf.int32))
aa=aa[2].assign(1)
then the output is:
array([0, 0, 1], dtype=int32)
ref:https://www.tensorflow.org/api_docs/python/tf/Variable#assign
When you have a tensor already,
convert the tensor to a list using tf.unstack (TF2.0) and then use tf.stack like @mrry has mentioned. (when using a multi-dimensional tensor, be aware of the axis argument in unstack)
a_list = tf.unstack(a_tensor)
a_list[50:55] = [np.nan for i in range(6)]
a_tensor = tf.stack(a_list)
As this comment says, a workaround would be to create a NEW tensor with the previous one and a new one on the zones needed.
- Create a mask of shape
outputs
with 0’s on the indices you want to replace and 1’s elsewhere (Can work also with True
and False
)
- Create new matrix of shape
outputs
with the new desired value: new_values
- Replace only the needed indexes with:
outputs_new = outputs* mask + new_values * (1 - mask)
If you would provide me with an MWE I could do the code for you.
A good reference is this note: How to Replace Values by Index in a Tensor with TensorFlow-2.0
-
Neither tf.Tensor
nor tf.Variable
is element-wise-assignable.
There is a trick however which is not the most efficient way of
course, especially when you do it iteratively.
You can create a mask
and a new_layer
tensor with new values and
then
do a Hadamard product (element-wise product).
x = original * mask + new_layer * (1-mask)
The original * mask
part sets the specified values of original
to 0 and the second part, new_layer*(1-mask)
assigns new_layer
tensor whatever you want without modifying the elements assigned to
0 by the mask
tensor in the previous step.
-
Another way is to use numpy instead:
x = np.zeros((tensor dimensions))
-
Use Pytorch:
x = torch.zeros((tensor dimensions))
I try to run this code:
outputs, states = rnn.rnn(lstm_cell, x, initial_state=initial_state, sequence_length=real_length)
tensor_shape = outputs.get_shape()
for step_index in range(tensor_shape[0]):
word_index = self.x[:, step_index]
word_index = tf.reshape(word_index, [-1,1])
index_weight = tf.gather(word_weight, word_index)
outputs[step_index, :, :]=tf.mul(outputs[step_index, :, :] , index_weight)
But I get error on last line:
TypeError: 'Tensor' object does not support item assignment
It seems I can not assign to tensor, how can I fix it?
In general, a TensorFlow tensor object is not assignable, so you cannot use it on the left-hand side of an assignment.
The easiest way to do what you’re trying to do is to build a Python list of tensors, and tf.stack()
them together at the end of the loop:
outputs, states = rnn.rnn(lstm_cell, x, initial_state=initial_state,
sequence_length=real_length)
output_list = []
tensor_shape = outputs.get_shape()
for step_index in range(tensor_shape[0]):
word_index = self.x[:, step_index]
word_index = tf.reshape(word_index, [-1,1])
index_weight = tf.gather(word_weight, word_index)
output_list.append(tf.mul(outputs[step_index, :, :] , index_weight))
outputs = tf.stack(output_list)
* With the exception of tf.Variable
objects, using the Variable.assign()
etc. methods. However, rnn.rnn()
likely returns a tf.Tensor
object that does not support this method.
Another way you can do it is like this.
aa=tf.Variable(tf.zeros(3, tf.int32))
aa=aa[2].assign(1)
then the output is:
array([0, 0, 1], dtype=int32)
ref:https://www.tensorflow.org/api_docs/python/tf/Variable#assign
When you have a tensor already,
convert the tensor to a list using tf.unstack (TF2.0) and then use tf.stack like @mrry has mentioned. (when using a multi-dimensional tensor, be aware of the axis argument in unstack)
a_list = tf.unstack(a_tensor)
a_list[50:55] = [np.nan for i in range(6)]
a_tensor = tf.stack(a_list)
As this comment says, a workaround would be to create a NEW tensor with the previous one and a new one on the zones needed.
- Create a mask of shape
outputs
with 0’s on the indices you want to replace and 1’s elsewhere (Can work also withTrue
andFalse
) - Create new matrix of shape
outputs
with the new desired value:new_values
- Replace only the needed indexes with:
outputs_new = outputs* mask + new_values * (1 - mask)
If you would provide me with an MWE I could do the code for you.
A good reference is this note: How to Replace Values by Index in a Tensor with TensorFlow-2.0
-
Neither
tf.Tensor
nortf.Variable
is element-wise-assignable.
There is a trick however which is not the most efficient way of
course, especially when you do it iteratively.You can create a
mask
and anew_layer
tensor with new values and
thendo a Hadamard product (element-wise product).
x = original * mask + new_layer * (1-mask)
The
original * mask
part sets the specified values oforiginal
to 0 and the second part,new_layer*(1-mask)
assignsnew_layer
tensor whatever you want without modifying the elements assigned to
0 by themask
tensor in the previous step. -
Another way is to use numpy instead:
x = np.zeros((tensor dimensions))
-
Use Pytorch:
x = torch.zeros((tensor dimensions))