【问题标题】:tf.keras embedding with mask_zero=True followed by GlobalAveragePooling1D generate TypeErrortf.keras 嵌入 mask_zero=True 后跟 GlobalAveragePooling1D 生成 TypeError
【发布时间】:2020-02-12 11:45:17
【问题描述】:

我正在使用 tf.keras 在 google colab 上使用 tensorflow v2。我正在尝试使用带有掩蔽的嵌入,然后是全局平均值。这是我的代码:

vocab_size = 1500

inputs = Input(shape=(None,), dtype=tf.int32, name='word_sequence')

x = Embedding(input_dim=vocab_size, output_dim=16, mask_zero=True)(inputs)

outputs = tf.keras.layers.GlobalAveragePooling1D()(x)

model = Model(inputs, outputs)

但是我收到了这个错误:

TypeError:无法将类型对象转换为张量。内容:[-1,无,1]。考虑将元素转换为支持的类型。

如果我提供了序列 Input(shape=(10,), .....) 的显式长度,那么它似乎没有错误(尽管我没有用样本数据对其进行测试)。我想知道为什么你需要指定一个显式的序列长度,我认为这可以在运行时当层第一次遇到数据时懒惰地完成。

此外,以下作品(取自“masking and padding” tf 教程):

inputs = tf.keras.Input(shape=(None,), dtype='int32')
x = layers.Embedding(input_dim=5000, output_dim=16, mask_zero=True)(inputs)
outputs = layers.LSTM(32)(x)

model = tf.keras.Model(inputs, outputs)

对于 LSTM,在模型的功能 api 构建期间,它似乎对 None 的输入形状很满意。

有人能解释一下 GlobalAveragePooling1D 有什么问题吗,或者这应该可以工作,但我做错了什么?

谢谢。

【问题讨论】:

  • 理论上,您不需要指定数组大小来计算均值。例如 np.mean(...) 不需要明确的输入长度。天真地,我确实认为这是一个错误,假设我在 API 调用方面做的一切都是正确的。

标签: keras mask embedding tf.keras max-pooling


【解决方案1】:

我没有添加评论的声誉,所以我想说的是:我似乎有同样的问题,无论是 GRU 还是 LSTM。当我改用 GlobalMaxPooling1D 时,问题似乎消失了。感觉是Masking底层实现造成的问题,但是我对底层Keras API一无所知,无法评论。

【讨论】:

  • 也许您可以分享您的 GRU/LSTM 用例。我认为他们应该工作。但我只尝试了该教程中使用的简单代码(我的 Q 中也粘贴了代码 sn-p)。
【解决方案2】:

这是因为 GlobalAveragePooling1D 的实现在 input_mask 不为 None 时需要指定时间步长维度。所以如果你尝试在Embedding层去掉mask_zero = True,就可以成功构建模型。

查看 GlobalAveragePooling1D 的源代码,我们可以看到:

  def call(self, inputs, mask=None):
    steps_axis = 1 if self.data_format == 'channels_last' else 2
    if mask is not None:
      mask = math_ops.cast(mask, backend.floatx())
      input_shape = inputs.shape.as_list()
      broadcast_shape = [-1, input_shape[steps_axis], 1]
      mask = array_ops.reshape(mask, broadcast_shape)
      inputs *= mask
      return backend.sum(inputs, axis=steps_axis) / math_ops.reduce_sum(
          mask, axis=steps_axis)
    else:
      return backend.mean(inputs, axis=steps_axis)

所以如果掩码不是无(在您的示例中,掩码是嵌入层生成的掩码,因为您设置了 mask_zero=True),broadcast_shape 将为 [-1, None, 1],并且 None 会导致错误在重塑(掩码,broadcast_shape)。所以我认为唯一的解决方案是将时间步长(序列长度)指定为输入形状。

【讨论】:

    猜你喜欢
    • 2018-10-02
    • 2018-10-14
    • 2019-09-07
    • 2018-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多