在tensorflow的循环中为数组赋值

时间:2017-03-14 06:13:18

标签: python tensorflow

我在tensorflow中有一个数组,我想根据for循环中的另一个数组更新它的值。这是代码:

def get_weights(labels, class_ratio=0.5):
        weights = tf.ones_like(labels, dtype=tf.float64))

        pos_num = class_ratio * 100
        neg_num = 100 - class_ratio * 100
        for i in range(labels.shape[0]):
            if labels[i] == 0:
               weights[i].assign(pos_num/neg_num)
            else:
               weights[i].assign(neg_num)

        return weights

然后我有这个代码来调用上面的函数:

with tf.Graph().as_default():
     labels = tf.placeholder(tf.int32, (5,))
     example_weights = get_weights(labels, class_ratio=0.1)
     with tf.Session() as sess:
          np_labels = np.random.randint(0, 2, 5)
          np_weights = sess.run(example_weights, feed_dict={labels: np_labels})
         print("Labels:  %r" % (np_labels,))
         print("Weights: %r" % (np_weights,))

但是当我运行它时,它给了我这个错误:

ValueError: Sliced assignment is only supported for variables

如何在tensorflow中分配/更新数组的值?

1 个答案:

答案 0 :(得分:2)

TensorFlow中的tf.Tensor是一个只读值 - 实际上是用于计算只读值的符号表达式 - 因此通常不能为其赋值。 (主要例外是tf.Variable个对象。)这意味着您鼓励使用“功能”操作来定义张量。例如,有几种方法可以在功能上生成weights张量:

  • 由于weights被定义为labels的元素转换,您可以使用tf.map_fn()创建一个新的张量(包含tf.cond()到{ {3}})通过在其上映射函数:

    def get_weights(labels, class_ratio=0.5):
      pos_num = tf.constant(class_ratio * 100)
      neg_num = tf.constant(100 - class_ratio * 100)
    
      def compute_weight(x):
        return tf.cond(tf.equal(x, 0), lambda: pos_num / neg_num, lambda: neg_num)
    
      return tf.map_fn(compute_weight, labels, dtype=tf.float32)
    

    此版本允许您对labels的每个元素应用任意复杂的函数。

  • 但是,由于功能简单,计算成本低,并且可以使用简单的TensorFlow操作表示,因此您可以避免使用tf.map_fn()而是使用replace the if statement

    def get_weights(labels, class_ratio=0.5):
      pos_num = tf.fill(tf.shape(labels), class_ratio * 100)
      neg_num = tf.fill(tf.shape(labels), 100 - class_ratio * 100)
      return tf.where(tf.equal(labels, 0), pos_num / neg_num, neg_num)
    

    (您也可以在tf.where()版本中使用tf.cond()代替tf.map_fn()。)