【问题标题】:TypeError: 'Tensor' object does not support item assignment in TensorFlowTypeError:“张量”对象不支持 TensorFlow 中的项目分配
【发布时间】:2016-10-08 10:35:18
【问题描述】:

我尝试运行这段代码:

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)

但我在最后一行得到错误: TypeError: 'Tensor' object does not support item assignment 似乎我无法分配给张量,我该如何解决?

【问题讨论】:

    标签: python tensorflow


    【解决方案1】:

    一般来说,TensorFlow 张量对象是不可赋值的*,因此您不能在赋值的左侧使用它。

    最简单的方法是构建张量的 Python 列表,并在循环结束时将它们一起tf.stack()

    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)
    

     * 除了tf.Variable 对象,使用Variable.assign() 等方法。但是,rnn.rnn() 可能会返回一个不支持此方法的 tf.Tensor 对象。

    【讨论】:

    • 请注意,自 TensorFlow 1.0 以来,tf.pack() 已被 tf.stack() 取代。
    • 我在stackoverflow.com/questions/55871023/… 中遇到了同样的问题,但我不知道如何使用 tf.stack 来解决这个问题。请指导一下这个问题吗?
    • 如何做到这一点?: 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, :]
    【解决方案2】:

    另一种方法可以这样做。

    aa=tf.Variable(tf.zeros(3, tf.int32))
    aa=aa[2].assign(1)
    

    那么输出是:

    数组([0, 0, 1], dtype=int32)

    参考:https://www.tensorflow.org/api_docs/python/tf/Variable#assign

    【讨论】:

    • 我在尝试以这种方式实现时似乎遇到了错误: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)
    • 注意:tf.Variable 在会话运行期间保持其值,这并不总是正确的解决方案。
    • 这个答案在我将一维向量分配给二维数组的所有速度测试中表现最差。不要使用这种方法!迄今为止最快的是 mrry 的答案,即附加到列表和堆叠。
    • 在 TF2 中不起作用:EagerTensor 对象没有属性“assign”
    【解决方案3】:

    当你已经有了张量时, 使用tf.unstack (TF2.0) 将张量转换为列表,然后像@mrry 提到的那样使用 tf.stack。 (使用多维张量时,注意 unstack 中的轴参数)

    a_list = tf.unstack(a_tensor)
    
    a_list[50:55] = [np.nan for i in range(6)]
    
    a_tensor = tf.stack(a_list)
    

    【讨论】:

      【解决方案4】:

      正如comment 所说,一种解决方法是创建一个 NEW 张量,其中包含前一个张量,并在所需区域上创建一个新张量。

      1. 创建形状为 outputs 的蒙版,在要替换的索引上使用 0,在其他位置使用 1(也可以使用 TrueFalse
      2. 使用新的所需值创建形状为outputs 的新矩阵:new_values
      3. 仅将需要的索引替换为:outputs_new = outputs* mask + new_values * (1 - mask)

      如果你能给我一个 MWE,我可以为你做代码。

      一个很好的参考是这个注释:How to Replace Values by Index in a Tensor with TensorFlow-2.0

      【讨论】:

      • 如何做到这一点?对于范围内的 x(int(r.shape[2]/2)): 对于范围内的 d(1,int(r.shape[0]/2)): r[d, :, x, :] = r [0, :, x+d, :]
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-31
      • 2014-02-18
      • 2017-03-26
      • 2021-08-05
      • 1970-01-01
      相关资源
      最近更新 更多