Training output error : Negative dimension size caused by subtracting 5 from 4 for

When starting training of my Neural Network it is reporting the following error:

Creating job... OK (ID: 219285)

Copying features from processing blocks...
Copying features from processing blocks OK

Scheduling job in cluster...
Job started
Splitting data into training and validation sets...
Splitting data into training and validation sets OK

Training model...
Training on 184 inputs, validating on 46 inputs
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/tensorflow/python/framework/ops.py", line 1654, in _create_c_op
    c_op = pywrap_tf_session.TF_FinishOperation(op_desc)
tensorflow.python.framework.errors_impl.InvalidArgumentError: Negative dimension size caused by subtracting 5 from 4 for '{{node conv1d/conv1d}} = Conv2D[T=DT_FLOAT, data_format="NHWC", dilations=[1, 1, 1, 1], explicit_paddings=[], padding="VALID", strides=[1, 1, 1, 1], use_cudnn_on_gpu=true](conv1d/conv1d/ExpandDims, conv1d/conv1d/ExpandDims_1)' with input shapes: [?,1,4,13], [1,5,13,30].

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/train.py", line 459, in <module>
    main_function()
  File "/home/train.py", line 396, in main_function
    X_train, X_test, Y_train, Y_test, len(X_train), classes)
  File "/home/train.py", line 44, in train_model
    model.add(Conv1D(30, kernel_size=5, activation='relu'))
  File "/usr/local/lib/python3.7/site-packages/tensorflow/python/training/tracking/base.py", line 456, in _method_wrapper
    result = method(self, *args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/tensorflow/python/keras/engine/sequential.py", line 213, in add
    output_tensor = layer(self.outputs[0])
  File "/usr/local/lib/python3.7/site-packages/tensorflow/python/keras/engine/base_layer.py", line 922, in __call__
    outputs = call_fn(cast_inputs, *args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/tensorflow/python/keras/layers/convolutional.py", line 207, in call
    outputs = self._convolution_op(inputs, self.kernel)
  File "/usr/local/lib/python3.7/site-packages/tensorflow/python/ops/nn_ops.py", line 1106, in __call__
    return self.conv_op(inp, filter)
  File "/usr/local/lib/python3.7/site-packages/tensorflow/python/ops/nn_ops.py", line 638, in __call__
    return self.call(inp, filter)
  File "/usr/local/lib/python3.7/site-packages/tensorflow/python/ops/nn_ops.py", line 237, in __call__
    name=self.name)
  File "/usr/local/lib/python3.7/site-packages/tensorflow/python/ops/nn_ops.py", line 226, in _conv1d
    name=name)
  File "/usr/local/lib/python3.7/site-packages/tensorflow/python/util/deprecation.py", line 574, in new_func
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/tensorflow/python/util/deprecation.py", line 574, in new_func
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/tensorflow/python/ops/nn_ops.py", line 1663, in conv1d
    name=name)
  File "/usr/local/lib/python3.7/site-packages/tensorflow/python/ops/gen_nn_ops.py", line 969, in conv2d
    data_format=data_format, dilations=dilations, name=name)
  File "/usr/local/lib/python3.7/site-packages/tensorflow/python/framework/op_def_library.py", line 744, in _apply_op_helper
    attrs=attr_protos, op_def=op_def)
  File "/usr/local/lib/python3.7/site-packages/tensorflow/python/framework/func_graph.py", line 595, in _create_op_internal
    compute_device)
  File "/usr/local/lib/python3.7/site-packages/tensorflow/python/framework/ops.py", line 3327, in _create_op_internal
    op_def=op_def)
  File "/usr/local/lib/python3.7/site-packages/tensorflow/python/framework/ops.py", line 1817, in __init__
    control_input_ops, op_def)
  File "/usr/local/lib/python3.7/site-packages/tensorflow/python/framework/ops.py", line 1657, in _create_c_op
    raise ValueError(str(e))
ValueError: Negative dimension size caused by subtracting 5 from 4 for '{{node conv1d/conv1d}} = Conv2D[T=DT_FLOAT, data_format="NHWC", dilations=[1, 1, 1, 1], explicit_paddings=[], padding="VALID", strides=[1, 1, 1, 1], use_cudnn_on_gpu=true](conv1d/conv1d/ExpandDims, conv1d/conv1d/ExpandDims_1)' with input shapes: [?,1,4,13], [1,5,13,30].

