首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Keras: BiLSTM只在return_sequences=True工作时才能工作

Keras: BiLSTM只在return_sequences=True工作时才能工作
EN

Stack Overflow用户
提问于 2019-04-15 09:08:54
回答 2查看 718关注 0票数 0

我一直试图在Keras中实现这个BiLSTM:https://github.com/ffancellu/NegNN

这就是我所在的地方,它的作用是:

代码语言:javascript
运行
复制
inputs_w = Input(shape=(sequence_length,), dtype='int32')
inputs_pos = Input(shape=(sequence_length,), dtype='int32')
inputs_cue = Input(shape=(sequence_length,), dtype='int32')

w_emb = Embedding(vocabulary_size+1, embedding_dim, input_length=sequence_length, trainable=False)(inputs_w)
p_emb = Embedding(tag_voc_size+1, embedding_dim, input_length=sequence_length, trainable=False)(inputs_pos)
c_emb = Embedding(2, embedding_dim, input_length=sequence_length, trainable=False)(inputs_cue)

summed = keras.layers.add([w_emb, p_emb, c_emb])

BiLSTM = Bidirectional(CuDNNLSTM(hidden_dims, return_sequences=True))(summed)

DPT = Dropout(0.2)(BiLSTM)

outputs = Dense(2, activation='softmax')(DPT)

checkpoint = ModelCheckpoint('bilstm_one_hot.hdf5', monitor='val_loss', verbose=1, save_best_only=True, mode='auto')
early = EarlyStopping(monitor='val_loss', min_delta=0.0001, patience=5, verbose=1, mode='auto')

model = Model(inputs=[inputs_w, inputs_pos, inputs_cue], outputs=outputs)

model.compile('adam', loss='categorical_crossentropy', metrics=['accuracy'])

model.summary()

model.fit([X_train, X_pos_train, X_cues_train], Y_train, batch_size=batch_size, epochs=num_epochs, verbose=1, validation_split=0.2, callbacks=[early, checkpoint])

在原代码中,在Tensorflow中,作者使用了带logits的掩蔽和softmax交叉熵。我还不知道如何在Keras中实现这一点。如果你有任何建议,不要犹豫。

我这里的主要问题是关于return_sequences=True的。作者似乎并没有在他的tensorflow实现中使用它,当我将它转换为False时,我得到了以下错误:

代码语言:javascript
运行
复制
ValueError: Error when checking target: expected dense_1 to have 2 dimensions, but got array with shape (820, 109, 2)

我还试着使用:

代码语言:javascript
运行
复制
outputs = TimeDistributed(Dense(2, activation='softmax'))(BiLSTM)

返回和不提供任何信息的AssertionError。

有什么想法吗?

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-04-15 10:27:14

作者使用掩蔽和软最大交叉熵与逻辑。我还不知道如何在Keras中实现这一点。

对于具有logits的softmax交叉熵,您是正确的。softmax_cross_entropy_with_logits作为损失函数+最后一层上没有激活函数,与您在最后一层上使用categorical_crossentropy作为损失+ softmax激活的方法相同。唯一的区别是后者在数值上不太稳定。如果这对您来说是个问题,您可以(如果您的Keras后端是tensorflow)传递tf.softmax_cross_entropy_with_logits作为您的损失。如果您有另一个后端,您将不得不在那里寻找一个等价的。

关于掩蔽,我不确定我是否完全明白作者在做什么。但是,在Keras中,Embedding层有一个可以设置为Truemask_zero参数。在这种情况下,所有具有0的时间步骤都将在所有进一步的计算中被忽略。但是,在您的源代码中,被蒙蔽的不是0,因此您必须相应地调整索引。如果这样做不起作用,那么您可以将Masking层放在您的递归层之前,但是我对此几乎没有经验。

我这里的主要问题是关于return_sequences=True的。作者似乎并没有使用它

你凭什么认为他不使用它?仅仅因为这个关键字没有出现在代码中,并不意味着什么。但我也不确定。代码非常老,我在文档中找不到它,它可以判断默认值是什么。

无论如何,如果您想使用return_sequences=False (无论出于什么原因),请注意这会改变层的输出形状:

  • 对于return_sequences=True,输出形状为(batch_size, timesteps, features)
  • 对于return_sequences=False,输出形状为(batch_size, features)

您所得到的错误基本上是告诉您,您的网络输出的一维小于您要输入的目标y值。因此,在我看来,return_sequences=True似乎正是您所需要的,但是如果没有更多的信息,就很难判断。

然后,关于TimeDistributed。我不太清楚你想用它实现什么,但引用了文档中的话:

此包装器将一个层应用于输入的每个时态切片。 输入应至少为三维,索引1的维数应视为时间维。

(重点是我的)

我不能从您的问题中确定,在哪种情况下会出现空断言。

如果您以前有一个带有return_sequences=False的递归层,那么您将再次缺少一个维度(不过,我不能告诉您为什么断言是空的)。

如果您以前有一个带有return_sequences=True的递归层,它应该可以工作,但是它是完全无用的,因为Dense是以一种时间分布式的方式应用的。如果我没有弄错的话,Dense层的这种行为在一些较旧的Keras版本中发生了改变(他们应该在那里更新示例,停止使用Dense!)。由于您所指的代码已经相当陈旧,很有可能那时需要TimeDistributed,但不再需要了。

如果您的计划是恢复缺少的维度,TimeDistributed不会帮助您,但是RepeatVector会帮助您。但是,如前所述,在这种情况下,最好首先使用return_sequences=True

票数 1
EN

Stack Overflow用户

发布于 2019-04-15 09:17:00

问题是目标值似乎是时间分布的。所以你有109个时间步骤,有一个大小为2的热目标向量。这就是你需要return_sequences=True的原因。否则,您将只需将最后一个时间步骤提供给密集层,您将只有一个输出。

因此,取决于您需要什么,您需要保持它现在的样子,或者如果仅仅是最后一个时间步骤就足够了,您可以摆脱它,但是您需要相应地调整y值。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55685867

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档