【问题标题】:Variable sentence length for LSTM using word2vec as inputs on tensorflow使用 word2vec 作为 tensorflow 输入的 LSTM 可变句子长度
【发布时间】:2018-09-27 07:33:12
【问题描述】:

我正在构建一个使用 word2vec 作为输入的 LSTM 模型。我正在使用张量流框架。我已经完成了词嵌入部分,但我被 LSTM 部分卡住了。

这里的问题是我有不同的句子长度,这意味着我必须进行填充或使用具有指定序列长度的 dynamic_rnn。我和他们两个都在苦苦挣扎。

  1. 填充。 填充令人困惑的部分是当我进行填充时。我的模型是这样的

    word_matrix=model.wv.syn0
    X = tf.placeholder(tf.int32, 形状)
    数据 = tf.placeholder(tf.float32, 形状)
    数据 = tf.nn.embedding_lookup(word_matrix, X)

然后,我将 word_matrix 的单词索引序列输入 X。我担心如果我将零填充到输入 X 的序列中,那么我会错误地继续输入不必要的输入(在这种情况下是 word_matrix[0])。

所以,我想知道 0 填充的正确方法是什么。如果您让我知道如何使用 tensorflow 实现它,那就太好了。

  1. dynamic_rnn 为此,我声明了一个包含所有句子长度的列表,并在末尾加上 X 和 y。在这种情况下,我不能将输入作为批次提供。然后,我遇到了这个错误(ValueError: as_list() is not defined on an unknown TensorShape.),在我看来,sequence_length 参数只接受列表? (不过我的想法可能完全不正确)。

以下是我的代码。

X = tf.placeholder(tf.int32)
labels = tf.placeholder(tf.int32, [None, numClasses])
length = tf.placeholder(tf.int32)

data = tf.placeholder(tf.float32, [None, None, numDimensions])
data = tf.nn.embedding_lookup(word_matrix, X)

lstmCell = tf.contrib.rnn.BasicLSTMCell(lstmUnits, state_is_tuple=True)
lstmCell = tf.contrib.rnn.DropoutWrapper(cell=lstmCell, output_keep_prob=0.25)
initial_state=lstmCell.zero_state(batchSize, tf.float32)
value, _ = tf.nn.dynamic_rnn(lstmCell, data, sequence_length=length,
                             initial_state=initial_state, dtype=tf.float32)

我在这部分非常挣扎,因此非常感谢任何帮助。

提前谢谢你。

【问题讨论】:

    标签: python tensorflow lstm word2vec


    【解决方案1】:

    Tensorflow 不支持变长张量。所以当你声明一个 Tensor 时,list/numpy 数组应该有一个统一的形状。

    1. 从您的第一部分开始,我了解到您已经能够在序列长度的最后一个时间步中填充零。理想的情况应该是这样的。下面是它应该如何查找批量大小为 4、ma​​x 序列长度为 10 和 50 个隐藏单元 ->

      [4,10,50] 将是整个批次的大小,但在内部,当您尝试可视化填充时,它可能是这样的形状 ->

      `[[5+5pad,50],[10,50],[8+2pad,50],[9+1pad,50]`
      

      每个 pad 代表一个长度为 1 的序列,隐藏状态大小为 50 张量。一切都充满了零。查看this questionthis one 了解更多关于如何手动填充的信息。

    2. 您将使用动态 rnn 的确切原因是您不想在填充序列上计算它。 tf.nn.dynamic_rnn api 将通过传递 sequence_length 参数来确保这一点。

      对于上述示例,该参数将为:[5,10,8,9] 对于上述示例。您可以通过对每个批次组件的非零实体求和来计算它。一种简单的计算方法是:

      data_mask = tf.cast(data, tf.bool)
      data_len = tf.reduce_sum(tf.cast(data_mask, tf.int32), axis=1)
      

      并在tf.nn.dynamic_rnn api 中传递它:

      tf.nn.dynamic_rnn(lstmCell, data, sequence_length=data_len, initial_state=initial_state)
      

    【讨论】:

    • 感谢您的帮助!它澄清了许多问题,我正在尝试实施它。非常感谢您的回答!
    • @KimJay 很高兴知道这一点!如果您认为答案令人满意,请将其标记为已接受。
    猜你喜欢
    • 1970-01-01
    • 2021-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-10
    • 1970-01-01
    • 2016-11-06
    相关资源
    最近更新 更多