自然语言处理入门(四)--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

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