Application exited with code 1 (Error)

Job failed (see above)

Here a screenshot of the same error:

Here a screenshot of the generated features (MFCC) that are used as input for the neural network:

Hello @janvda, thanks for your question!

By default, the 1D conv/pool layers are configured to support an input with a particular size and shape. It looks like you may have altered the MFCC parameters in a way that has resulted in a different input shape, so you may have to adjust the configuration of your network’s layers. In this case, you could try changing the kernel size of your second 1D conv layer to 3.

Could you post a screenshot of your MFCC Parameters configuration?

Warmly,
Dan

I have tried that but getting same error:

I managed to fix it by setting the kernel size of the first 1D conv layer to 4 and for the 2nd 1D conv layer to 1 :

import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, InputLayer, Dropout, Conv1D, Conv2D, Flatten, Reshape, MaxPooling1D, AveragePooling2D, BatchNormalization
from tensorflow.keras.optimizers import Adam

from sklearn.utils.class_weight import compute_class_weight

class_weights = dict(enumerate(compute_class_weight('balanced', np.unique(np.argmax(Y_train, axis=1)), np.argmax(Y_train, axis=1))))

# model architecture
model = Sequential()
model.add(InputLayer(input_shape=(input_length, ), name='x_input'))
model.add(Reshape((int(input_length / 13), 13), input_shape=(input_length, )))
model.add(Conv1D(30, kernel_size=4, activation='relu'))
model.add(MaxPooling1D(pool_size=4, padding='same'))
model.add(Conv1D(10, kernel_size=1, activation='relu'))
model.add(MaxPooling1D(pool_size=1, padding='same'))
model.add(Flatten())
model.add(Dense(classes, activation='softmax', name='y_pred'))

# this controls the learning rate
opt = Adam(lr=0.00005, beta_1=0.9, beta_2=0.999)

# this controls the batch size, or you can manipulate the tf.data.Dataset objects yourself
BATCH_SIZE = 32
train_dataset, validation_dataset = set_batch_size(BATCH_SIZE, train_dataset, validation_dataset)
callbacks.append(BatchLoggerCallback(BATCH_SIZE, train_sample_count))

# train the neural network
model.compile(loss='categorical_crossentropy', optimizer=opt, metrics=['accuracy'])
model.fit(train_dataset, epochs=100, validation_data=validation_dataset,class_weight=class_weights, verbose=2, callbacks=callbacks)

Glad you were able to get it working!

The issue here is that the input to your neural network is very small, only 4x13 values. The first convolutional layer’s kernel size was too big to fit inside that input. Even with that fixed, the pooling layer reduced the size further, so by the time we got to the second convolutional layer it was too small again.

Another fix for this is to add padding to the convolutional layers, like this:

# model architecture
model = Sequential()
model.add(InputLayer(input_shape=(input_length, ), name='x_input'))
model.add(Reshape((int(input_length / 13), 13), input_shape=(input_length, )))
model.add(Conv1D(30, kernel_size=5, activation='relu', padding='same'))
model.add(MaxPooling1D(pool_size=5, padding='same'))
model.add(Conv1D(10, kernel_size=5, activation='relu', padding='same'))
model.add(MaxPooling1D(pool_size=5, padding='same'))
model.add(Flatten())
model.add(Dense(classes, activation='softmax', name='y_pred'))

You can then play with the kernel and pool sizes freely. That said, given the input is so small, you could even try doing away with convolutions altogether and just use a dense layer. Depending on how many dense layers and neurons you need, this might result in a smaller model.

There’s another thing worth noting, though. The window length set on your input block is short, at 100 ms. By default, the MFCC block is set up with a frame length and stride of 20ms (shown as 0.02 in the MFCC block config). This is why your model only has 4x13 values: it has 4 sets of frequency buckets.

It may turn out this is sufficient for your application, but it might be worth experimenting with reducing the frame length and stride (I recommend giving them both the same value) to increase the resolution of your model’s input. Depending on the type of signal you are analyzing, this might improve accuracy.

Thanks for your bug report, I’ll make some changes in the studio so that we use padding for these layers by default. That way there will no longer be an error even for small inputs.

1 Like

Thanks for the support !

I know I have created this issue under “bug report” but I rather should have created it under “issue” (but this category doesn’t exist).