【问题标题】:Tensorflow 2 - How to conditionally update values directly in tf.VariableTensorflow 2 - 如何有条件地直接在 tf.Variable 中更新值
【发布时间】:2021-07-02 22:21:08
【问题描述】:

问题

请告知如何有条件地更新原始 tf.Variable。这是与conditional assignment of tf.variable in Tensorflow 2 不同的问题。

背景

tf.Variable 是可变的,assign 方法将更新相同的内存区域。看起来assign 方法在分配值时没有合并条件的选项。因此我想tf.where 是有条件地更新 tf.Variable。

Returns:
    If x and y are provided: 
        A Tensor with the same type as x and y, and shape that is broadcast from the condition, x, and y.
    Otherwise: 
        A Tensor with shape (num_true, dim_size(condition)).

在 numpy 中,可以使用索引直接更新 numpy 数组,但在 TensorFlow 中似乎没有这种方式。

# Numpy conditional uddate with boolean indexing
x = np.random.uniform(-1, 1, size=(3, 4))
x[x > 0] = 0

问题

由于tf.Variable 是可变的,预计tf.where 会改变原来的Variable,但是如下,原来的Variable x 没有更新。

x = tf.Variable(np.random.uniform(-1, 1, size=(3,4)), dtype=tf.float32)
print(f"x:{x}\n")
print(f"x > 0:\n{x > 0}\n")
print(f"tf.where(x>0, 1, x):\n{tf.where(x>0, 1, x)}")

x  # check if updated

结果:

# --------------------------------------------------------------------------------
# Original tf.Variable x
# --------------------------------------------------------------------------------
x is <tf.Variable 'Variable:0' shape=(3, 4) dtype=float32, numpy=
array([[ 0.8015974 ,  0.8223503 , -0.2704468 ,  0.01874248],
       [ 0.46989247,  0.4753061 , -0.06808566, -0.57646054],
       [ 0.07082719,  0.2924774 , -0.12741995,  0.3168819 ]],
      dtype=float32)>

x > 0 is [[ True  True False  True]
 [ True  True False False]
 [ True  True False  True]]

# --------------------------------------------------------------------------------
# Update using tf.where
# --------------------------------------------------------------------------------
tf.where(x>0, 1, x)=
[[ 1.          1.         -0.2704468   1.        ]
 [ 1.          1.         -0.06808566 -0.57646054]
 [ 1.          1.         -0.12741995  1.        ]]

# --------------------------------------------------------------------------------
# The x is the same as before.
# --------------------------------------------------------------------------------
<tf.Variable 'Variable:0' shape=(3, 4) dtype=float32, numpy=
array([[ 0.8015974 ,  0.8223503 , -0.2704468 ,  0.01874248],
       [ 0.46989247,  0.4753061 , -0.06808566, -0.57646054],
       [ 0.07082719,  0.2924774 , -0.12741995,  0.3168819 ]],
      dtype=float32)>

请帮助我了解是否有办法直接更新x


注意事项

首先,幻灯片操作的返回值是一个张量,它不是原始变量。

var_slice = var[4:5]
var_slice.assign(math_ops.sub(var, const))

对于张量,它没有“assign”或“assign_add”等方法。

我认为最可行的方法是创建一个 TensorArray,其中包含 您的平均值/方差值幻灯片,并在 单元格的 call() 主体。一旦图层遍历所有时间步,您 可以为 TensorArray 做一个堆栈并将值分配回 变量本身。您不必连续写入变量 在处理时间步时,因为时间步 t 不应该影响 结果为 t+1(如果我正确理解您的问题)

【问题讨论】:

    标签: tensorflow


    【解决方案1】:

    要更新tf.Variable,您需要致电assign。在Introduction to Variables 指南中阅读更多信息。

    >>> import tensorflow as tf
    >>> tf.random.set_seed(0)
    >>> x = tf.Variable(tf.random.uniform((3,4),-1,1), dtype=tf.float32)
    >>> x
    <tf.Variable 'Variable:0' shape=(3, 4) dtype=float32, numpy=
    array([[-0.41604972, -0.5868671 ,  0.07078147,  0.12251496],
           [-0.16665101,  0.6156559 , -0.0135498 ,  0.9962585 ],
           [ 0.3934703 , -0.7492528 ,  0.4196334 ,  0.32483125]],
          dtype=float32)>
    >>> x.assign(tf.where(x>0,x,0))
    <tf.Variable 'UnreadVariable' shape=(3, 4) dtype=float32, numpy=
    array([[0.        , 0.        , 0.07078147, 0.12251496],
           [0.        , 0.6156559 , 0.        , 0.9962585 ],
           [0.3934703 , 0.        , 0.4196334 , 0.32483125]], dtype=float32)>
    >>> x
    <tf.Variable 'Variable:0' shape=(3, 4) dtype=float32, numpy=
    array([[0.        , 0.        , 0.07078147, 0.12251496],
           [0.        , 0.6156559 , 0.        , 0.9962585 ],
           [0.3934703 , 0.        , 0.4196334 , 0.32483125]], dtype=float32)>
    

    【讨论】:

      【解决方案2】:

      这里还有一些案例。主要内容是更新tf.Variable 中的内容,我们使用assign。但请注意,它会急切地赋值。

      x = tf.Variable(range(5), shape=(5,), name="a")
      x.numpy()
      array([0, 1, 2, 3, 4], dtype=int32)
      
      x.assign(tf.where(x > 2, x, -1)).numpy()
      array([-1, -1, -1,  3,  4], dtype=int32)
      
      x.assign(range(5,10)).numpy()
      array([5, 6, 7, 8, 9], dtype=int32)
      
      x.assign(tf.where(x < 8, tf.range(5), tf.where(x > 8 , x, -1))).numpy()
      array([ 0,  1,  2, -1,  9], dtype=int32)
      

      【讨论】:

        猜你喜欢
        • 2021-04-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-10
        • 1970-01-01
        • 2018-06-27
        • 2019-10-21
        • 1970-01-01
        相关资源
        最近更新 更多