Keras seq2seq堆叠层

Keras seq2seq堆叠层,keras,seq2seq,multi-layer,Keras,Seq2seq,Multi Layer,在教程中:我们有一层seq2seq模型。我想扩展这个模型,在编码器端增加一层,在解码器端增加一层。培训似乎是工作,但我不能得到解码器在推理设置正确的多层。下面是我对教程中提到的模型所做的更改 编码器: encoder_inputs = Input(shape=(None, num_encoder_tokens)) encoder1 = LSTM( latent_dim, return_sequences=True ) encoder2 = LSTM( latent_dim, re

在教程中:我们有一层seq2seq模型。我想扩展这个模型,在编码器端增加一层,在解码器端增加一层。培训似乎是工作,但我不能得到解码器在推理设置正确的多层。下面是我对教程中提到的模型所做的更改

编码器:

encoder_inputs = Input(shape=(None, num_encoder_tokens))
encoder1 = LSTM(
  latent_dim,
  return_sequences=True
)
encoder2 = LSTM(
  latent_dim,
  return_state=True,
)
x=encoder1(encoder_inputs)
encoder_outputs, state_h, state_c = encoder2(x)
解码器:

encoder_states = [state_h, state_c]

# Set up the decoder, using `encoder_states` as initial state.
decoder_inputs = Input(shape=(None, num_decoder_tokens))
# We set up our decoder to return full output sequences,
# and to return internal states as well. We don't use the
# return states in the training model, but we will use them in inference.

decoder1 = LSTM(
  latent_dim,
  return_sequences=True
)
decoder2 = LSTM(
  latent_dim,
  return_sequences=True, return_state=True
)

dx = decoder1(decoder_inputs, initial_state=encoder_states)


decoder_outputs, _, _ = decoder2(dx)
decoder_dense = Dense(num_decoder_tokens, activation='softmax')
decoder_outputs = decoder_dense(decoder_outputs)

# decoder_lstm = LSTM(latent_dim, return_sequences=True, return_state=True)
# Define the model that will turn
# `encoder_input_data` & `decoder_input_data` into `decoder_target_data`
model = Model([encoder_inputs, decoder_inputs], decoder_outputs)
推断(这是我不知道如何创建多层解码器的部分)当前不起作用的实现如下所示:

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]

out_decoder1 = LSTM(
  latent_dim,
  return_sequences=True, return_state=True
)
out_decoder2 = LSTM(
  latent_dim,
  return_sequences=True, return_state=True
)

odx = out_decoder1(decoder_inputs, initial_state=decoder_states_inputs)

decoder_lstm = LSTM(latent_dim, return_sequences=True, return_state=True)
decoder_outputs, state_h, state_c = out_decoder2(odx)
#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)

# Reverse-lookup token index to decode sequences back to
# something readable.
reverse_input_char_index = dict(
    (i, char) for char, i in input_token_index.items())
reverse_target_char_index = dict(
    (i, char) for char, i in target_token_index.items())


def decode_sequence(input_seq):
    # Encode the input as state vectors.
    states_value = encoder_model.predict(input_seq)
    # Generate empty target sequence of length 1.
    target_seq = np.zeros((1, 1, num_decoder_tokens))
    # Populate the first character of target sequence with the start character.
    target_seq[0, 0, target_token_index['\t']] = 1.

    # Sampling loop for a batch of sequences
    # (to simplify, here we assume a batch of size 1).
    stop_condition = False
    decoded_sentence = ''
    while not stop_condition:
        output_tokens, h, c = decoder_model.predict(
            [target_seq] + states_value)

        # Sample a token
        sampled_token_index = np.argmax(output_tokens[0, -1, :])
        print(output_tokens)
        print(sampled_token_index)
        sampled_char = reverse_target_char_index[sampled_token_index]
        decoded_sentence += sampled_char

        # Exit condition: either hit max length
        # or find stop character.
        if (sampled_char == '\n' or
           len(decoded_sentence) > max_decoder_seq_length):
            stop_condition = True

        # Update the target sequence (of length 1).
        target_seq = np.zeros((1, 1, num_decoder_tokens))
        target_seq[0, 0, sampled_token_index] = 1.

        # Update states
        states_value = [h, c]

    return decoded_sentence


for seq_index in range(1):
    # Take one sequence (part of the training set)
    # for trying out decoding.
    input_seq = encoder_input_data[seq_index: seq_index + 1]
    decoded_sentence = decode_sequence(input_seq)
    print('-')
    print('Input sentence:', input_texts[seq_index])
    print('Decoded sentence:', decoded_sentence)

Thnx

我做了一些更改,它似乎工作得很好

