TensorFlow
Conv2D error
deep learning
neural networks
troubleshooting

Negative dimension size caused by subtracting 3 from 1 for 'conv2d_2/convolution'

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

This TensorFlow error means a convolution layer is trying to apply a kernel to a feature map that is already too small. The phrase "subtracting 3 from 1" is the clue: one spatial dimension has size 1, but the layer wants a 3 x 3 kernel with settings that reduce the tensor instead of preserving its size. The fix is to inspect how your model shrinks height and width before that failing Conv2D.

Why the Error Happens

For a Conv2D layer with padding="valid", the kernel must fit fully inside the input. A 3 x 3 kernel cannot run on a 1 x N or N x 1 feature map because there is no room to slide across one of the spatial dimensions.

A minimal failing example looks like this:

python
1import tensorflow as tf
2
3model = tf.keras.Sequential([
4    tf.keras.layers.Input(shape=(5, 5, 1)),
5    tf.keras.layers.Conv2D(8, kernel_size=3, padding="valid"),
6    tf.keras.layers.MaxPooling2D(pool_size=2),
7    tf.keras.layers.Conv2D(16, kernel_size=3, padding="valid")
8])
9
10model.summary()

The first convolution turns 5 x 5 into 3 x 3. The max-pooling layer turns 3 x 3 into 1 x 1. The second 3 x 3 convolution then fails because the input is too small.

Check the Spatial Shape After Every Layer

The fastest way to debug this class of error is to print the model summary and trace the spatial dimensions layer by layer.

python
1import tensorflow as tf
2
3model = tf.keras.Sequential([
4    tf.keras.layers.Input(shape=(5, 5, 1)),
5    tf.keras.layers.Conv2D(8, kernel_size=3, padding="valid"),
6    tf.keras.layers.MaxPooling2D(pool_size=2),
7    tf.keras.layers.Conv2D(16, kernel_size=3, padding="valid")
8])
9
10model.summary()

Look specifically at the output shape of the layer immediately before the failing convolution. If either height or width is smaller than the kernel size, that is the problem.

In many real models, the shrinking is caused by a combination of several layers:

  • repeated padding="valid" convolutions
  • pooling layers with stride greater than 1
  • small input images to begin with
  • accidental transposition that changes the expected spatial layout

Common Fixes

The correct fix depends on the model design, but four options solve most cases.

1. Use padding="same"

If preserving feature-map size is acceptable, same padding prevents the convolution from shrinking the tensor.

python
1import tensorflow as tf
2
3model = tf.keras.Sequential([
4    tf.keras.layers.Input(shape=(5, 5, 1)),
5    tf.keras.layers.Conv2D(8, kernel_size=3, padding="same"),
6    tf.keras.layers.MaxPooling2D(pool_size=2),
7    tf.keras.layers.Conv2D(16, kernel_size=3, padding="same")
8])
9
10model.summary()

2. Reduce the Kernel Size

If you truly have a 1 x 1 or 2 x 2 feature map, a smaller kernel may match the intent better.

python
1import tensorflow as tf
2
3model = tf.keras.Sequential([
4    tf.keras.layers.Input(shape=(5, 5, 1)),
5    tf.keras.layers.Conv2D(8, kernel_size=3, padding="valid"),
6    tf.keras.layers.MaxPooling2D(pool_size=2),
7    tf.keras.layers.Conv2D(16, kernel_size=1, padding="valid")
8])

3. Remove or Delay Pooling

If the input is already small, downsampling too early is often the real design mistake.

python
1import tensorflow as tf
2
3model = tf.keras.Sequential([
4    tf.keras.layers.Input(shape=(5, 5, 1)),
5    tf.keras.layers.Conv2D(8, kernel_size=3, padding="valid"),
6    tf.keras.layers.Conv2D(16, kernel_size=3, padding="same"),
7    tf.keras.layers.MaxPooling2D(pool_size=2)
8])

4. Increase the Input Size

Some architectures assume a minimum image size. If you copied a model that was designed for 64 x 64 images and you feed 16 x 16, later convolutions may inevitably fail.

Watch for Data Format Mistakes

Another common cause is mixing up channel ordering. Keras usually expects channels_last, meaning input shaped like (height, width, channels). If you accidentally pass (channels, height, width) while the model expects channels_last, TensorFlow may interpret the spatial dimensions incorrectly and create impossible convolution shapes.

A safe input definition for grayscale images is:

python
inputs = tf.keras.Input(shape=(28, 28, 1))

For RGB images:

python
inputs = tf.keras.Input(shape=(28, 28, 3))

Common Pitfalls

  • Looking only at the failing layer instead of the sequence of layers that reduced the tensor first.
  • Using padding="valid" repeatedly on very small images.
  • Adding pooling too early and collapsing the feature map to 1 x 1.
  • Copying a model built for larger inputs without adjusting the input resolution.
  • Mixing up channels_first and channels_last layouts.

Summary

  • The error means a convolution kernel is larger than one spatial dimension of the incoming tensor.
  • Use model.summary() to trace height and width through the network.
  • Fixes usually involve padding="same", a smaller kernel, less aggressive pooling, or larger inputs.
  • Check the data format if shapes look correct on paper but fail at runtime.
  • Diagnose the first layer that makes the spatial dimensions too small, not just the layer that throws the exception.

Course illustration
Course illustration

All Rights Reserved.