在使用Keras子类化API时,从Tensorflow文档中,他们给出了有关如何将遮罩传递给其他实现遮罩的层的示例。我想知道这是否是明确要求的,或者在Embedding层具有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,则无需在后续层上执行其他命令。
答案 0 :(得分:2)
如果您了解了Masking层,那么它也支持在开始使用蒙版后,所有其他层都会自动获得蒙版。
报价:
对于输入张量中的每个时间步长(张量中的第1维),如果该时间步长上的输入张量中的所有值均等于mask_value,则该时间步长将在所有下游层中被屏蔽(跳过)因为它们支持遮罩。
如果任何下游层不支持屏蔽但仍接收到这样的输入掩码,则会引发异常。
此other link也表示相同。遮罩将传播到所有层。
报价:
使用功能性API或顺序性API时,由嵌入或掩蔽层生成的掩码将通过网络传播到能够使用它们的任何层(例如RNN层)。 Keras将自动获取与输入相对应的遮罩,并将其传递给知道如何使用该遮罩的任何层。
第二个链接确实包含有关遮罩的详细信息。
请注意,您显示的代码是用于自定义嵌入的。如果您要教您如何“创建并传递”蒙版,则要创建一个将创建蒙版的图层。它基本上显示了普通嵌入层的功能。
因此,我们可以得出结论,如果您使用的是普通的Embedding
层,则只需mask_zero=True
,一切都会顺畅进行。
答案 1 :(得分:-1)
我认为您必须在子类化层的每一层传递蒙版。 从Tensorflow文档中:引用
请注意,在子类化模型或图层的调用方法中,不会自动传播遮罩,因此您需要手动将遮罩参数传递给需要一个图层的任何图层。