Keras双向LSTM - 层分组

时间:2018-04-16 10:45:49

标签: python deep-learning keras lstm

在使用Keras努力实现论文(使用带CRF的分层编码器的对话法序列标签)时,我需要实现特定的双向LSTM架构。

我必须根据对话的概念训练网络。对话由话语组成,话语由单词组成。单词是N维向量。本文中表示的模型首先将每个话语减少为单个M维向量。为此,它使用双向LSTM层。我们将此图层称为 A

(为简单起见,我们假设每个话语的长度为|U|,每个对话的长度为|C|

每个话语输入到具有U个时间步长的Bi-LSTM层,并且获取最后一个时间步的输出。输入大小为(|U|, N),输出大小为(1, M)

此Bi-LSTM图层应单独/同时应用于对话中的每个话语。请注意,由于网络将整个对话作为输入,因此网络的单个输入的维度将为(|C|, |U|, N)

正如论文所描述的那样,我打算为该输入提供每个话语(即每个(|U|, N))并将其提供给具有|U|个单位的Bi-LSTM层。因为有| C |对话中的话语,这意味着应该有总共|C| x |U|个Bi-LSTM单位,为每个话语分组为|C|个不同的分区。 |C|个单位组之间应该没有联系。处理后,每个C组双向LSTM单元的输出将被输入另一个Bi-LSTM层,例如 B

如何仅将输入的特定部分输入到 A 层的特定部分,并确保它们不互连? (即,用于话语的Bi-LSTM单位部分不应连接到用于另一个话语的Bi-LSTM单位)

是否可以通过keras.models.Sequential实现这一目标,或者是否有使用Functional API实现此目的的特定方法?

这是我到目前为止所尝试的内容:

# ...
model = Sequential()
model.add(Bidirectional(LSTM(C * U), input_shape = (C, U, N),
                        merge_mode='concat'))
model.add(GlobalMaxPooling1D())
model.add(Bidirectional(LSTM(n, return_sequences = True), merge_mode='concat'))
# ...

model.compile(loss = loss_function,
              optimizer = optimizer,
              metrics=['accuracy'])

但是,此代码目前收到以下错误:

  

ValueError:输入0与图层bidirectional_1不兼容:预期ndim = 3,找到ndim = 4

更重要的是,上面的代码显然没有进行我提到的分组。我正在寻找一种方法来增强模型,如上所述。

最后,下面是我上面描述的模型的图。它可能有助于澄清上面叙述的一些书面内容。该层标记为"话语层"就是我称之为 A 的图层。正如您在图中所看到的,图中的每个话语u_i都由单词w_j组成,这些单词是N维向量。 (出于此问题的目的,您可以省略嵌入层)为简单起见,假设每个u_i具有相同数量的字,那么话语层中的每个双向LSTM节点输入大小为(|U|, N)。但是,由于对话中有|C|个这样的话语u_i,整个输入的维度将为(|C|, |U|, N)

Bi-LSTM Model diagram

1 个答案:

答案 0 :(得分:1)

我会为照片中的内容创建一个网络。现在我忽略了"单位"我在对你的问题的评论中提到的部分。

此模型完全符合图片中所示的内容。所有的话语都是从头到尾完全分开的。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    expand-text="yes"
    version="3.0">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="yyy">
      <xsl:merge>
          <xsl:merge-source select="list/desc">
              <xsl:merge-key select="@id"/>
          </xsl:merge-source>
          <xsl:merge-source select="rec/val">
              <xsl:merge-key select="@id"/>
          </xsl:merge-source>
          <xsl:merge-action>
              <strow>
                  <stentry>{current-merge-group()[1]/@name}</stentry>
                  <stentry>{current-merge-group()[2]}</stentry>
              </strow>
          </xsl:merge-action>
      </xsl:merge>
  </xsl:template>

</xsl:stylesheet>

请注意,在每个双向层中,我将输出大小除以2,因此model = Sequential() #You have an extra time dimension that should be kept as is #So we add a TimeDistributed` wrapper to the first layers model.add(TimeDistributed(Embedding(dictionaryLength,N), input_shape=(C,U))) #This is the utterance layer. It works in "word steps", keeping "utterance steps" untouched model.add(TimeDistributed(Bidirectional(LSTM(M//2, return_sequences=False)))) #Is the pooling really demanded by the article? #Or was it an attempt to remove one of the time dimensions? #Not adding it here because I used `return_sequences=False` model.add(Bidirectional(LSTM(someSize//2,return_sequences=True))) model.add(Dense(anotherSize)) #is this a CRF layer??? model.summary() M是偶数非常重要。