2

我正在尝试使用 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=[...],以便我可以将文档向量重用于分类任务。

4

2 回答 2

3

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

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

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

#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())
于 2020-01-02T12:50:00.457 回答
1

TF 1.x with tf.keras(使用 TF 1.15 测试)

Keras 使用符号张量进行操作。因此,除非您将数据传递给占位符取决于(在这种情况下) ,print(states_h)否则不会给您任何东西。您可以按如下方式进行。states_hinputs1

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 解决此问题时,我将编辑我的答案。

于 2019-12-30T23:17:27.803 回答