[英]Restore keras seq2seq model
我在這里使用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)
我想翻譯此代碼,以確定從磁盤加載的模型中的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)
但是,當我嘗試構建解碼器模型時,遇到此錯誤:
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: []
作為測試,我嘗試了具有相同結果的Model(decoder_inputs,decoder_outputs)。 我不清楚與圖表有什么聯系,因為這些層是從模型中加載的。
好的,我解決了這個問題,解碼器產生了合理的結果。 在上面的代碼中,我錯過了解碼器步驟中的幾個細節,特別是它call()s
LSTM和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)
該代碼的一個很大的缺點是我們事先了解完整的架構。 我希望最終能夠加載與體系結構無關的解碼器。
在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')
稍后加載編碼器和解碼器:
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')
在預測期間,您還將需要許多其他數據,例如,編碼器/解碼器令牌的數量,將char映射到索引的字典等。您可以在訓練后將它們保存到文件中,然后像模型一樣加載它們。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.