微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Keras 掩码从掩码层通过循环、池化和密集层传播

如何解决Keras 掩码从掩码层通过循环、池化和密集层传播

系统信息

  • 操作系统平台和发行版(例如 Linux Ubuntu 16.04):Debian 10
  • 从(源代码或二进制文件)安装的 TensorFlow:pip
  • TensorFlow 版本(使用下面的命令):2.4.1
  • Python 版本:3.8

当前行为

据我所知,Masking 层创建的遮罩仅通过某些层传播,我无法确定通过哪些层以及最终结果是否会因缺少此遮罩而有所不同。

在我的示例中,我已经嵌入了形状 (None,timesteps,features) 的输入并填充了 0,以便具有恒定的 timesteps 值。我想通过一些循环层传递输入,然后执行分类(或标记分类,但问题仍然存在)。问题是:

  1. 如果我的输出层没有 input_mask(例如在损失中计算的 0-padding),我是否有问题?
  2. 是否需要在每次需要传播蒙版时制作自定义图层(不修改 timesteps 维度时)?

对于下面四个最小示例中的每一个,我运行这段代码来确定哪个层有或没有 input_mask 属性

model = make_model(120,768)
print(model.summary())
for layer in model.layers:
    print(layer.name,layer.input_mask)

示例 1:使用 Masking+LSTM+Dense 进行 Token 分类

def make_model(m_len: int,emb_dim: int):
    inputs = Input(shape=(m_len,emb_dim))
    x = Masking(mask_value=0)(inputs)
    x = Bidirectional(LSTM(256,return_sequences=True))(x)
    output = Dense(1,activation="sigmoid")(x)
    mod = Model(inputs,output)
    mod.compile(
        optimizer="Adam",loss="binary_crossentropy",metrics=["accuracy"]
    )
    return mod

输出

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(None,120,768)]        0         
_________________________________________________________________
masking (Masking)            (None,768)          0         
_________________________________________________________________
bidirectional (Bidirectional (None,512)          2099200   
_________________________________________________________________
dense (Dense)                (None,1)            513       
=================================================================
Total params: 2,099,713
Trainable params: 2,713
Non-trainable params: 0
_________________________________________________________________
None
input_1 None
masking None
bidirectional KerasTensor(type_spec=TensorSpec(shape=(None,120),dtype=tf.bool,name=None),name='masking/Squeeze:0')
dense KerasTensor(type_spec=TensorSpec(shape=(None,name='Placeholder_2:0')

由于 timesteps 维度没有改变,因此掩码显然通过循环层传播,并且也在 Dense 层中。

示例 2:使用 Masking+LSTM+Dense 进行分类

与上面相同的代码,但设置了 return_sequences=False输出

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(None,512)               2099200   
_________________________________________________________________
dense (Dense)                (None,1)                 513       
=================================================================
Total params: 2,name='masking/Squeeze:0')
dense None

到目前为止按预期工作,降维不允许掩码传递。

示例 3:使用 Masking+LSTM 进行分类

def make_model(m_len: int,return_sequences=True))(x)
    output = LSTM(1,metrics=["accuracy"]
    )
    return mod

输出

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(None,512)          2099200   
_________________________________________________________________
lstm_1 (LSTM)                (None,1)                 2056      
=================================================================
Total params: 2,101,256
Trainable params: 2,256
Non-trainable params: 0
_________________________________________________________________
None
input_1 None
masking None
bidirectional KerasTensor(type_spec=TensorSpec(shape=(None,name='masking/Squeeze:0')
lstm_1 KerasTensor(type_spec=TensorSpec(shape=(None,name='Placeholder_2:0')

即使去除timesteps 暗淡,蒙版输出层上仍然有效,这种行为是否符合预期?

示例 4:使用 Masking+LSTM+AveragePooling+Flatten+Dense 进行分类

def make_model(m_len: int,return_sequences=True))(x)
    x = AveragePooling1D(pool_size=512,data_format='channels_first')(x)
    x = Flatten()(x)
    output = Dense(1,512)          2099200   
_________________________________________________________________
average_pooling1d (AveragePo (None,1)            0         
_________________________________________________________________
flatten (Flatten)            (None,120)               0         
_________________________________________________________________
dense (Dense)                (None,1)                 121       
=================================================================
Total params: 2,321
Trainable params: 2,321
Non-trainable params: 0
_________________________________________________________________
None
input_1 None
masking None
bidirectional KerasTensor(type_spec=TensorSpec(shape=(None,name='masking/Squeeze:0')
average_pooling1d KerasTensor(type_spec=TensorSpec(shape=(None,name='Placeholder_2:0')
flatten None
dense None

这个我不太自信,但对最后一个维度求平均不会改变 timesteps 维度,但掩码没有传播。我想也许平均可以创建“0”向量,之后会被忽略,但掩码是由掩码计算的,并且在这里是 120 长布尔值,无论如何。 AveragePooling1D 没有将遮罩传递给 Flatten 层有什么原因吗?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。