【问题标题】:Mask tensorflow input data屏蔽张量流输入数据
【发布时间】:2017-12-07 11:15:45
【问题描述】:

我想对 tensorflow 中的每个输入特征应用一个掩码。如果掩码是固定的,这很容易做到 - 只需在图中定义并应用它。问题是,我希望在训练期间改变面具 - 每个训练步骤都会略有不同。事实上,对于每一步,我都有一个函数,它返回一个 numpy 数组,表示每一步的掩码。

经过多次反复试验和搜索,我发现无法应用此掩码 - 就我而言,这是不可能的,由 tensorflow 的属性要求修复计算的所有属性,当图表已构建。

但是,我对 tensorflow 还很陌生,所以这很可能是可行的,甚至很容易。谁能帮帮我?

伪代码是:

    build graph with mask as placeholder
    Loop over training steps
        numpy_array = my_func(step_number)
        mask_placeholder = something(numpy_array)*
        Session.run([my graph(mask_placeholder)])*

星星是我不知道该做什么的地方。

【问题讨论】:

    标签: tensorflow


    【解决方案1】:

    这似乎只用 numpy 就很容易了。事实上,我有一种情况,我想做一些对我来说在 numpy 中似乎微不足道但在 tensorflow 中困难的事情。具体来说,我想根据这些元素的值将数学函数应用于张量的某些元素。例如:

    array_a[array_a > 0] = np.log(array_a + 1)[array_a > 0]

    这意味着“A 大于零的 A 等于 A 的对数加一,其中 A 大于零”。

    直到我发现 tf.py_func,我才在 tensorflow 中取得成功。根据https://www.tensorflow.org/api_docs/python/tf/py_func对py_func的描述,

    “给定一个 python 函数 func,它将 numpy 数组作为其输入并返回 numpy 数组作为其输出,将此函数包装为 TensorFlow 图中的一个操作。”

    因此,要将其应用于您的情况,您可以执行类似的操作

    def tf_mask(the_tensor,the_mask):
        def np_mask(a,b):
            return a[b]
        return tf.py_func(np_mask, [the_tensor,the_mask], tf.float32)
    

    或者如果您想保留数组的形状,请执行类似的操作

    def tf_mask(the_tensor,the_mask):
        def np_mask(a,b):
            a[b == 0] = 0
            return a
        return tf.py_func(np_mask, [the_tensor,the_mask], tf.float32)
    

    综上,在numpy中想办法做到,然后使用py_func。 Numpy 非常强大,很高兴我们可以在 Tensorflow 中使用这种强大功能。

    【讨论】:

      【解决方案2】:

      您需要将屏蔽操作逻辑添加为TensorFlow graph 的一部分。具体来说,control flow operatorstf.logical_andtf.logical_ortf.case 允许您在模型时有条件地选择所需的数据正在运行。

      例如,下面的代码展示了如何根据两个训练数据或标签输入的状态构建一个 4 元素张量。您应该能够将类似的逻辑应用于您的情况。

      def const_v(val):
          return tf.constant(val, tf.float32)
      
      def const_1():
          return const_v(1)
      
      def const_0():
          return const_v(0)
      
      def cond_and(cond_1, cond_2, val_1, val_2):
          return tf.logical_and(tf.equal(cond_1, val_1),
                                tf.equal(cond_2, val_2))
      
      def vec4(c1, c2, c3, c4):
          return [const_v(c1), const_v(c2), const_v(c3), const_v(c4)]
      
      # c1 c2 vector
      # 1 1 [1, 0 , 0 ,0]
      # 1 0 [0, 1, 0, 0]
      # 0 1 [0, 0, 1, 0]
      # 0 0 [0, 0, 0, 1]
      
      def combined_conditions(cond_1, cond_2):
          return tf.stack(tf.case({cond_and(cond_1, cond_2, const_1(), const_1()): lambda: vec4(1, 0, 0, 0),
                          cond_and(cond_1, cond_2, const_1(), const_0()): lambda: vec4(0, 1, 0, 0),
                          cond_and(cond_1, cond_2, const_0(), const_1()): lambda: vec4(0, 0, 1, 0),
                          cond_and(cond_1, cond_2, const_0(), const_0()): lambda: vec4(0, 0, 0, 1)
                          }, default=lambda: vec4(0, 0, 0, 0), exclusive=True))
      

      【讨论】:

      • 我不确定这是否能解决问题。让我举一个具体的例子。假设我的特征是长度为 100,000 的向量。我用 100,000 步进行训练。在每一步,我想用一个和零的掩码向量来掩码输入特征,其中一个的个数就是训练步数。图表必须以某种方式知道这个数字并在每一步创建一个新的掩码。请注意,它需要的数字不能从输入数据集本身收集。
      • 我从未使用过它们,但您似乎可以从Training Utility 函数之一获得训练步骤——tf.train.get_global_step 或 tf.train.global_step。这加上图形逻辑和一些聪明的 Python 可能会解决您的问题。
      猜你喜欢
      • 1970-01-01
      • 2020-04-18
      • 1970-01-01
      • 1970-01-01
      • 2018-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-07
      相关资源
      最近更新 更多