2

当试图编译一个具有一个经常性图层的网络时,我发现问题。似乎第一层的维度存在一些问题,因此我对Keras中RNN层的工作原理有所了解。Keras简单的RNN实现

我的代码示例是:

model.add(Dense(8, 
       input_dim = 2, 
       activation = "tanh", 
       use_bias = False)) 
model.add(SimpleRNN(2, 
        activation = "tanh", 
        use_bias = False)) 
model.add(Dense(1, 
       activation = "tanh", 
       use_bias = False)) 

该错误是

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

input_dim无关的值将返回此错误。我错过了什么?

回答

2

该消息表示:进入rnn的输入有2个维度,但rnn层需要3个维度。

对于RNN图层,需要形状如(BatchSize, TimeSteps, FeaturesPerStep)的输入。这些是预期的3个维度。

A Dense图层(在keras 2中)可以使用2维或3维。我们可以看到您正在使用2,因为您通过了input_dim而不是传递了input_shape=(Steps,Features)

解决这个问题的方法有很多种,但最有意义和最合理的是输入数据是带时间步长的序列。

解决方案1 ​​ - 您的训练数据是一个序列:

如果你的训练数据是一个序列,你塑造它喜欢(NumberOfSamples, TimeSteps, Features)并把它传递到您的模型。确保在第一层使用input_shape=(TimeSteps,Features)而不是使用input_dim

解决方案2 - 你重塑第一致密层的输出,所以它有额外的维度:

model.add(Reshape((TimeSteps,Features))) 

确保产品TimeSteps*Features等于8,你的第一个致密层的输出。

+0

太棒了,谢谢你,另外一个问题。第一个解决方案是完美的,但是如果我想要有无限的时间步骤(理论问题,我知道,无限的时间步骤是愚蠢的)?然后,我必须使用你的第二个解决方案来重塑第一层的输出。但是,我通过记忆XOR序列做了简单的测试,当我对输出进行混洗时,网络未能按照我的预期做出反应。更好地说,它的输出与之前的洗牌相同。如何重塑影响复发层的工作(与第一种解决方案相比)? – Seraph

+1

整形只需要数据(任何数据),这只不过是按照分段划分的一串连续数字。假设你有300个元素。当你像(30,10,1)那样重塑它们时,你只需以不同的方式分离这300个元素。所以,如果你为了序列目的而重塑形状,你必须知道你想要达到什么样的目标,以及你的数据的格式是什么,所以你可以用一个重要的方式来重塑它。 –

+0

对于您的无限序列,您应该只使用1个样本'(BatchSize = 1,TimeSteps,Features)'的输入,并用'stateful = True'标记您的循环图层。这意味着这些图层将保持其记忆,并且下一批将被视为以一个单一序列继续前一批。在这种情况下,当您决定一个序列结束并且您将开始输入另一个序列时,您必须手动“删除存储器”(称为“复位状态”)。 –