Keras SimpleRNN混淆

时间:2018-05-31 01:15:49

标签: python keras rnn

...来自TensorFlow,几乎任何形状和一切都明确定义,我对Keras'用于循环模型的API。让一个Elman网络在TF工作很容易,但Keras拒绝接受正确的形状......

例如:

x = k.layers.Input(shape=(2,))
y = k.layers.Dense(10)(x)
m = k.models.Model(x, y)

...完美无缺,根据model.summary(),我得到一个形状为(None, 2)的输入图层,后跟一个输出形状为(None, 10)的密集图层。这是有道理的,因为Keras会自动添加批处理的第一个维度。

但是,以下代码:

x = k.layers.Input(shape=(2,))
y = k.layers.SimpleRNN(10)(x)
m = k.models.Model(x, y)

引发异常ValueError: Input 0 is incompatible with layer simple_rnn_1: expected ndim=3, found ndim=2

仅当我添加另一个维度时才有效:

x = k.layers.Input(shape=(2,1))
y = k.layers.SimpleRNN(10)(x)
m = k.models.Model(x, y)

...但是现在,我的输入当然不再是(None, 2)了。

model.summary()

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         (None, 2, 1)              0         
_________________________________________________________________
simple_rnn_1 (SimpleRNN)     (None, 10)                120       
=================================================================

当我只想向网络提供带有2个值的向量时,如何输入batch_size x 2类型的输入?

此外,我将如何链接RNN细胞?

x = k.layers.Input(shape=(2, 1))
h = k.layers.SimpleRNN(10)(x)
y = k.layers.SimpleRNN(10)(h)
m = k.models.Model(x, y)

...使用不兼容的暗淡大小引发相同的异常。

此示例适用于:

x = k.layers.Input(shape=(2, 1))
h = k.layers.SimpleRNN(10, return_sequences=True)(x)
y = k.layers.SimpleRNN(10)(h)
m = k.models.Model(x, y)

...但是图层h不再输出(None, 10),而是(None, 2, 10),因为它返回的是整个序列,而不仅仅是"常规" RNN细胞输出。

为什么需要这样做?

而且:各州在哪里?他们只是默认为1个复发状态吗?

1 个答案:

答案 0 :(得分:1)

documentation触及了Keras中预期的复发组件形状,让我们来看看你的情况:

  1. Keras中的任何RNN图层都需要3D形状(batch_size, timesteps, features)。这意味着您拥有 timeseries 数据。
  2. RNN层然后在输入的第二个时间维度上使用循环单元格迭代,即实际的循环计算。
  3. 如果您指定return_sequences,那么您将收集每个时间步的输出,获得另一个3D张量(batch_size, timesteps, units),否则您只能得到(batch_size, units)的最后一个输出。
  4. 现在回到你的问题:

    1. 你提到向量,但shape=(2,) a 向量,所以这不起作用。 shape=(2,1)有效,因为现在您有2个大小为1的向量,这些形状不包括batch_size。因此,要向您提供大小的向量,需要shape=(how_many_vectors, 2),其中第一个维度是您希望RNN处理的向量数,在这种情况下是时间步长。
    2. 要链接RNN图层,您需要提供3D数据,因为这是RNN所期望的。当您指定return_sequences时,RNN层会在每个时间步都返回输出,以便可以链接到另一个RNN层。
    3. 状态是RNN小区使用的向量的集合,LSTM使用2,GRU具有1个隐藏状态,其也是输出。它们默认为0,但可以在使用initial_states=[...]作为张量列表调用图层时指定。
    4. 关于克拉斯的RNN层和RNN小区之间的区别已经有post,这可能有助于进一步澄清情况。