我使用keras和tensorflow后端。
我有一个训练有素的LSTM模型,其隐藏状态向量我想在每个时间步长提取。
在keras中执行此操作的最佳方式是什么?
答案 0 :(得分:1)
处理是否返回所有隐藏状态向量的函数是Recurrent.call()
(在最新版本中它已重命名为RNN.call()
)。它会检查参数return_sequences
以做出决定。
在此函数中调用后端函数K.rnn()
时:
last_output, outputs, states = K.rnn(self.step,
preprocessed_input,
initial_state,
go_backwards=self.go_backwards,
mask=mask,
constants=constants,
unroll=self.unroll,
input_length=input_shape[1])
...
if self.return_sequences:
output = outputs
else:
output = last_output
张量outputs
就是你想要的。您可以通过再次调用Recurrent.call()
来获得此张量,但使用return_sequences=True
。这不会对您训练有素的LSTM模型造成任何伤害(至少在当前的Keras中)。
这是一个玩具Bi-LSTM模型,展示了这种方法:
input_tensor = Input(shape=(None,), dtype='int32')
embedding = Embedding(10, 100, mask_zero=True)(input_tensor)
hidden = Bidirectional(LSTM(10, return_sequences=True))(embedding)
hidden = Bidirectional(LSTM(10, return_sequences=True))(hidden)
hidden = Bidirectional(LSTM(2))(hidden)
out = Dense(1, activation='sigmoid')(hidden)
model = Model(input_tensor, out)
首先,为最后一个LSTM图层设置return_sequences
到True
(因为您使用的是Bidirectional
包装器,您必须设置forward_layer
和{{1}还):
backward_layer
现在通过再次调用此图层,将返回包含所有时间步骤中的隐藏向量的张量(将产生创建其他入站节点的副作用,但它不应影响预测)。
target_layer = model.layers[-2]
target_layer.return_sequences = True
target_layer.forward_layer.return_sequences = True
target_layer.backward_layer.return_sequences = True
您可以通过调用outputs = target_layer(target_layer.input)
m = Model(model.input, outputs)
来获取隐藏的向量。
m.predict(X_test)
如您所见,返回所有5个时间步的隐藏向量,并且最后2个步骤被正确屏蔽。