【问题标题】:keras LSTM get hidden-state (converting sentece-sequence to document context vectors)keras LSTM 获得隐藏状态(将句子序列转换为文档上下文向量)
【发布时间】:2019-12-27 09:11:36
【问题描述】:

我正在尝试使用 keras 通过 LSTM 从句子向量创建文档上下文向量(因此每个文档都包含一系列句子向量)。

我的目标是使用 keras 复制以下博客文章:https://andriymulyar.com/blog/bert-document-classification

我有一个(玩具)张量,看起来像这样:X = np.array(features).reshape(5, 200, 768) 所以 5 个文档,每个文档有 200 个句子向量序列 - 每个句子向量有 768 个特征。

所以为了从我的句子向量中获得嵌入,我将我的文档编码为 one-hot-vectors 来学习 LSTM:

y = [1,2,3,4,5] # 5 documents in toy-tensor
y = np.array(y)
yy = to_categorical(y)
yy = yy[0:5,1:6]

到目前为止,我的代码是这样的

inputs1=Input(shape=(200,768))
lstm1, states_h, states_c =LSTM(5,dropout=0.3,recurrent_dropout=0.2, return_state=True)(inputs1)
model1=Model(inputs1,lstm1)
model1.compile(loss='categorical_crossentropy',optimizer='rmsprop',metrics=['acc']) 
model1.summary()
model1.fit(x=X,y=yy,batch_size=100,epochs=10,verbose=1,shuffle=True,validation_split=0.2)

当我打印 states_h 时,我得到一个 shape=(?,5) 的张量,但我真的不知道如何访问该张量中的向量,这应该代表我的文档。

print(states_h)
Tensor("lstm_51/while/Exit_3:0", shape=(?, 5), dtype=float32)

还是我做错了什么?据我了解,应该有 5 个文档向量,例如doc1=[...] ; ...; doc5=[...] 这样我就可以将文档向量重用于分类任务。

【问题讨论】:

  • 您使用的是哪个 TF 版本?您使用的是keras 还是tf.keras

标签: python keras lstm embedding bert-language-model


【解决方案1】:

嗯,打印一个张量正好表明了这一点:它是一个张量,它有那个形状和那个类型。

如果您想查看数据,则需要提供数据。
状态不是权重,它们不是持久的,它们只存在于输入数据中,就像任何其他模型输出一样。

您应该创建一个输出此信息的模型(您的没有)以便获取它。你可以有两个模型:

#this is the model you compile and train - exactly as you are already doing
training_model = Model(inputs1,lstm1)     

#this is just for getting the states, nothing else, don't compile, don't train
state_getting_model = Model(inputs1, [lstm1, states_h, states_c]) 

(别担心,这两个模型会共享相同的权重并一起更新,即使你只训练training_model

现在你可以:

关闭急切模式(也可能“开启”):

lstm_out, states_h_out, states_c_out = state_getting_model.predict(X)
print(states_h_out)
print(states_c_out)

开启急切模式:

lstm_out, states_h_out, states_c_out = state_getting_model(X)
print(states_h_out.numpy())
print(states_c_out.numpy())

【讨论】:

  • 好的,我对 keras 还太陌生,无法完全理解:我确实设置了我的 inputs1lstm1, states_h, states_c,然后使用 training_modelstate_getting_model 来设置我的Model()?然后我运行training_model.compile().fit() 来训练我的模型,它也会训练state_getting_model?这不可能是正确的..如果我在 state_getting_model Error when checking model target: the list of Numpy arrays that you are passing to your model is not the size the model expected 上运行 .compile()fit() 会收到错误消息
  • @Felix ,您不必训练或编译 state_getting_model。你只需要训练和编译training_model
  • training_modelstate_getting_model 是两个不同的模型,但它们共享所有层和权重。 training_model 仅输出您要训练的数据。 state_getting_model 输出数据和状态。
  • state_getting_model 怎么可能共享相同的权重,即使它没有编译并适合数据?是不是因为 Keras Model() 迭代运行并更新,所以 Model() 本身会适应输入/输出数据?嗯..我可能需要更深入地研究 keras:-/
  • 因为它使用完全相同的层。而training_model 从输入张量inputs1 出发,经过所有层,直到输出张量lstm1;模型state_getting_model 遵循几乎完全相同的路径(自然是相同的层),从输入张量inputs1 到输出张量lstm1,但包括两个额外的输出张量states_hstates_c(它来自与输出张量lstm1 相同的层)。因此,您所做的只是创建两个使用完全相同的层的模型(或函数)。
【解决方案2】:

带有tf.keras 的TF 1.x(使用TF 1.15 测试)

Keras 使用符号张量进行运算。因此,print(states_h) 不会给您任何东西,除非您将数据传递给占位符 states_h 取决于(在本例中为 inputs1)。你可以这样做。

import tensorflow.keras.backend as K

inputs1=Input(shape=(200,768))
lstm1, states_h, states_c =LSTM(5,dropout=0.3,recurrent_dropout=0.2, return_state=True)(inputs1)
model1=Model(inputs1,lstm1)
model1.compile(loss='categorical_crossentropy',optimizer='rmsprop',metrics=['acc']) 
model1.summary()
model1.fit(x=X,y=yy,batch_size=100,epochs=10,verbose=1,shuffle=True,validation_split=0.2)

sess = K.get_session()
out = sess.run(states_h, feed_dict={inputs1:X})

那么out 将是(batch_size, 5) 大小的输出。

TF 2.x 与 tf.keras

上面的代码不能按原样工作。而且我还没有找到如何让它与 TF 2.0 一起工作(即使 TF 2.0 仍会根据docs 生成一个占位符)。当我找到如何为 TF 2.x 解决此问题时,我将编辑我的答案。

【讨论】:

  • 真的很抱歉,但我不明白如何在我的代码中包含get_session()。如果我运行sess.run(...),我会得到FailedPreconditionError: Attempting to use uninitialized value lstm_57/bias...,你能再解释一下吗?跨度>
  • @Felix 为了在这种情况下使用 sess.run(...),您首先需要运行 model.compile()model.fit()。你试过没有这些就跑吗?因为这是您会收到上述错误的一种情况。
  • 嗯,这似乎是一个路径错误FailedPreconditionError: Attempting to use uninitialized value lstm_59/kernel [[node lstm_59/kernel/read (defined at C:\Users\anaconda3\lib\site-packages\keras\backend\tensorflow_backend.py:402) ]],当我运行上述所有内容时我仍然得到它。我想我必须检查我的路径
猜你喜欢
  • 1970-01-01
  • 2018-06-29
  • 2015-08-28
  • 2019-03-15
  • 1970-01-01
  • 1970-01-01
  • 2018-09-21
  • 2018-10-07
  • 1970-01-01
相关资源
最近更新 更多