【问题标题】:Provide Tensorflow Seq2Seq output as input at next step (inference)提供 Tensorflow Seq2Seq 输出作为下一步的输入(推理)
【发布时间】:2019-09-04 01:47:05
【问题描述】:

我想创建一个 Seq2Seq 模型来预测时间序列数据。我正在使用 InferenceHelper,我正在努力使用 sample_fn 参数。我想通过密集层传递每个单元的解码器输出,以便在每个时间步生成单个输出。所以我提供了一个对sample_fn 参数执行此操作的函数。

稍后我想将 rnn 单元输出与其他非时间序列特征连接起来,并在其上构建更密集的层。

网络在训练时表现良好,但在推理时表现不佳。我认为这是因为我在训练和推理时间之间没有共享相同的密集层。

我尝试设置重用参数并使用with tf.variable_scope() 环境。但是,sample_fn 已经在 dynamic_decode 的特定范围内调用,因此我无法使用与训练期间相同的范围。

我的代码的相关部分如下所示:

占位符:

inputs = tf.placeholder(shape=(None, 100, 1), dtype=tf.float32, name='inputs')
input_lengths = tf.placeholder(shape=(None,), dtype=tf.int32, name='input_lengths')

targets = tf.placeholder(shape=(None, 100), dtype=tf.float32, name='targets')
target_lengths = tf.placeholder(shape=(None,), dtype=tf.int32, name='target_lengths')

编码器:

encoder_cell = tf.nn.rnn_cell.MultiRNNCell([tf.contrib.rnn.GRUCell(num_units=16, name='encoder_cell_0'])
self.decoder_cell = tf.nn.rnn_cell.MultiRNNCell([tf.contrib.rnn.GRUCell(num_units=16, name='decoder_cell_0']))

_, final_encoder_states = tf.nn.dynamic_rnn(cell=encoder_cell, inputs=inputs,
                                                sequence_length=input_lengths, dtype=tf.float32)

解码器(训练)

start_tokens = tf.fill([tf.shape(inputs)[0]], start_token)
start_tokens = tf.cast(tf.expand_dims(start_tokens, 1), dtype=tf.float32)
targets_as_inputs = tf.concat([start_tokens, targets], axis=1)
targets_as_inputs = tf.reshape(targets_as_inputs, (-1, targets_as_inputs.shape[1], 1))

training_helper = tf.contrib.seq2seq.TrainingHelper(inputs=targets_as_inputs, sequence_length=target_lengths, name='training_helper')
training_decoder = tf.contrib.seq2seq.BasicDecoder(cell=decoder_cell, helper=training_helper, initial_state=final_encoder_states)

train_outputs, _, _ = tf.contrib.seq2seq.dynamic_decode(decoder=training_decoder, maximum_iterations=max_target_sequence_length, impute_finished=True)

train_predictions = train_outputs.rnn_output
train_predictions = tf.layers.dense(train_predictions, 1, activation=None, name='output_dense_layer')

解码器(推理)。不正确的部分:

def sample_fn(outputs):
    return tf.layers.dense(outputs, 1, activation=None,         
                           name='output_dense_layer', reuse=tf.AUTO_REUSE)

infer_helper = tf.contrib.seq2seq.InferenceHelper(sample_fn=sample_fn, sample_shape=(1), 
                                                       sample_dtype=tf.float32, start_inputs=start_tokens, end_fn=lambda sample_ids: False, next_inputs_fn=None)
infer_decoder = tf.contrib.seq2seq.BasicDecoder(cell=decoder_cell, helper=infer_helper, initial_state=final_encoder_states)

infer_outputs, _, _ = tf.contrib.seq2seq.dynamic_decode(decoder=infer_decoder, maximum_iterations=max_target_sequence_length, impute_finished=True)

infer_predictions = infer_outputs.rnn_output
infer_predictions = sample_fn(infer_predictions)

有一个类似的问题:How to use tensorflow seq2seq without embeddings?

作者使用sample_fn=lambda outputs: outputs。但是在我的情况下这会返回一个 ValueError ,因为尺寸不匹配。他们怎么可能拥有多个细胞? sample_fn 应该返回一个值。

【问题讨论】:

    标签: tensorflow time-series seq2seq


    【解决方案1】:

    现在,我通过创建自己的 dynamic_decode 函数解决了我的问题。我复制了旁边的所有内容

    with variable_scope.variable_scope(scope, "decoder", reuse=reuse) as varscope:
    

    还有一个与 varscope 相关的 if 条件和另一个 if 条件测试来自 tf.contrib.seq2seq.dynamic_decode 的解码器类。

    不是一个很好的解决方案,但现在已经足够了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多