培训模式: 定义输入序列并对其进行处理。 编码器输入=输入(形状=(无,编码器标记数)) 编码器=LSTM(潜在尺寸,返回状态=真,返回序列=真) 编码器2=LSTM(潜在尺寸,返回状态=True) 编码器输出,状态h,状态c=编码器R2(编码器(编码器输入)) #我们丢弃“编码器输出”,只保留状态。 编码器状态=[状态h,状态c] #设置解码器,使用“编码器状态”作为初始状态。 解码器\u输入=输入(形状=(无,num\u解码器\u标记)) #我们将解码器设置为返回完整的输出序列, #以及返回内部状态。我们不使用 #在训练模型中返回状态,但我们将在推理中使用它们。 解码器=LSTM(潜在尺寸,返回序列=True,返回状态=True) decoder2=LSTM(潜在尺寸,返回序列=True,返回状态=True) 解码器输出,解码器2(解码器(解码器输入,初始状态=编码器状态)) 解码器\u密集=密集(num\u解码器\u令牌,activation='softmax') 解码器输出=解码器输出(解码器输出) #定义要转换的模型 #“编码器输入数据”和“解码器输入数据”进入“解码器目标数据”` 模型=模型([编码器输入,解码器输入],解码器输出) 推断
#定义采样模型
编码器模型=模型(编码器输入、编码器状态)
解码器\状态\输入\ h=输入(形状=(潜在尺寸)
解码器\状态\输入\ c=输入(形状=(潜在尺寸)
解码器\状态\输入=[解码器\状态\输入\ h,解码器\状态\输入\ c]
解码器输出,状态h,状态c=解码器(
解码器输入,初始状态=解码器状态(输入)
解码器2输出,状态2,状态2=解码器2(解码器(解码器输入,初始状态=[状态h,状态c]))
解码器\状态=[状态\ h2,状态\ c2]
解码器输出=解码器密集(解码器2输出)
解码器\模型=模型(
[解码器输入]+解码器状态输入,
[解码器输出]+解码器状态)

看看这是否有效。

在同一问题上挣扎了几天之后,我发现以下是有效的方法:

使用多个LSTM层进行编码根本不是问题。 #这里我用了3个。注意旗帜。最后一段的顺序 #层不会返回,因为我们需要一个存储所有内容的向量,而不是一个时间序列。。。 编码器输入=输入(形状=(无,允许的字符数),名称='编码器输入') 编码器\u lstm1=LSTM(state\u size,name='encoder\u lstm1', 返回\序列=真,返回\状态=真) 编码器\u lstm2=LSTM(状态\u大小,名称='encoder\u lstm2', 返回\序列=真,返回\状态=真) 编码器\u lstm3=LSTM(状态\u大小,名称='encoder\u lstm3', return\u sequences=False,return\u state=True) #连接所有LSTM层。 x=编码器输入 x、 _u,u=编码器_lstm1(x) x、 _u,u=编码器_lstm2(x) #只关注最后一层的状态。 x、 状态h,状态c=编码器lstm3(x) 编码器_输出=x#这是编码的、固定大小的向量,seq2seq就是关于这个向量的 编码器状态=[状态h,状态c] 现在让我们看看解码(以及最困难的)位:

#这里有一些新东西:对于每一个解码层,我们需要一个输入变量,用于两个隐藏状态(h)
#细胞状态(c)。在这里,我将使用两个堆叠解码层,因此初始化h1、c1、h2、c2。
解码器\初始\状态\ h1=输入(形状=(状态\大小,),
name='decoder\u initial\u state\u h1')
解码器\初始\状态\ c1=输入(形状=(状态\大小,),
name='decoder\u initial\u state\u c1')
解码器\初始\状态\ h2=输入(形状=(状态\大小,),
name='decoder\u initial\u state\u h2')
解码器\初始\状态\ c2=输入(形状=(状态\大小,),
name='decoder\u initial\u state\u c2')
解码器输入=输入(形状=(无,允许的字符数),名称=解码器输入')
#注意return_序列和return_状态标志。
解码器\u lstm1=LSTM(state\u size,name='decoder\u lstm1',
返回\序列=真,返回\状态=真)
解码器\u lstm2=LSTM(状态\u大小,名称='decoder\u lstm2',
返回\序列=真,返回\状态=真)
解码器密度=密度(
允许的字符数,activation='softmax',name=“解码器输出”)
#连接解码器进行训练(初始状态=编码器状态)
#我将编码器_状态作为初始输入提供给两个解码lstm层
x=解码器输入
x、 h1,c1=解码器lstm1(x,初始状态=编码器状态)
#我试图将[h1,c1]作为下一行中的初始状态传递,但结果是垃圾
x、 _u,u=解码器_lstm2(x,初始状态=编码器状态)
解码器输出=解码器密度(x)
模型列车=模型(输入=[编码器输入,解码器输入],
输出=解码器(输出)
型号编码器=型号(输入=编码器输入,
输出=编码器(U状态)
这是解码器连接用于推理的部分。它与用于训练的解码器设置略有不同

#此解码器模型设置用于推断
#重要!每一层都保持自己的状态。这在解码_序列()中同样重要
x=解码器输入
x、 h1,c1=解码器lstm1(
x、 初始状态=[解码器初始状态\uH1,解码器初始状态\uC1])
x、 h2,c2=解码器lstm2(
x、 初始状态=[解码器初始状态\uH2,解码器初始状态\uC2])
解码器输出=解码器密度(x)
译码器