簡體   English   中英

恢復keras seq2seq模型

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM