54

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?

5 Answers 5

53

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Note that tf.pack() has been replaced by tf.stack() since TensorFlow 1.0.
I have the same problem with the issue in stackoverflow.com/questions/55871023/…, but I do not know how can I do this with tf.stack. could please guide about this issue?
How would one do this?: for x in range(int(r.shape[2]/2)): for d in range(1,int(r.shape[0]/2)): r[d, :, x, :] = r[0, :, x+d, :]
20

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

4 Comments

I seem to be getting an error when trying to implement it this way: x = tf.Variable(tf.ones([1,2,2,3], tf.float32)) x = x[:,:,:,1].assign(2.0) with tf.Session() as sess: sess.run(tf.global_variables_initializer()) x_data = sess.run(x)
note: tf.Variable maintains its value across session runs, this is not always the right solution.
This answer has the worst performance in all speed tests I've done to assign 1D vectors to 2D array. Don't use this method! The fastest so far is mrry's answer with appending to a list and stacking.
doesn't work in TF2: EagerTensor object has no attribute 'assign'
8

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)

1 Comment

this worked for me. thanks.
1
  1. 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.

  2. Another way is to use numpy instead:

    x = np.zeros((tensor dimensions)) 
    
  3. Use Pytorch:

    x = torch.zeros((tensor dimensions))
    

Comments

0

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.

  1. 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)
  2. Create new matrix of shape outputs with the new desired value: new_values
  3. 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

1 Comment

How would one do this? for x in range(int(r.shape[2]/2)): for d in range(1,int(r.shape[0]/2)): r[d, :, x, :] = r[0, :, x+d, :]

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.