自然語言處理入門(四)--Keras簡單實現seq2seq模型

本文主要是利用keras框架記錄簡單實現seq2seq模型的過程,seq2seq的應用主要有問答系統、人機對話、機器翻譯等。

seq2seq模型介紹

seq2seq模型主要有兩個部分Encoder和Decoder,Encoder負責將輸入編碼,Decoder負責解碼輸出。最簡單的seq2seq模型圖:
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層結構圖
從上面seq2seq模型中獲取Encoder子模型:

encoder_model = Model(inputs=model.get_layer('encoder_model').input, 
                    outputs=model.get_layer('encoder_model').output)
encoder_model.summary()

Encoder內部的層結構和參數:
Encoder層結構圖
從上面seq2seq模型中獲取Decoder子模型:

decoder_model = Model(inputs=model.get_layer('decoder_model').input, 
                    outputs=model.get_layer('decoder_model').output)
decoder_model.summary()

Decoder內部的層結構和參數:
Encoder層結構圖

seq2seq模型訓練

後面會完善一個具體如何訓練的例子,未完待續。。。

參考文檔

[1]. https://machinelearningmastery.com/develop-encoder-decoder-model-sequence-sequence-prediction-keras/
[2]. https://www.tensorflow.org/guide/keras/functional

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章