我在最后一个Dense层使用return_sequences=True
和TimeDistributed
包装器在Keras中训练了多对多序列模型:
model = Sequential()
model.add(Embedding(input_dim=vocab_size, output_dim=50))
model.add(LSTM(100, return_sequences=True))
model.add(TimeDistributed(Dense(vocab_size, activation='softmax')))
# train...
model.save_weights("weights.h5")
因此,在训练过程中(在每个时间戳记中)所有隐藏状态下的损失都将进行计算。但是为了推理,我只需要在最后一个时间戳上获取输出。因此,我将权重加载到多对一序列模型中以进行无TimeDistributed
包装的推理,并将return_sequences=False
设置为仅获取LSTM层的最后输出:
inference_model = Sequential()
inference_model.add(Embedding(input_dim=vocab_size, output_dim=50))
inference_model.add(LSTM(100, return_sequences=False))
inference_model.add(Dense(vocab_size, activation='softmax'))
inference_model.load_weights("weights.h5")
当我在长度为20的序列上测试推理模型时,我希望获得形状为(vocab_size)的预测,但是inference_model.predict(...)
仍会为每个时间戳返回预测-形状的张量(20,vocab_size)>
答案 0 :(得分:0)
如果出于某种原因,在推理过程中您只需要最后一个时间步长,则可以构建一个新模型,该模型将经过训练的模型应用于输入,并使用Lambda
层将最后一个时间步长作为其输出返回: / p>
from keras.models import Model
from keras.layers import Input, Lambda
inp = Input(shape=put_the_input_shape_here)
x = model(inp) # apply trained model on the input
out = Lambda(lambda x: x[:,-1])(x)
inference_model = Model(inp, out)
侧面说明:如this answer中所述,TimeDistributed(Dense(...))
和Dense(...)
是等效的,因为Dense
层应用于最后一个尺寸输入张量。因此,这就是为什么您获得相同的输出形状。