【问题标题】:Clarification on Tensorflow 2.0 Masking关于 Tensorflow 2.0 掩码的说明
【发布时间】:2020-02-14 20:17:10
【问题描述】:

在使用 Keras 子类化 API 时,从 Tensorflow 文档中,他们给出了这个示例,说明如何将掩码传递给实现掩码的其他层。我想知道这是否是明确要求的,或者在嵌入层具有 mask_zero=True 之后是否正确处理。

class MyLayer(layers.Layer):

  def __init__(self, **kwargs):
    super(MyLayer, self).__init__(**kwargs)
    self.embedding = layers.Embedding(input_dim=5000, output_dim=16, mask_zero=True)
    self.lstm = layers.LSTM(32)

  def call(self, inputs):
    x = self.embedding(inputs)
    # Note that you could also prepare a `mask` tensor manually.
    # It only needs to be a boolean tensor
    # with the right shape, i.e. (batch_size, timesteps).
    mask = self.embedding.compute_mask(inputs)
    output = self.lstm(x, mask=mask)  # The layer will ignore the masked values
    return output

layer = MyLayer()
x = np.random.random((32, 10)) * 100
x = x.astype('int32')
layer(x)

我的困惑来自文档的另一个领域:

屏蔽

该层支持对可变数量的输入数据进行屏蔽 时间步长。要将掩码引入数据,请使用嵌入层 将 mask_zero 参数设置为 True。

这似乎意味着如果 mask_zero=True 则不需要在后续层上执行进一步的命令。

【问题讨论】:

    标签: tensorflow keras masking


    【解决方案1】:

    如果您阅读了Masking 层,它还将支持一旦您开始使用遮罩,其余所有层都会自动获取遮罩。

    引用:

    对于输入张量中的每个时间步(张量中的第 1 维),如果该时间步中输入张量中的所有值都等于 mask_value,则该时间步将在所有下游层中被屏蔽(跳过)(只要因为它们支持遮罩)。

    如果任何下游层不支持掩码但接收到这样的输入掩码,则会引发异常。

    这个other link 也声明了相同的内容。掩码将传播到所有层。

    引用:

    使用 Functional API 或 Sequential API 时,由 Embedding 或 Masking 层生成的掩码将通过网络传播到能够使用它们的任何层(例如 RNN 层)。 Keras 会自动获取与输入对应的掩码,并将其传递给任何知道如何使用它的层。

    第二个链接真的充满了关于屏蔽的细节。

    请注意,您显示的代码用于自定义嵌入。 If 教您如何“创建和传递”蒙版,如果您想创建将创建蒙版的图层。它基本上显示了正常的嵌入层的作用。

    因此,我们可以得出结论,如果您使用的是普通的Embedding 层,那么您只需要mask_zero=True,一切都会顺其自然。

    【讨论】:

    • 感谢您的回复,第二个链接也是我获得大部分信息的地方,但在您的第二个引用中,当我使用子类化 API 时,它被声明为“功能 API 或顺序 API” .我不确定这是否适用于我的工作。我还更新了我带错的代码 sn-p 来解释我的问题。
    【解决方案2】:

    除了给出的高层次答案,我们来看看一些重要的技术细节。

    如有疑问,请查看the masking source code,了解其工作原理。

    • Masking 为张量添加了一个 _keras_mask 属性,用于标记要跳过的条目,从而有效地让其他 API 方法知道它。
    • 通过supports_masking 属性测试自己是否有图层支持遮罩。示例:tf.keras.layers.GlobalMaxPool1D().supports_masking
    • 屏蔽逻辑是:如果所有特征都等于屏蔽值,则跳过一个时间步(TF 源代码使用not_equalany 标记剩余的内容)
    import tensorflow ast f
    arr = np.arange(6).reshape((1,6,1))
    arr_masked = tf.keras.layers.Masking(mask_value=5)(arr)
    
    print(arr_masked._keras_mask)
    print(arr_masked.numpy())
    

    【讨论】:

      【解决方案3】:

      我认为您必须在子类化层中逐层传递掩码。 来自 Tensorflow 文档:引用

      请注意,在子类模型或层的调用方法中,掩码不会自动传播,因此您需要手动将掩码参数传递给任何需要掩码的层。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-08-29
        • 2019-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多