Sonn中的LSTM时间步长

2024-09-25 00:25:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在努力学习Sonnet。你知道吗

我的网络(不完整,问题基于此):

class Model(snt.AbstractModule):

    def __init__(self, name="LSTMNetwork"):
        super(Model, self).__init__(name=name)
        with self._enter_variable_scope():
            self.l1 = snt.LSTM(100)
            self.l2 = snt.LSTM(100)
            self.out = snt.LSTM(10)

    def _build(self, inputs):

        # 'inputs' is of shape (batch_size, input_length)
        # I need it to be of shape (batch_size, sequence_length, input_length)

        l1_state = self.l1.initialize_state(np.shape(inputs)[0]) # init with batch_size
        l2_state = self.l2.initialize_state(np.shape(inputs)[0]) # init with batch_size
        out_state = self.out.initialize_state(np.shape(inputs)[0])

        l1_out, l1_state = self.l1(inputs, l1_state)
        l1_out = tf.tanh(l1_out)
        l2_out, l2_state = self.l2(l1_out, l2_state)
        l2_out = tf.tanh(l2_out)
        output, out_state = self.out(l2_out, out_state)
        output = tf.sigmoid(output)

        return output, out_state

在其他框架(例如Keras)中,LSTM输入的形式是(batch_size, sequence_length, input_length)。你知道吗

然而,十四行诗文档指出,十四行诗的LSTM的输入形式是(batch_size, input_length)。你知道吗

如何使用它们进行顺序输入?你知道吗

到目前为止,我已经尝试在_build内使用for循环,在每个时间步上迭代,但这会给出看似随机的输出。你知道吗

我在Keras中尝试过同样的架构,运行起来没有任何问题。你知道吗

我正在急切地执行,使用GradientTape进行训练。你知道吗


Tags: selfl1inputoutputsizeinitbatchout
1条回答
网友
1楼 · 发布于 2024-09-25 00:25:02

我们通常在十四行诗中编写RNN以单个时间步为基础,而对于强化学习,您通常需要运行一个时间步来选择一个动作,如果没有这个动作,您就无法从环境中获得下一个观察结果(和下一个输入时间步)。使用tf.nn.dynamic_rnn(见下文)很容易在序列上展开单个timestep模块。我们还有一个包装器,它负责每个时间步合成几个RNN核心,我相信这就是您要做的。这样做的好处是DeepCore对象支持dynamic_rnn所需的启动状态方法,因此它与LSTM或任何其他单个timestep模块的API兼容。你知道吗

你想做的事情应该是可以做到的:

# Create a single-timestep RNN module by composing recurrent modules and
# non-recurrent ops.
model = snt.DeepRNN([
    snt.LSTM(100),
    tf.tanh,
    snt.LSTM(100),
    tf.tanh,
    snt.LSTM(100),
    tf.sigmoid
], skip_connections=False)

batch_size = 2
sequence_length = 3
input_size = 4

single_timestep_input = tf.random_uniform([batch_size, input_size])
sequence_input = tf.random_uniform([batch_size, sequence_length, input_size])

# Run the module on a single timestep
single_timestep_output, next_state = model(
    single_timestep_input, model.initial_state(batch_size=batch_size))

# Unroll the module on a full sequence
sequence_output, final_state = tf.nn.dynamic_rnn(
    core, sequence_input, dtype=tf.float32)

需要注意的几件事-如果您还没有查看存储库中的RNN example,因为这显示了围绕一个非常相似的模型设置的完整的图形模式训练过程。你知道吗

其次,如果您最终需要实现一个DeepRNN允许的更复杂的模块,那么将循环状态穿入和穿出模块是很重要的。在您的示例中,您在内部创建输入状态,而作为输出的l1_statel2_state被有效地丢弃,因此无法对其进行适当的训练。如果DeepRNN不可用,您的模型将如下所示:

class LSTMNetwork(snt.RNNCore):  # Note we inherit from the RNN-specific subclass
  def __init__(self, name="LSTMNetwork"):
    super(Model, self).__init__(name=name)
    with self._enter_variable_scope():
      self.l1 = snt.LSTM(100)
      self.l2 = snt.LSTM(100)
      self.out = snt.LSTM(10)

  def initial_state(self, batch_size):
    return (self.l1.initial_state(batch_size),
            self.l2.initial_state(batch_size),
            self.out.initial_state(batch_size))

  def _build(self, inputs, prev_state):

    # separate the components of prev_state
    l1_prev_state, l2_prev_state, out_prev_state = prev_state

    l1_out, l1_next_state = self.l1(inputs, l1_prev_state)
    l1_out = tf.tanh(l1_out)
    l2_out, l2_next_state = self.l2(l1_out, l2_prev_state)
    l2_out = tf.tanh(l2_out)
    output, out_next_state = self.out(l2_out, out_prev_state)

    # Output state of LSTMNetwork contains the output states of inner modules.
    full_output_state = (l1_next_state, l2_next_state, out_next_state)

    return tf.sigmoid(output), full_output_state

最后,如果你使用的是渴望模式,我强烈建议你看一看十四行诗2——它是对tf2/渴望模式的完全重写。它不是向后兼容的,但是所有相同类型的模块组合都是可能的。十四行诗1主要是为图形模式TF编写的,虽然它确实适用于渴望模式,但您可能会遇到一些不太方便的事情。你知道吗

我们与TensorFlow团队密切合作,以确保TF2和十四行诗2能够很好地协同工作,所以请看一看:(https://github.com/deepmind/sonnet/tree/v2)。十四行诗2应该被认为是阿尔法,并正在积极发展,所以我们还没有负载的例子,但更多将在不久的将来添加。你知道吗

相关问题 更多 >