0

我正在尝试将序列到序列建模应用于 EEG 数据。编码工作得很好,但让解码工作被证明是有问题的。输入数据的形状None为 ×3000×31,其中第二维是序列长度。

编码器如下所示:

initial_state = lstm_sequence_encoder.zero_state(batchsize, dtype=self.model_precision)

encoder_output, state = dynamic_rnn(
     cell=LSTMCell(32),
     inputs=lstm_input, # shape=(None,3000,32)
     initial_state=initial_state, # zeroes
     dtype=lstm_input.dtype # tf.float32
)

我使用 RNN 的最终状态作为解码器的初始状态。对于培训,我使用TrainingHelper

training_helper = TrainingHelper(target_input, [self.sequence_length])
training_decoder = BasicDecoder(
     cell=lstm_sequence_decoder,
     helper=training_helper,
     initial_state=thought_vector
)
output, _, _ = dynamic_decode(
     decoder=training_decoder,
     maximum_iterations=3000
)

当我尝试实施推理时,我的麻烦就开始了。由于我使用的是非句子数据,我不需要标记或嵌入,因为数据本质上已经嵌入。这InferenceHelper门课似乎是实现我的目标的最佳方式。所以这就是我使用的。我会给出我的代码然后解释我的问题。

def _sample_fn(decoder_outputs):
     return decoder_outputs
def _end_fn(_):
     return tf.tile([False], [self.lstm_layersize]) # Batch-size is sequence-length because of time major
inference_helper = InferenceHelper(
     sample_fn=_sample_fn,
     sample_shape=[32],
     sample_dtype=target_input.dtype,
     start_inputs=tf.zeros(batchsize_placeholder, 32), # the batchsize varies
     end_fn=_end_fn
)
inference_decoder = BasicDecoder(
     cell=lstm_sequence_decoder,
     helper=inference_helper,
     initial_state=thought_vector
)
output, _, _ = dynamic_decode(
     decoder=inference_decoder,
     maximum_iterations=3000
)

问题

我不知道输入的形状应该是什么。我知道开始输入应该为零,因为它是第一个时间步。但这会引发错误;它期望输入为(1,32).

我还认为我应该将每个时间步的输出不变地传递给下一个。但是,这会在运行时引发问题:批量大小不同,因此形状是局部的。库在尝试将 转换为张量时抛出异常start_input

...
self._start_inputs = ops.convert_to_tensor(
      start_inputs, name='start_inputs')

有任何想法吗?

4

1 回答 1

0

这是糟糕文档的一个教训。

我解决了我的问题,但未能解决可变批量大小问题。

_end_fn引起了我不知道的问题。我还设法弄清楚InferenceHelper. 我已经给出了字段名称,以防将来有人需要指导

 def _end_fn(_):
      return tf.tile([False], [batchsize])
 inference_helper = InferenceHelper(
      sample_fn=_sample_fn,
      sample_shape=[lstm_number_of_units], # In my case, 32
      sample_dtype=tf.float32, # Depends on the data
      start_inputs=tf.zeros((batchsize, lstm_number_of_units)),
      end_fn=_end_fn
 )

至于批量大小问题,我正在考虑两件事:

  1. 更改模型对象的内部状态。我的 TensorFlow 计算图是在一个类中构建的。一个类字段记录批量大小。在训练期间改变这一点可能会奏效。或者:

  2. 填充批次,使它们有 200 个序列长。这会浪费时间。

最好我想要一种动态管理批量大小的方法。

编辑:我找到了一种方法。它涉及简单地用方括号代替括号:

 inference_helper = InferenceHelper(
      sample_fn=_sample_fn,
      sample_shape=[self.lstm_layersize],
      sample_dtype=target_input.dtype,
      start_inputs=tf.zeros([batchsize, self.lstm_layersize]),
      end_fn=_end_fn
 )
于 2018-06-25T13:37:50.327 回答