本文主要是利用keras框架記錄簡單實現seq2seq模型的過程,seq2seq的應用主要有問答系統、人機對話、機器翻譯等。
seq2seq模型介紹
seq2seq模型主要有兩個部分Encoder和Decoder,Encoder負責將輸入編碼,Decoder負責解碼輸出。最簡單的seq2seq模型圖:
Keras實現seq2seq模型
Encoder部分
encoder部分就是一個標準的RNN/LSTM模型,取最後時刻的隱藏層作爲輸出。這裏是用tensorflow中自帶的keras,用原始的keras也可以。
先導入keras的常用包:
from tensorflow.keras import backend as K
from tensorflow.keras import activations
from tensorflow.keras.layers import Layer, Input, Embedding, LSTM, Dense
from tensorflow.keras.models import Model, load_model
encoder部分結構,主要就是一個Embedding,加上LSTM層。
def Encoder(maxlen, embedding_dim, hidden_units):
"""
define encoder model
"""
# Input Layer
encoder_inputs = Input(shape=(maxlen,), name="encode_input")
# Embedding Layer
encoder_embed = Embedding(vocab_size, embedding_dim)(encoder_inputs)
# Encode LSTM Layer
encoder_lstm = LSTM(hidden_units, return_state=True, name="encode_lstm")
encoder_outputs, state_h, state_c = encoder_lstm(encoder_embed)
encoder_states = [state_h, state_c]
# Model
encoder_model = Model(inputs=encoder_inputs, outputs=encoder_states, name="encoder_model")
return encoder_model
Decoder部分
decoder部分結構,有兩部分輸入,一個是encoder的隱藏狀態輸出,另一個是decoder的目標輸入。
def Decoder(embedding_dim, hidden_units, vocab_size):
"""
define decoder model
"""
# Input Layer
decoder_inputs = Input(shape=(maxlen,), name="decode_input")
state_input_h = Input(shape=(hidden_units,))
state_input_c = Input(shape=(hidden_units,))
decoder_states_inputs = [state_input_h, state_input_c]
# Embedding Layer
decoder_embed = Embedding(vocab_size, embedding_dim)(decoder_inputs)
# Decode LSTM Layer
decoder_lstm = LSTM(hidden_units, return_sequences=True, return_state=True, name="decode_lstm")
decoder_outputs, state_h, state_c = decoder_lstm(decoder_embed, initial_state=decoder_states_inputs)
decoder_states = [state_h, state_c]
# Dense Layer
decoder_dense = Dense(vocab_size, activation='softmax', name="dense")
dense_outputs = decoder_dense(decoder_outputs)
# Model
decoder_model = Model(inputs=[decoder_inputs] + decoder_states_inputs,
outputs=[dense_outputs] + decoder_states,
name="decoder_model")
return decoder_model
Encoder和Decoder合併
encoder和decoder合併,組成一個完整的seq2seq模型。
def Seq2Seq(maxlen, embedding_dim, hidden_units, vocab_size):
"""
define seq2seq model
"""
# Input Layer
encoder_inputs = Input(shape=(maxlen,), name="encode_input")
decoder_inputs = Input(shape=(maxlen,), name="decode_input")
# Encoder Layer
encoder = Encoder(maxlen, embedding_dim, hidden_units)
encoder_state_h, encoder_state_c = encoder(encoder_inputs)
# Decoder Layer
decoder = Decoder(embedding_dim, hidden_units, vocab_size)
decoder_outputs, state_h, state_c = decoder([decoder_inputs, encoder_state_h, encoder_state_c])
# seq2seq model
model = Model(inputs=[encoder_inputs, decoder_inputs], outputs=decoder_outputs)
return model
模型詳細結構
我們自定義一些參數,看看seq2seq整個模型結構。
maxlen = 10
embedding_dim = 50
hidden_units = 128
vocab_size = 10000
model = Seq2Seq(maxlen, embedding_dim, hidden_units, vocab_size)
model.summary()
seq2seq的層結構和參數,由於上面我們把encoder和decoder都封裝在一起,所以這裏看起來只有一個層,當然也可以展開的。
從上面seq2seq模型中獲取Encoder子模型:
encoder_model = Model(inputs=model.get_layer('encoder_model').input,
outputs=model.get_layer('encoder_model').output)
encoder_model.summary()
Encoder內部的層結構和參數:
從上面seq2seq模型中獲取Decoder子模型:
decoder_model = Model(inputs=model.get_layer('decoder_model').input,
outputs=model.get_layer('decoder_model').output)
decoder_model.summary()
Decoder內部的層結構和參數:
seq2seq模型訓練
後面會完善一個具體如何訓練的例子,未完待續。。。
參考文檔:
[1]. https://machinelearningmastery.com/develop-encoder-decoder-model-sequence-sequence-prediction-keras/
[2]. https://www.tensorflow.org/guide/keras/functional