0

I am willing to create a GRU model of 3 layers where each layer will have 32,16,8 units respectively. The model would take analog calue as input and produce analog value as output.

I have written the following code:

def getAModelGRU(neuron=(10), look_back=1, numInputs = 1, numOutputs = 1):
    model = Sequential()
    if len(neuron) > 1:
        model.add(GRU(units=neuron[0], input_shape=(look_back,numInputs)))
        for i in range(1,len(neuron)-1):
            model.add(GRU(units=neuron[i]))
        model.add(GRU(units=neuron[-1], input_shape=(look_back,numInputs)))
    else:
    model.add(GRU(units=neuron, input_shape=(look_back,numInputs)))
    model.add(Dense(numOutputs))
    model.compile(loss='mean_squared_error', optimizer='adam')
    return model

And, I will call this function as:

chkEKF = getAModelGRU(neuron=(32,16,8), look_back=1, numInputs=10, numOutputs=6)

And, I obtained the following:

Traceback (most recent call last):
  File "/home/momtaz/Dropbox/QuadCopter/quad_simHierErrorCorrectionEstimator.py", line 695, in <module>
    Single_Point2Point()
  File "/home/momtaz/Dropbox/QuadCopter/quad_simHierErrorCorrectionEstimator.py", line 74, in Single_Point2Point
    chkEKF = getAModelGRU(neuron=(32,16,8), look_back=1, numInputs=10, numOutputs=6)
  File "/home/momtaz/Dropbox/QuadCopter/rnnUtilQuad.py", line 72, in getAModelGRU
    model.add(GRU(units=neuron[i]))
  File "/home/momtaz/PycharmProjects/venv/lib/python3.6/site-packages/keras/engine/sequential.py", line 181, in add
    output_tensor = layer(self.outputs[0])
  File "/home/momtaz/PycharmProjects/venv/lib/python3.6/site-packages/keras/layers/recurrent.py", line 532, in __call__
    return super(RNN, self).__call__(inputs, **kwargs)
  File "/home/momtaz/PycharmProjects/venv/lib/python3.6/site-packages/keras/engine/base_layer.py", line 414, in __call__
    self.assert_input_compatibility(inputs)
  File "/home/momtaz/PycharmProjects/venv/lib/python3.6/site-packages/keras/engine/base_layer.py", line 311, in assert_input_compatibility
    str(K.ndim(x)))
ValueError: Input 0 is incompatible with layer gru_2: expected ndim=3, found ndim=2

I tried online but did not find any solution for 'ndim' related issue.

Please let me know which I am doing wrong here.

Imran
  • 89
  • 2
  • 10

1 Answers1

2

You need to ensure input_shape parameter is being defined in the first layer exclusively, and every layer to have return_sequences=True except potentially the last one (depending on your model).

The code below serves for the common case where you want to stack several layers and only the number of units in each layer changes.

model = tf.keras.Sequential()

gru_options = [dict(units = units,
                    time_major=False,
                    kernel_regularizer=0.01,
                    # ... potentially more options
                    return_sequences=True) for units in [32,16,8]]
gru_options[0]['input_shape'] = (n_timesteps, n_inputs)
gru_options[-1]['return_sequences']=False # optionally disable sequences in the last layer. 
                                          # If you want to return sequences in your last
                                          # layer delete this line, however it is necessary
                                          # if you want to connect this to a dense layer
                                          # for example.
for opts in gru_options:
    model.add(tf.keras.layers.GRU(**opts))

model.add(tf.keras.Dense(6))

By the way there is a bug in your code, as no indentation is done after the else clause. Also notice that Python classes that implement the Iterable protocol (e.g. lists and tuples) can be iterated over by using for-in syntax, you don't have to do C-like iteration (it's more idiomatic or pythonic to use the aforementioned syntax).

Adrian
  • 755
  • 9
  • 17