本文主要是利用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