【问题标题】:how to average a tensor axis with specified mask in tensorflow如何在张量流中使用指定的掩码对张量轴进行平均
【发布时间】:2018-06-30 16:51:34
【问题描述】:

例如:

我有一个输入tensor(input),形状为(?,10)dtype=float32,第一个维度表示batch_size

还有一个面具tensor(mask),形状为(?,10)mask[sample_number][True,True,False,...] 类似,表示面具

标签张量(avg_label),形状为(?,),表示每个样本的掩码位置的正确平均值

我想训练模型,但找不到获得输出的好方法。

tf.reduce_...(例如 tf.reduce_mean)函数似乎不支持关于屏蔽的论点。

我尝试tf.boolean_mask,但它会将输出形状扁平化为一维,抛出sample_number维度,因此无法区分样本

我考虑过tf.where,比如:

masked=tf.where(mask,input,tf.zeros(tf.shape(input)))
avg_out=tf.reduce_mean(masked,axis=1)
loss=tf.pow(avg_out-avg_label,2)

但是上面的代码肯定是行不通的,因为 False 设置为 0 会改变 avg。如果使用 np.nan ,它总是会得到 nan。我想知道做reduce操作时是否有一个表示缺席的值。

我该怎么做?

【问题讨论】:

  • 您的问题不清楚。您有一个形状为 (?, 10) 的输入张量,一个形状为 (?, 10) 的蒙版张量,并且您想获得输入的平均值,仅适用于 mask=True 的那些值。对吗?
  • 对,就是这个意思。

标签: python tensorflow artificial-intelligence conv-neural-network


【解决方案1】:

你可以使用tf.ragged.boolean_mask来保持维度。

tf.reduce_mean(tf.ragged.boolean_mask(x, mask=mask), axis=1)

【讨论】:

    【解决方案2】:

    您可以通过计算掩码中的非消失条目来编写自己的均值函数

    为什么不直接

    import tensorflow as tf
    import numpy as np
    
    B, H, W, C = 5, 224, 224, 3
    
    data = np.random.randn(B, H, W, C).astype(np.float32)
    mask = np.random.randint(2, size=(B, H, W, C)).astype(np.float32)
    
    expected = (data * mask).sum(axis=(1, 2, 3), keepdims=True)
    expected = expected / mask.sum(axis=(1, 2, 3), keepdims=True)
    
    data_op = tf.convert_to_tensor(data)
    mask_op = tf.convert_to_tensor(mask)
    
    actual_op = tf.reduce_sum(tf.multiply(data, mask), axis=[1, 2, 3], keepdims=True) / tf.reduce_sum(mask, axis=[1, 2, 3], keepdims=True)
    
    with tf.Session() as sess:
        actual = sess.run(actual_op)
    
    np.testing.assert_allclose(actual, expected)
    

    【讨论】:

    • 如果这不是讽刺,请随意接受。否则,请相应地更改您的问题,以便您真正获得所需的信息。
    • 如果在填充上下文中使用它,我可能会建议使用tf.math.divide_no_nan。序列末端的东西可能在掩码中沿您要减少的任何维度全为零。
    【解决方案3】:

    您可以使用tf.boolean_mask

    In [17]: tensor = tf.constant([[1, 2], [3, 4], [5, 6]])
    In [18]: mask = np.array([[True, False], [False, True], [True, False]])
    In [19]: masked = tf.boolean_mask(tensor, mask)
    In [20]: masked.eval()
    Out[20]: array([1, 4, 5], dtype=int32)
    In [21]: tf.reduce_mean(masked).eval()
    Out[21]: 3
    

    对于 False 掩码值,您可以使用 tf.logical_not 切换掩码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-31
      • 2019-11-05
      • 1970-01-01
      • 2021-07-08
      • 2019-04-13
      • 2020-03-19
      相关资源
      最近更新 更多