Rob*_*Sim 2 python machine-learning keras tensorflow
我在这里使用keras seq2seq示例:https : //github.com/keras-team/keras/blob/master/examples/lstm_seq2seq.py
我希望保留词汇表和解码器,以便以后可以再次加载它并将其应用于新序列。
尽管代码调用了model.save(),但这还不够,因为我可以看到解码设置引用了许多其他变量,这些变量是已训练模型的深层指针:
encoder_model = Model(encoder_inputs, encoder_states)
decoder_state_input_h = Input(shape=(latent_dim,))
decoder_state_input_c = Input(shape=(latent_dim,))
decoder_states_inputs = [decoder_state_input_h, decoder_state_input_c]
decoder_outputs, state_h, state_c = decoder_lstm(
decoder_inputs, initial_state=decoder_states_inputs)
decoder_states = [state_h, state_c]
decoder_outputs = decoder_dense(decoder_outputs)
decoder_model = Model(
[decoder_inputs] + decoder_states_inputs,
[decoder_outputs] + decoder_states)
Run Code Online (Sandbox Code Playgroud)
我想翻译此代码,以确定从磁盘加载的模型中的encoder_inputs,encoder_states,latent_dim,decoder_inputs。可以假设我事先知道模型架构是可以的。有没有简单的方法可以做到这一点?
更新:我在使用解码器构造代码并根据需要提取层输入/输出方面取得了一些进展。
encoder_inputs = model.input[0] #input_1
decoder_inputs = model.input[1] #input_2
encoder_outputs, state_h_enc, state_c_enc = model.layers[2].output # lstm_1
_, state_h_dec, state_c_dec = model.layers[3].output # lstm_2
decoder_outputs = model.layers[4].output # dense_1
encoder_states = [state_h_enc, state_c_enc]
encoder_model = Model(encoder_inputs, encoder_states)
latent_dim = 256 # TODO: infer this from the model. Should match lstm_1 outputs.
decoder_state_input_h = Input(shape=(latent_dim,))
decoder_state_input_c = Input(shape=(latent_dim,))
decoder_states_inputs = [decoder_state_input_h, decoder_state_input_c]
decoder_states = [state_h_dec, state_c_dec]
decoder_model = Model(
[decoder_inputs] + decoder_states_inputs,
[decoder_outputs] + decoder_states)
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试构建解码器模型时,遇到此错误:
RuntimeError: Graph disconnected: cannot obtain value for tensor Tensor("input_1:0", shape=(?, ?, 96), dtype=float32) at layer "input_1". The following previous layers were accessed without issue: []
Run Code Online (Sandbox Code Playgroud)
作为测试,我尝试了具有相同结果的Model(decoder_inputs,decoder_outputs)。我不清楚与图表有什么联系,因为这些层是从模型中加载的。
好的,我解决了这个问题,解码器产生了合理的结果。在上面的代码中,我错过了解码器步骤中的几个细节,特别是call()sLSTM和Dense层以便将它们连接起来。另外,新的解码器输入需要唯一的名称,因此它们不会与input_1和input_2冲突(此细节闻起来像是keras的错误)。
encoder_inputs = model.input[0] #input_1
encoder_outputs, state_h_enc, state_c_enc = model.layers[2].output # lstm_1
encoder_states = [state_h_enc, state_c_enc]
encoder_model = Model(encoder_inputs, encoder_states)
decoder_inputs = model.input[1] #input_2
decoder_state_input_h = Input(shape=(latent_dim,),name='input_3')
decoder_state_input_c = Input(shape=(latent_dim,),name='input_4')
decoder_states_inputs = [decoder_state_input_h, decoder_state_input_c]
decoder_lstm = model.layers[3]
decoder_outputs, state_h_dec, state_c_dec = decoder_lstm(
decoder_inputs, initial_state=decoder_states_inputs)
decoder_states = [state_h_dec, state_c_dec]
decoder_dense = model.layers[4]
decoder_outputs=decoder_dense(decoder_outputs)
decoder_model = Model(
[decoder_inputs] + decoder_states_inputs,
[decoder_outputs] + decoder_states)
Run Code Online (Sandbox Code Playgroud)
该代码的一个很大的缺点是我们事先了解完整的架构。我希望最终能够加载与体系结构无关的解码器。
在 Keras seq2seq 示例的代码中的某个时刻,您将拥有一个完成的编码器和解码器模型。您可以将这些模型的架构和权重保存到磁盘并稍后加载。以下对我有用:
将模型保存到磁盘:
with open('encoder_model.json', 'w', encoding='utf8') as f:
f.write(encoder_model.to_json())
encoder_model.save_weights('encoder_model_weights.h5')
with open('decoder_model.json', 'w', encoding='utf8') as f:
f.write(decoder_model.to_json())
decoder_model.save_weights('decoder_model_weights.h5')
Run Code Online (Sandbox Code Playgroud)
稍后加载编码器和解码器:
def load_model(model_filename, model_weights_filename):
with open(model_filename, 'r', encoding='utf8') as f:
model = model_from_json(f.read())
model.load_weights(model_weights_filename)
return model
encoder = load_model('encoder_model.json', 'encoder_model_weights.h5')
decoder = load_model('decoder_model.json', 'decoder_model_weights.h5')
Run Code Online (Sandbox Code Playgroud)
在预测过程中,您还需要许多其他数据,例如编码器/解码器标记的数量、将字符映射到索引的字典等。您可以在训练后将这些数据保存到文件中,然后再加载它们,就像模型一样。